[Checkins] SVN: Grokstar/trunk/ Introduce the use of hurry.workflow
to workflow the blog. Right now
Martijn Faassen
faassen at infrae.com
Thu Feb 1 17:25:16 EST 2007
Log message for revision 72314:
Introduce the use of hurry.workflow to workflow the blog. Right now
we've implemented a very simple, non-versioned workflow from
CREATED to PUBLISHED. Entries that have not yet been PUBLISHED do
not show up on the blog frontpage or the calendar. You need to
edit them (by remembering their name and adding it behind the blog root URL and
doing '/edit' :) and click 'publish'.
Changed:
U Grokstar/trunk/buildout.cfg
U Grokstar/trunk/setup.py
U Grokstar/trunk/src/grokstar/blog.py
U Grokstar/trunk/src/grokstar/calendar.py
U Grokstar/trunk/src/grokstar/entry.py
U Grokstar/trunk/src/grokstar/interfaces.py
A Grokstar/trunk/src/grokstar/workflow.py
-=-
Modified: Grokstar/trunk/buildout.cfg
===================================================================
--- Grokstar/trunk/buildout.cfg 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/buildout.cfg 2007-02-01 22:25:15 UTC (rev 72314)
@@ -7,6 +7,15 @@
extra_options = --with-python=${buildout:executable} --force
url = http://www.zope.org/Products/Zope3/3.3.0/Zope-3.3.0.tgz
+# the above part might not work if you have Python 2.4.4. This version
+# of Python is not compatible with Zope 3.3.0. Instead, you can *remove*
+# the 'zope3' name from the 'parts' listing in the [buildout] section,
+# and uncomment what's below. Check out a version of Zope 3.3 branch
+# and do 'make inplace', and point to it with 'location' below. Then
+# rerun bin/buildout
+# [zope3]
+# location = /home/faassen/buildout/Zope3.3
+
[data]
recipe = zc.recipe.filestorage
@@ -42,6 +51,7 @@
grokstar
hurry.query
zc.catalog
+ hurry.workflow
[test]
recipe = zc.recipe.testrunner
Modified: Grokstar/trunk/setup.py
===================================================================
--- Grokstar/trunk/setup.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/setup.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -21,6 +21,7 @@
install_requires=['setuptools',
'grok',
'hurry.query',
+ 'hurry.workflow',
],
entry_points="""
# -*- Entry points: -*-
Modified: Grokstar/trunk/src/grokstar/blog.py
===================================================================
--- Grokstar/trunk/src/grokstar/blog.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/src/grokstar/blog.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -8,11 +8,18 @@
from zope.app.catalog.interfaces import ICatalog
from zope.app.catalog.field import FieldIndex
+from hurry.query.query import Query
+from hurry import query
+from hurry.workflow.interfaces import IWorkflowState
+
import grok
-from grokstar.interfaces import IEntry
+from grokstar.interfaces import IEntry, PUBLISHED
+
def setup_catalog(catalog):
catalog['published'] = FieldIndex('published', IEntry)
+ catalog['workflow_state'] = FieldIndex('getState', IWorkflowState, True)
+ catalog['workflow_id'] = FieldIndex('getId', IWorkflowState, True)
class Blog(grok.Container, grok.Site):
@@ -55,7 +62,10 @@
return "Entries: %s" % ' '.join(self.context.keys())
def lastEntries(amount):
- entries = grok.getSite()['entries'].values()
+ entries = Query().searchResults(
+ query.Eq(('entry_catalog', 'workflow_state'),
+ PUBLISHED))
+
return sorted(
entries, key=lambda entry: entry.published, reverse=True
)[:amount]
Modified: Grokstar/trunk/src/grokstar/calendar.py
===================================================================
--- Grokstar/trunk/src/grokstar/calendar.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/src/grokstar/calendar.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -5,6 +5,8 @@
from hurry.query.query import Query
from hurry import query
+from grokstar.interfaces import PUBLISHED
+
class Year(grok.Model):
def __init__(self, year):
self.year = year
@@ -78,7 +80,9 @@
def entriesInDateRange(from_, until):
entries = Query().searchResults(
- query.Between(('entry_catalog', 'published'), from_, until))
+ query.And(query.Between(('entry_catalog', 'published'), from_, until),
+ query.Eq(('entry_catalog', 'workflow_state'), PUBLISHED)))
+
return sorted(
entries, key=lambda entry: entry.published, reverse=True
)
Modified: Grokstar/trunk/src/grokstar/entry.py
===================================================================
--- Grokstar/trunk/src/grokstar/entry.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/src/grokstar/entry.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -2,19 +2,22 @@
from docutils.core import publish_parts
from zope import schema, interface
+from zope.annotation.interfaces import IAttributeAnnotatable
+from hurry.workflow.interfaces import IWorkflowInfo
+
import grok
from grokstar.blog import Blog
from grokstar import interfaces
class Entry(grok.Model):
- interface.implements(interfaces.IEntry)
+ interface.implements(interfaces.IEntry, IAttributeAnnotatable)
def __init__(self, title, summary, rightsinfo):
self.title = title
self.updated = datetime.now()
- self.published = datetime.now()
+ self.published = None
self.summary = summary
self.rightsinfo = rightsinfo
@@ -37,7 +40,9 @@
@grok.action('Add entry')
def add(self, id, **data):
- self.context['entries'][id] = RestructuredTextEntry(**data)
+ new_entry = RestructuredTextEntry(**data)
+ self.context['entries'][id] = new_entry
+ IWorkflowInfo(new_entry).fireTransition('create')
self.redirect(self.url(self.context))
class Edit(grok.EditForm):
@@ -49,6 +54,13 @@
self.applyChanges(**data)
self.redirect(self.url(self.context))
+ @grok.action('Publish')
+ def publish(self, **data):
+ self.applyChanges(**data)
+ self.context.published = datetime.now()
+ IWorkflowInfo(self.context).fireTransitionToward(interfaces.PUBLISHED)
+ self.redirect(self.url(self.context))
+
class RenderedContent(grok.View):
def render(self):
return renderRest(self.context.content)
Modified: Grokstar/trunk/src/grokstar/interfaces.py
===================================================================
--- Grokstar/trunk/src/grokstar/interfaces.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/src/grokstar/interfaces.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -1,6 +1,9 @@
from zope.interface import Interface
from zope import schema, interface
+CREATED = 0
+PUBLISHED = 1
+
class IEntry(Interface):
"""
This interface is based on the Atom entry definition, from the Atom RFC.
Added: Grokstar/trunk/src/grokstar/workflow.py
===================================================================
--- Grokstar/trunk/src/grokstar/workflow.py 2007-02-01 22:05:59 UTC (rev 72313)
+++ Grokstar/trunk/src/grokstar/workflow.py 2007-02-01 22:25:15 UTC (rev 72314)
@@ -0,0 +1,65 @@
+import grok
+from grokstar.entry import Entry
+from hurry.workflow import workflow
+from hurry.workflow.interfaces import IWorkflow
+from hurry.query.query import Query
+from hurry.query import Eq
+
+from grokstar.interfaces import CREATED, PUBLISHED
+
+def create_workflow():
+ create_transition = workflow.Transition(
+ transition_id='create',
+ title='create',
+ source=None,
+ destination=CREATED)
+
+ publish_transition = workflow.Transition(
+ transition_id='publish',
+ title='publish',
+ source=CREATED,
+ destination=PUBLISHED)
+
+ update_transition = workflow.Transition(
+ transition_id='update',
+ title='update',
+ source=PUBLISHED,
+ destination=PUBLISHED)
+
+ return [create_transition, publish_transition, update_transition]
+
+class Workflow(grok.GlobalUtility, workflow.Workflow):
+ # grok.name('grokstar_workflow')
+ grok.provides(IWorkflow)
+
+ def __init__(self):
+ super(Workflow, self).__init__(create_workflow())
+
+class Versions(grok.GlobalUtility, workflow.WorkflowVersions):
+
+ def getVersions(self, state, id):
+ q = Query()
+ return q.searchResults(
+ Eq(('entry_catalog', 'workflow_state'),
+ state) &
+ Eq(('entry_catalog', 'workflow_id'),
+ id))
+
+ def getVersionsWithAutomaticTransitions(self):
+ return []
+
+ def hasVersion(self, id, state):
+ return bool(len(self.getVersions(state, id)))
+
+ def hasVersionId(self, id):
+ q = Query()
+ result = q.searchResults(
+ Eq(('entry_catalog', 'workflow_id'), id))
+ return bool(len(result))
+
+class WorkflowState(grok.Adapter, workflow.WorkflowState):
+ grok.context(Entry)
+
+class WorkflowInfo(grok.Adapter, workflow.WorkflowInfo):
+ grok.context(Entry)
+
More information about the Checkins
mailing list