Hi,

Adds a parameter that represents a DateTime format using datetime.datetime
object from python's native datetime library.

In the CLI, accepts one of the following formats:
Accepts subset of values defined by ISO 8601:
%Y-%m-%dT%H:%M:%S
%Y-%m-%dT%H:%M
'%Y%m%dT%H:%M:%S'
'%Y%m%dT%H:%M'

Also accepts LDAP Generalized time in the following format:
'%Y%m%d%H%M%SZ'

As a simplification, it does not deal with timezone info and ISO 8601
values with timezone info (+-hhmm) are rejected. Values are expected
to be in the UTC timezone.

Values are saved to LDAP as LDAP Generalized time values in the format
'%Y%m%d%H%SZ' (no time fractions and UTC timezone is assumed). To avoid
confusion, in addition to subset of ISO 8601 values, the LDAP generalized
time in the format '%Y%m%d%H%M%SZ' is also accepted as an input (as this
is the
format user will see on the output).

Part of: https://fedorahosted.org/freeipa/ticket/3306

>From 26a57febd0a1b920cb0857f3a12912bb69c82d90 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Thu, 9 Jan 2014 11:14:56 +0100
Subject: [PATCH 137/140] ipalib: Add DateTime parameter

Adds a parameter that represents a DateTime format using datetime.datetime
object from python's native datetime library.

In the CLI, accepts one of the following formats:
    Accepts subset of values defined by ISO 8601:
        %Y-%m-%dT%H:%M:%S
        %Y-%m-%dT%H:%M
       '%Y%m%dT%H:%M:%S'
       '%Y%m%dT%H:%M'

    Also accepts LDAP Generalized time without in the following format:
       '%Y%m%d%H%M%SZ'

As a simplification, it does not deal with timezone info and ISO 8601
values with timezone info (+-hhmm) are rejected. Values are expected
to be in the UTC timezone.

Values are saved to LDAP as LDAP Generalized time values in the format
'%Y%m%d%H%SZ' (no time fractions and UTC timezone is assumed). To avoid
confusion, in addition to subset of ISO 8601 values, the LDAP generalized
time in the format '%Y%m%d%H%M%SZ' is also accepted as an input (as this is the
format user will see on the output).

Part of: https://fedorahosted.org/freeipa/ticket/3306
---
 ipalib/__init__.py   |  2 +-
 ipalib/parameters.py | 45 +++++++++++++++++++++++++++++++++++++++++++++
 ipalib/rpc.py        | 14 ++++++++++++--
 ipapython/ipaldap.py |  3 +++
 4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/ipalib/__init__.py b/ipalib/__init__.py
index ab89ab77ec94603d242e56436021c9b6ed8663cb..5dfeab3326f0a7b77120f2ef560cf08e8b9aa704 100644
--- a/ipalib/__init__.py
+++ b/ipalib/__init__.py
@@ -886,7 +886,7 @@ from frontend import Command, LocalOrRemote, Updater, Advice
 from frontend import Object, Method, Property
 from crud import Create, Retrieve, Update, Delete, Search
 from parameters import DefaultFrom, Bool, Flag, Int, Decimal, Bytes, Str, IA5Str, Password, DNParam, DeprecatedParam
-from parameters import BytesEnum, StrEnum, IntEnum, AccessTime, File
+from parameters import BytesEnum, StrEnum, IntEnum, AccessTime, File, DateTime
 from errors import SkipPluginModule
 from text import _, ngettext, GettextFactory, NGettextFactory
 
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index 757c185655bbe1b586fbf088256891a7e7558876..eb5d57fc8da3a1f3796abf6c9d08412ed2181dae 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -102,6 +102,7 @@ a more detailed description for clarity.
 import re
 import decimal
 import base64
+import datetime
 from xmlrpclib import MAXINT, MININT
 
 from types import NoneType
@@ -1602,6 +1603,50 @@ class File(Str):
         ('noextrawhitespace', bool, False),
     )
 
