← Back to team overview

openerp-dev-web team mailing list archive

[Merge] lp:~openerp-dev/openobject-server/6.0-bug-747746-xrg into lp:openobject-server/6.0

 

xrg has proposed merging lp:~openerp-dev/openobject-server/6.0-bug-747746-xrg into lp:openobject-server/6.0.

Requested reviews:
  OpenERP Core Team (openerp)
Related bugs:
  Bug #747746 in OpenERP Server: "tools: 'date_eval' utility for relative dates in YAML"
  https://bugs.launchpad.net/openobject-server/+bug/747746

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/6.0-bug-747746-xrg/+merge/56001
-- 
https://code.launchpad.net/~openerp-dev/openobject-server/6.0-bug-747746-xrg/+merge/56001
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-server/6.0-bug-747746-xrg.
=== added file 'bin/tools/date_eval.py'
--- bin/tools/date_eval.py	1970-01-01 00:00:00 +0000
+++ bin/tools/date_eval.py	2011-04-01 20:41:28 +0000
@@ -0,0 +1,86 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import re
+import time
+import datetime
+from dateutil.relativedelta import relativedelta
+
+re_abstimes = { 'now': datetime.datetime.now,
+                'today': datetime.date.today,
+                'tomorrow': lambda: (datetime.date.today() + datetime.timedelta(1)),
+                'yesterday': lambda: (datetime.date.today() - datetime.timedelta(1)),
+                }
+
+rel_units = { 'yr' : 'Y',
+            'year': 'Y',
+            'years': 'Y',
+            'month': 'M',
+            'months': 'M',
+            'mo': 'M',
+            'd': 'D',
+            'day': 'D',
+            'days': 'D',
+            'h': 3600,
+            'hr': 3600,
+            'hour': 3600,
+            'hours': 3600,
+            'm': 60,
+            'min': 60,
+            'minute': 60,
+            'minutes': 60,
+            's': 1,
+            'sec' : 1,
+            'second': 1,
+            'seconds': 1,
+            }
+
+re_dateeval = re.compile(r"(?P<abs>" + '|'.join(re_abstimes) +")"
+        r"|(?:(?P<rel>(?:\+|-)[0-9]+)(?P<rel_unit>" + '|'.join(rel_units)+ "))"
+        r"|(?: ?\bon ?(?P<date>[0-9]{1,2}(?:/[0-9]{1,2}(?:/[0-9]{2,4})?)?))"
+        r"|(?: ?\bat ?(?P<time>[0-9]{1,2}(?::[0-9]{2}(?::[0-9]{2})?)?))"
+        r"| +", re.I)
+
+def date_eval(rstr):
+    cur_time = datetime.datetime.now()
+    for m in re_dateeval.finditer(rstr):
+        if m.group('abs'):
+            cur_time = re_abstimes[m.group('abs')]()
+            if not isinstance(cur_time, datetime.datetime):
+                cur_time = datetime.datetime.fromordinal(cur_time.toordinal())
+            
+        elif m.group('rel'):
+            mrel = int(m.group('rel')[1:])
+            if m.group('rel')[0] == '-':
+                mrel = 0 - mrel
+            mun = rel_units[m.group('rel_unit')]
+            if mun == 'Y':
+                drel = relativedelta(years=mrel)
+            elif mun == 'M':
+                drel = relativedelta(months=mrel)
+            elif mun == 'D':
+                drel = datetime.timedelta(days=mrel)
+            else:
+                drel = mrel * datetime.timedelta(seconds=mun)
+
+            cur_time = cur_time + drel
+        elif m.group('date'):
+            dli = map(int, m.group('date').split('/'))
+            if len(dli) == 2:
+                dli += [cur_time.year,]
+            elif len(dli) == 1:
+                dli += [cur_time.month, cur_time.year]
+            cur_time = datetime.datetime.combine(datetime.date(dli[2],dli[1],dli[0]), cur_time.time())
+        elif m.group('time'):
+            dli = map(int, m.group('time').split(':'))
+            if len(dli) == 2:
+                dli += [cur_time.second,]
+            elif len(dli) == 1:
+                dli += [cur_time.minute, cur_time.second]
+            cur_time = datetime.datetime.combine(cur_time.date(), datetime.time(dli[0],dli[1],dli[2]))
+        else:
+            pass
+
+    return cur_time
+
+#eof

=== modified file 'bin/tools/yaml_tag.py'
--- bin/tools/yaml_tag.py	2010-12-03 14:20:35 +0000
+++ bin/tools/yaml_tag.py	2011-04-01 20:41:28 +0000
@@ -1,5 +1,7 @@
 import yaml
 import logging
+from date_eval import date_eval
+from misc import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
 
 class YamlTag(object):
     """
@@ -90,7 +92,7 @@
         super(Eval, self).__init__()
     def __str__(self):
         return '!eval %s' % str(self.expression)
-    
+
 class Ref(YamlTag):
     def __init__(self, expr="False", *args, **kwargs):
         self.expr = expr
@@ -150,6 +152,16 @@
     expression = loader.construct_scalar(node)
     return Eval(expression)
     
+def date_constructor(loader, node):
+    expression = loader.construct_scalar(node)
+    # TODO return a datetime.date object, not string
+    return date_eval(expression).strftime(DEFAULT_SERVER_DATE_FORMAT)
+
+def datetime_constructor(loader, node):
+    expression = loader.construct_scalar(node)
+    # TODO return a datetime.datetime object
+    return date_eval(expression).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+
 def ref_constructor(loader, tag_suffix, node):
     if tag_suffix == "id":
         kwargs = {"id": loader.construct_scalar(node)}
@@ -177,6 +189,8 @@
     yaml.add_constructor(u"!delete", delete_constructor)
     yaml.add_constructor(u"!url", url_constructor)
     yaml.add_constructor(u"!eval", eval_constructor)
+    yaml.add_constructor(u"!date", date_constructor)
+    yaml.add_constructor(u"!datetime", datetime_constructor)
     yaml.add_multi_constructor(u"!ref", ref_constructor)
     yaml.add_constructor(u"!ir_set", ir_set_constructor)
 add_constructors()


Follow ups