From 451f2eb597cecf2a39a4ee9289f37241845f26ed Mon Sep 17 00:00:00 2001
From: lsowen <logan.owen@***********.com>
Date: Tue, 24 Apr 2012 16:36:40 -0400
Subject: [PATCH] add automatic serialization/deserializtion for dateTime type

---
 generateDS.py |   88 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/generateDS.py b/generateDS.py
index 32892da..8a5e873 100755
--- a/generateDS.py
+++ b/generateDS.py
@@ -1432,7 +1432,6 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
     child_type = child.getType()
     if child_type in StringType or \
         child_type == TokenType or \
-        child_type == DateTimeType or \
         child_type == TimeType or \
         child_type == DateType:
         wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
@@ -1497,6 +1496,12 @@ def generateExportFn_1(wrt, child, name, namespace, fill):
         s1 = "%s            outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_base64(self.%s, input_name='%s'), namespace_, eol_))\n" % \
             (fill, name, name, mappedName, name, )
         wrt(s1)
+    elif child_type == DateTimeType:
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
+        wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
+        s1 = "%s            outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_datetime(self.%s, input_name='%s'), namespace_, eol_))\n" % \
+            (fill, name, name, mappedName, name, )
+        wrt(s1)
     else:
         wrt("%s        if self.%s is not None:\n" % (fill, mappedName))
         # name_type_problem
@@ -1518,7 +1523,6 @@ def generateExportFn_2(wrt, child, name, namespace, fill):
     wrt("%s    for %s_ in self.%s:\n" % (fill, cleanName, mappedName, ))
     if child_type in StringType or \
         child_type == TokenType or \
-        child_type == DateTimeType or \
         child_type == TimeType or \
         child_type == DateType:
         wrt('%s        showIndent(outfile, level, pretty_print)\n' % fill)
@@ -1570,6 +1574,11 @@ def generateExportFn_2(wrt, child, name, namespace, fill):
         s1 = "%s        outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_base64(%s_, input_name='%s'), namespace_, eol_))\n" % \
             (fill, name, name, cleanName, name, )
         wrt(s1)
+    elif child_type == DateTimeType:
+        wrt('%s        showIndent(outfile, level, pretty_print)\n' % fill)
+        s1 = "%s        outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_datetime(%s_, input_name='%s'), namespace_, eol_))\n" % \
+            (fill, name, name, cleanName, name, )
+        wrt(s1)
     else:
         # name_type_problem
         if False:        # name == child.getType():
@@ -1588,7 +1597,6 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
     # fix_simpletype
     if child_type in StringType or \
         child_type == TokenType or \
-        child_type == DateTimeType or \
         child_type == TimeType or \
         child_type == DateType:
         wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
@@ -1653,6 +1661,12 @@ def generateExportFn_3(wrt, child, name, namespace, fill):
         s1 = "%s            outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_base64(self.%s, input_name='%s'), namespace_, eol_))\n" % \
             (fill, name, name, mappedName, name, )
         wrt(s1)
+    elif child_type == DateTimeType:
+        wrt('%s        if self.%s is not None:\n' % (fill, mappedName, ))
+        wrt('%s            showIndent(outfile, level, pretty_print)\n' % fill)
+        s1 = "%s            outfile.write('<%%s%s>%%s</%%s%s>%%s' %% (namespace_, self.gds_format_datetime(self.%s, input_name='%s'), namespace_, eol_))\n" % \
+            (fill, name, name, mappedName, name, )
+        wrt(s1)
     else:
         wrt("%s        if self.%s is not None:\n" % (fill, mappedName))
         # name_type_problem
@@ -1686,7 +1700,6 @@ def generateExportAttributes(wrt, element, hasAttributes):
             if (attrDef.getType() in StringType or
                 attrDef.getType() in IDTypes or
                 attrDef.getType() == TokenType or
-                attrDef.getType() == DateTimeType or
                 attrDef.getType() == TimeType or
                 attrDef.getType() == DateType):
                 s1 = '''%s        outfile.write(' %s=%%s' %% (self.gds_format_string(quote_attrib(self.%s).encode(ExternalEncoding), input_name='%s'), ))\n''' % \
