Skip to content

Commit

Permalink
Merge pull request #18 from collective/add-datetime-deserializer
Browse files Browse the repository at this point in the history
Implement new deserializer for datetime fields.
  • Loading branch information
jone committed Aug 28, 2015
2 parents 4f4216e + 648d421 commit 5def5d4
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGES.rst
Expand Up @@ -5,7 +5,8 @@ Changelog
1.5.3 (unreleased)
------------------

- Nothing changed yet.
- Implement new deserializer for datetime fields.
[mbaechtold]


1.5.2 (2015-07-13)
Expand Down
5 changes: 5 additions & 0 deletions README.rst
Expand Up @@ -34,6 +34,11 @@ Actually tested and supported fields
needs a datetime.date or datetime.datetime object, or a string in the
following format "%Y-%m-%d"

- Datetime
needs a datetime.datetime object, or a string parseable by
`DateTime.DateTime` e.g. "2015-12-31 17:59:59"
or "2004/12/30 00:20:00 GMT+1" etc.


Default pipelines
=================
Expand Down
29 changes: 29 additions & 0 deletions transmogrify/dexterity/converters.py
@@ -1,5 +1,6 @@
from .interfaces import IDeserializer
from .interfaces import ISerializer
from DateTime import DateTime
from datetime import datetime
from plone.app.textfield.interfaces import IRichText
from plone.app.textfield.value import RichTextValue
Expand All @@ -11,6 +12,7 @@
from zope.interface import implementer
from zope.schema.interfaces import ICollection
from zope.schema.interfaces import IDate
from zope.schema.interfaces import IDatetime
from zope.schema.interfaces import IField
from zope.schema.interfaces import IFromUnicode
from zope.schema.interfaces import IObject
Expand Down Expand Up @@ -382,6 +384,33 @@ def __call__(self, value, filestore, item,
return value


@implementer(IDeserializer)
@adapter(IDatetime)
class DatetimeDeserializer(object):

def __init__(self, field):
self.field = field

def __call__(self, value, filestore, item,
disable_constraints=False, logger=None):
if isinstance(value, basestring):
value = DateTime(value).asdatetime()
try:
self.field.validate(value)
except Exception as e:
if not disable_constraints:
raise e
else:
if logger:
logger(
"%s is invalid in %s: %s" % (
self.field.__name__,
item['_path'],
e)
)
return value


@implementer(ISerializer)
@adapter(IField)
class DefaultSerializer(object):
Expand Down
1 change: 1 addition & 0 deletions transmogrify/dexterity/converters.zcml
Expand Up @@ -16,6 +16,7 @@
<adapter factory=".converters.CollectionDeserializer" />

<adapter factory=".converters.DateDeserializer" />
<adapter factory=".converters.DatetimeDeserializer" />

<adapter factory=".converters.DefaultSerializer" />
<adapter factory=".converters.DefaultDeserializer" />
Expand Down
7 changes: 7 additions & 0 deletions transmogrify/dexterity/testing.py
Expand Up @@ -2,6 +2,7 @@
from collective.transmogrifier.interfaces import ISectionBlueprint
from collective.transmogrifier.sections.tests import SampleSource
from datetime import date
from datetime import datetime
from ftw.builder.testing import BUILDER_LAYER
from ftw.builder.testing import functional_session_factory
from ftw.builder.testing import set_builder_session_factory
Expand Down Expand Up @@ -72,6 +73,10 @@ class ITestSchema(form.Schema):
title=u'test_date',
)

test_datetime = schema.Datetime(
title=u'test_datetime',
)

fancy_text = RichText(
title=u"Fancy text",
)
Expand Down Expand Up @@ -131,6 +136,7 @@ def __init__(self, transmogrifier, name, options, previous):
'data': zptlogo,
'filename': 'zptlogo.gif'},
test_date='2010-10-12',
test_datetime='2010-10-12 17:59:59',
fieldnotchanged='nochange',
),
dict(_path='/two',
Expand All @@ -142,6 +148,7 @@ def __init__(self, transmogrifier, name, options, previous):
test_file=zptlogo,
_filename="testlogo.gif",
test_date=date(2010, 0o1, 0o1, ),
test_datetime=datetime(2010, 0o1, 0o1, 17, 59, 59),
fieldnotchanged='nochange',
),
)
Expand Down
8 changes: 8 additions & 0 deletions transmogrify/dexterity/tests/schemaupdater.txt
Expand Up @@ -70,6 +70,14 @@ DateFields:
>>> two.test_date
datetime.date(2010, 1, 1)

DatetimeFields:

>>> spam.test_datetime
datetime.datetime(2010, 10, 12, 17, 59, 59)

>>> two.test_datetime
datetime.datetime(2010, 1, 1, 17, 59, 59)

Won't touch already existing values

>>> transmogrifier = Transmogrifier(portal)
Expand Down
20 changes: 20 additions & 0 deletions transmogrify/dexterity/tests/testconverters.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from ftw.builder import Builder
from ftw.builder import create
from plone.app.textfield import RichText
Expand All @@ -9,6 +10,7 @@
from z3c.relationfield.relation import RelationValue
from z3c.relationfield.schema import RelationChoice
from z3c.relationfield.schema import RelationList
from zope.schema import Datetime
import pprint
import unittest
import zope.testing
Expand Down Expand Up @@ -195,3 +197,21 @@ def test_filestore(self):
"x-application/cow",
"Content type from dict should override default")
self.assertEqual(rtv.encoding, "latin-1")


class TestDatetimeDeserializer(unittest.TestCase):

layer = TRANSMOGRIFY_DEXTERITY_FUNCTIONAL_TESTING

def setUp(test):
test.pp = pprint.PrettyPrinter(indent=4)
# TODO: This should read the zcml instead
zope.component.provideAdapter(converters.DatetimeDeserializer)

def test_datetime_deserializer(self):
deserializer = IDeserializer(Datetime())
value = deserializer('2015-12-31 17:59:59', None, None)
self.assertEqual(
datetime(2015, 12, 31, 17, 59, 59),
value
)

0 comments on commit 5def5d4

Please sign in to comment.