+class DateTime(Param):
+    """
+    DateTime parameter type.
+
+    Accepts subset of values defined by ISO 8601:
+        %Y-%m-%dT%H:%M:%S
+        %Y-%m-%dT%H:%M
+       '%Y%m%dT%H:%M:%S'
+       '%Y%m%dT%H:%M'
+
+    Also accepts LDAP Generalized time without in the following format:
+       '%Y%m%d%H%M%SZ'
+
+    Refer to the `man strftime` for the explanations for the %Y,%m,%d,%H.%M,%S.
+    """
+
+    accepted_formats = ['%Y-%m-%dT%H:%M:%S',
+                        '%Y-%m-%dT%H:%M',
+                        '%Y%m%dT%H:%M:%S',
+                        '%Y%m%dT%H:%M',
+                        '%Y%m%d%H%M%SZ']
+
+    type = datetime.datetime
+
+    def _convert_scalar(self, value, index=None):
+        if isinstance(value, datetime.datetime):
+            return value
+        elif isinstance(value, str) or isinstance(value, unicode):
+            for date_format in self.accepted_formats:
+                try:
+                    time = datetime.datetime.strptime(value, date_format)
+                    return time
+                except ValueError:
+                    pass
+
+            # If we get here, the strptime call did not succeed for any
+            # the accepted formats, therefore raise error
+
+            error = "does not match any of accepted formats: %s" % self.accepted_formats
+
+            raise ValidationError(name=self.name,
+                                  value=value,
+                                  index=index,
+                                  error=error)
 
 class AccessTime(Str):
     """
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index 3d6cc3f2cf90384bb29a7f002415abe93e43562e..fdbb04770c64f956d4f6aff76315e9df388f7e46 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -33,6 +33,7 @@ Also see the `ipaserver.rpcserver` module.
 from types import NoneType
 from decimal import Decimal
 import sys
+import datetime
 import os
 import locale
 import base64
@@ -41,8 +42,8 @@ import json
 import socket
 from urllib2 import urlparse
 
-from xmlrpclib import (Binary, Fault, dumps, loads, ServerProxy, Transport,
-        ProtocolError, MININT, MAXINT)
+from xmlrpclib import (Binary, Fault, DateTime, dumps, loads, ServerProxy,
+        Transport, ProtocolError, MININT, MAXINT)
 import kerberos
 from dns import resolver, rdatatype
 from dns.exception import DNSException
@@ -162,6 +163,11 @@ def xml_wrap(value):
         return unicode(value)
     if isinstance(value, DN):
         return str(value)
+
+    # Encode datetime.datetime objects as xmlrpclib.DateTime objects
+    if isinstance(value, datetime.datetime):
+        return DateTime(value)
+
     assert type(value) in (unicode, int, long, float, bool, NoneType)
     return value
 
@@ -195,6 +201,8 @@ def xml_unwrap(value, encoding='UTF-8'):
     if isinstance(value, Binary):
         assert type(value.data) is str
         return value.data
+    if isinstance(value, DateTime):
+        return str(value)
     assert type(value) in (unicode, int, float, bool, NoneType)
     return value
 
@@ -264,6 +272,8 @@ def json_encode_binary(val):
         return {'__base64__': base64.b64encode(str(val))}
     elif isinstance(val, DN):
         return str(val)
+    elif isinstance(val, datetime.datetime):
+        return val.strftime("%Y%m%dT%H:%M:%S")
     else:
         return val
 
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index a48879f0a0e0ce943daa6a4692af755d3232e046..14bbcbc3a440ed8b076890a53513d0c31a5c3a60 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -21,6 +21,7 @@
 
 import string
 import time
+import datetime
 import shutil
 from decimal import Decimal
 from copy import deepcopy
@@ -371,6 +372,8 @@ class IPASimpleLDAPObject(object):
         elif isinstance(val, dict):
             dct = dict((self.encode(k), self.encode(v)) for k, v in val.iteritems())
             return dct
+        elif isinstance(val, datetime.datetime):
+            return val.strftime("%Y%m%d%H%M%SZ")
         elif val is None:
             return None
         else:
-- 
1.8.4.2

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to