@@ -1708,6 +1721,9 @@ def generateExportAttributes(wrt, element, hasAttributes):
             elif attrDef.getType() == DoubleType:
                 s1 = '''%s        outfile.write(' %s="%%s"' %% self.gds_format_double(self.%s, input_name='%s'))\n''' % (
                     indent, name, cleanName, name)
+            elif attrDef.getType() == DateTimeType:
+                s1 = '''%s        outfile.write(' %s="%%s"' %% self.gds_format_datetime(self.%s, input_name='%s'))\n''' % (
+                    indent, name, cleanName, name)
             else:
                 s1 = '''%s        outfile.write(' %s=%%s' %% (quote_attrib(self.%s), ))\n''' % (
                     indent, name, cleanName, )
@@ -2422,7 +2438,6 @@ def generateBuildStandard_1(wrt, prefix, child, headChild,
     if (attrCount == 0 and
         ((childType in StringType or
             childType == TokenType or
-            childType == DateTimeType or
             childType == TimeType or
             childType == DateType or
             child.isListType()
@@ -2516,6 +2531,15 @@ def generateBuildStandard_1(wrt, prefix, child, headChild,
             wrt("            self.%s.append(fval_)\n" % (mappedName, ))
         else:
             wrt("            self.%s = fval_\n" % (mappedName, ))
+    elif childType == DateTimeType:
+        wrt("        %s nodeName_ == '%s':\n" % (keyword, origName, ))
+        wrt("            sval_ = child_.text\n")
+        wrt("            dval_ = self.gds_parse_datetime(sval_, node, '%s')\n" % (
+            name, ))
+        if child.getMaxOccurs() > 1:
+            wrt("            self.%s.append(dval_)\n" % (mappedName, ))
+        else:
+            wrt("            self.%s = dval_\n" % (mappedName, ))
     elif childType == Base64Type:
         wrt("        %s nodeName_ == '%s':\n" % (keyword, origName, ))
         wrt("            sval_ = child_.text\n")
@@ -2523,7 +2547,7 @@ def generateBuildStandard_1(wrt, prefix, child, headChild,
         wrt("                bval_ = base64.b64decode(sval_)\n")
         wrt("            except (TypeError, ValueError), exp:\n")
         wrt("                raise_parse_error(child_, 'requires base64 encoded string: %s' % exp)\n")
-        wrt("            fval_ = self.gds_validate_base64(bval_, node, '%s')\n" % (
+        wrt("            bval_ = self.gds_validate_base64(bval_, node, '%s')\n" % (
             name, ))
         if child.getMaxOccurs() > 1:
             wrt("            self.%s.append(bval_)\n" % (mappedName, ))
@@ -2830,6 +2854,7 @@ def buildCtorArgs_aux(addedArgs, add, element):
             childType = child.getType()
             if childType in StringType or \
                 childType == TokenType or \
+                childType == Base64Type or \
                 childType == DateTimeType or \
                 childType == TimeType or \
                 childType == DateType:
@@ -3322,6 +3347,8 @@ import sys
 import getopt
 import re as re_
 import base64
+from datetime import datetime, tzinfo, timedelta
+
 
 etree_ = None
 Verbose_import_ = False
@@ -3449,6 +3476,55 @@ except ImportError, exp:
                 if value not in ('true', '1', 'false', '0', ):
                     raise_parse_error(node, 'Requires sequence of booleans ("true", "1", "false", "0")')
             return input_data
+        def gds_validate_datetime(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_datetime(self, input_data, input_name=''):
+            _svalue = input_data.strftime('%%Y-%%m-%%dT%%H:%%M:%%S')
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            return _svalue
+        def gds_parse_datetime(self, input_data, node, input_name=''):
+            class _FixedOffsetTZ(tzinfo):
+                def __init__(self, offset, name):
+                    self.__offset = timedelta(minutes = offset)
+                    self.__name = name
+
+                def utcoffset(self, dt):
+                    return self.__offset
+
+                def tzname(self, dt):
+                    return self.__name
+
+                def dst(self, dt):
+                    return None
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = _FixedOffsetTZ(0, 'GMT')
+                input_data = input_data[:-1]
+            else:
+                tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
+                results = tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = _FixedOffsetTZ( tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            return datetime.strptime(input_data, '%%Y-%%m-%%dT%%H:%%M:%%S').replace(tzinfo = tz)
         def gds_str_lower(self, instring):
             return instring.lower()
         def get_path_(self, node):
-- 
1.7.1

