From 0777933d7dd73a2b91af5577a7c8a9407a6c5629 Mon Sep 17 00:00:00 2001 From: hvelarde Date: Wed, 27 Aug 2014 19:23:12 -0300 Subject: [PATCH] Implement automatic loading of new micro-updates using AJAX calls --- src/collective/liveblog/browser/__init__.py | 3 + .../liveblog/browser/add_microupdate.py | 39 +++++++ .../liveblog/browser/configure.zcml | 7 ++ .../liveblog/browser/templates/updates.pt | 22 ++++ .../liveblog/{ => browser}/templates/view.pt | 41 ++++--- src/collective/liveblog/browser/updates.py | 38 +++++++ .../liveblog/{browser.py => browser/view.py} | 41 ++----- src/collective/liveblog/configure.zcml | 1 + .../tests/test_add_microupdate_view.py | 39 +++++++ src/collective/liveblog/tests/test_views.py | 102 ++++++++++++++---- src/collective/liveblog/utils.py | 9 ++ 11 files changed, 277 insertions(+), 65 deletions(-) create mode 100644 src/collective/liveblog/browser/__init__.py create mode 100644 src/collective/liveblog/browser/add_microupdate.py create mode 100644 src/collective/liveblog/browser/configure.zcml create mode 100644 src/collective/liveblog/browser/templates/updates.pt rename src/collective/liveblog/{ => browser}/templates/view.pt (53%) create mode 100644 src/collective/liveblog/browser/updates.py rename src/collective/liveblog/{browser.py => browser/view.py} (61%) create mode 100644 src/collective/liveblog/tests/test_add_microupdate_view.py create mode 100644 src/collective/liveblog/utils.py diff --git a/src/collective/liveblog/browser/__init__.py b/src/collective/liveblog/browser/__init__.py new file mode 100644 index 0000000..9d624b5 --- /dev/null +++ b/src/collective/liveblog/browser/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from .view import View # noqa +from .add_microupdate import AddMicroUpdateView # noqa diff --git a/src/collective/liveblog/browser/add_microupdate.py b/src/collective/liveblog/browser/add_microupdate.py new file mode 100644 index 0000000..e074e46 --- /dev/null +++ b/src/collective/liveblog/browser/add_microupdate.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from collective.liveblog import _ +from collective.liveblog.adapters import IMicroUpdateContainer +from collective.liveblog.adapters import MicroUpdate +from collective.liveblog.interfaces import IBrowserLayer +from collective.liveblog.interfaces import ILiveblog +from five import grok +from plone import api +from zope.event import notify +from zope.lifecycleevent import ObjectModifiedEvent + +grok.templatedir('templates') + + +class AddMicroUpdateView(grok.View): + + """Add a micro-update to the Liveblog.""" + + grok.context(ILiveblog) + grok.layer(IBrowserLayer) + grok.name('add-microupdate') + grok.require('collective.liveblog.AddMicroUpdate') + + def render(self): + title = self.request.form.get('title', None) + text = self.request.form.get('text', None) + if not text: + msg = _(u'There were some errors. Required input is missing.') + api.portal.show_message(msg, self.request, type='error') + else: + adapter = IMicroUpdateContainer(self.context) + adapter.add(MicroUpdate(title, text)) + + # notify the Liveblog has a new micro-update + notify(ObjectModifiedEvent(self.context)) + msg = _(u'Item published.') + api.portal.show_message(msg, self.request) + + self.request.response.redirect(self.context.absolute_url()) diff --git a/src/collective/liveblog/browser/configure.zcml b/src/collective/liveblog/browser/configure.zcml new file mode 100644 index 0000000..d5fb2df --- /dev/null +++ b/src/collective/liveblog/browser/configure.zcml @@ -0,0 +1,7 @@ + + + diff --git a/src/collective/liveblog/browser/templates/updates.pt b/src/collective/liveblog/browser/templates/updates.pt new file mode 100644 index 0000000..55ce3df --- /dev/null +++ b/src/collective/liveblog/browser/templates/updates.pt @@ -0,0 +1,22 @@ + + +
+
+

+ +

+
+ +
+
+ + diff --git a/src/collective/liveblog/templates/view.pt b/src/collective/liveblog/browser/templates/view.pt similarity index 53% rename from src/collective/liveblog/templates/view.pt rename to src/collective/liveblog/browser/templates/view.pt index 49fe3fb..f1d9f6d 100644 --- a/src/collective/liveblog/templates/view.pt +++ b/src/collective/liveblog/browser/templates/view.pt @@ -5,6 +5,7 @@ xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="collective.liveblog"> +

Add micro-update

@@ -28,21 +29,37 @@
-
-
- +
+
+

+ +

+
+
-
-

-

-
- By - +
+

+ No micro-updates yet for this Liveblog. +

+
+
-

- No micro-updates yet for this Liveblog. -

+ diff --git a/src/collective/liveblog/browser/updates.py b/src/collective/liveblog/browser/updates.py new file mode 100644 index 0000000..9a5abdd --- /dev/null +++ b/src/collective/liveblog/browser/updates.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from collective.liveblog.interfaces import IBrowserLayer +from collective.liveblog.interfaces import ILiveblog +from five import grok +from plone.memoize import ram +from time import time + +grok.templatedir('templates') + + +class Updates(grok.View): + + """Helper view for Liveblog.""" + + grok.context(ILiveblog) + grok.layer(IBrowserLayer) + grok.require('zope2.View') + + def _updates_since_timestamp(self): + """Return the list of micro-updates since the specified timestamp.""" + timestamp = self.request.get('timestamp', None) + + # timestamp should a string representing a float + try: + float(timestamp) + except (TypeError, ValueError): + return [] + + updates = self.context.restrictedTraverse('view').updates() + updates = [u for u in updates if u['timestamp'] > timestamp] + return updates + + @ram.cache(lambda *args: time() // 20) + def updates_since_timestamp(self): + """Return the list of micro-updates since the specified timestamp; + the list is cached for 20 seconds. + """ + return self._updates_since_timestamp() diff --git a/src/collective/liveblog/browser.py b/src/collective/liveblog/browser/view.py similarity index 61% rename from src/collective/liveblog/browser.py rename to src/collective/liveblog/browser/view.py index e66c032..6d14f9c 100644 --- a/src/collective/liveblog/browser.py +++ b/src/collective/liveblog/browser/view.py @@ -1,14 +1,12 @@ # -*- coding: utf-8 -*- -from collective.liveblog import _ from collective.liveblog.adapters import IMicroUpdateContainer -from collective.liveblog.adapters import MicroUpdate from collective.liveblog.interfaces import IBrowserLayer from collective.liveblog.interfaces import ILiveblog +from collective.liveblog.utils import _timestamp +from datetime import datetime from five import grok from plone import api from plone.memoize import ram -from zope.event import notify -from zope.lifecycleevent import ObjectModifiedEvent grok.templatedir('templates') @@ -42,6 +40,7 @@ def _updates(self): updates.append(dict( id=id + 1, creator=update.creator, + timestamp=_timestamp(update.created), created=api.portal.get_localized_time(update.created, True), time_only=api.portal.get_localized_time(update.created, time_only=True), title=update.title, @@ -52,35 +51,17 @@ def _updates(self): @ram.cache(_render_updates_cachekey) def updates(self): + """Return the list of micro-updates in the Liveblog in reverse order; + the list is cached until a new update is published. + """ return self._updates() @property def has_updates(self): + """Return True if Liveblog has updates.""" return len(self.updates()) > 0 - -class AddMicroUpdateView(grok.View): - - """Add a micro-update to the Liveblog.""" - - grok.context(ILiveblog) - grok.layer(IBrowserLayer) - grok.name('add-microupdate') - grok.require('collective.liveblog.AddMicroUpdate') - - def render(self): - title = self.request.form.get('title', None) - text = self.request.form.get('text', None) - if not text: - msg = _(u'There were some errors. Required input is missing.') - api.portal.show_message(msg, self.request, type='error') - else: - adapter = IMicroUpdateContainer(self.context) - adapter.add(MicroUpdate(title, text)) - - # notify the Liveblog has a new micro-update - notify(ObjectModifiedEvent(self.context)) - msg = _(u'Item published.') - api.portal.show_message(msg, self.request) - - self.request.response.redirect(self.context.absolute_url()) + @property + def now(self): + """Return a timestamp for the current date and time.""" + return _timestamp(datetime.now()) diff --git a/src/collective/liveblog/configure.zcml b/src/collective/liveblog/configure.zcml index 995267b..68b1637 100644 --- a/src/collective/liveblog/configure.zcml +++ b/src/collective/liveblog/configure.zcml @@ -30,6 +30,7 @@ +