[quills-dev] [Collective-checkins] r33380 - in Quills/branches/maurits-traversal: . skins/Quills
quills-dev at lists.etria.com quills-dev at lists.etria.comFri Nov 10 21:47:30 UTC 2006
- Previous message: [quills-dev] [Collective-checkins] r33379 - Quills/branches/maurits-traversal
- Next message: [quills-dev] [Collective-checkins] r33381 - Quills/branches/maurits-traversal
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: maurits
Date: Fri Nov 10 21:47:27 2006
New Revision: 33380
Added:
Quills/branches/maurits-traversal/archive.py
Modified:
Quills/branches/maurits-traversal/QuillsWorkflow.py
Quills/branches/maurits-traversal/WeblogArchive.py
Quills/branches/maurits-traversal/configure.zcml
Quills/branches/maurits-traversal/interfaces.py
Quills/branches/maurits-traversal/skins/Quills/weblog_view.pt
Quills/branches/maurits-traversal/skins/Quills/weblogarchive_view.pt
Quills/branches/maurits-traversal/traversal.py
Log:
Lots of refactoring to get a new traversal somewhat working and to
break the rest. :)
Modified: Quills/branches/maurits-traversal/QuillsWorkflow.py
==============================================================================
--- Quills/branches/maurits-traversal/QuillsWorkflow.py (original)
+++ Quills/branches/maurits-traversal/QuillsWorkflow.py Fri Nov 10 21:47:27 2006
@@ -60,7 +60,7 @@
new_state_id="draft",
trigger_type=1,
script_name="",
- after_script_name="moveToWeblogRoot",
+ after_script_name="",
actbox_name="Revert to Draft",
actbox_url="",
actbox_category="workflow",
@@ -72,7 +72,7 @@
new_state_id="published",
trigger_type=1,
script_name="",
- after_script_name="moveToArchive",
+ after_script_name="",
actbox_name="Publish",
actbox_url="",
actbox_category="workflow",
Modified: Quills/branches/maurits-traversal/WeblogArchive.py
==============================================================================
--- Quills/branches/maurits-traversal/WeblogArchive.py (original)
+++ Quills/branches/maurits-traversal/WeblogArchive.py Fri Nov 10 21:47:27 2006
@@ -136,7 +136,9 @@
path={'query':path, 'level': 0},
sort_on = 'effective',
sort_order = 'reverse',
- review_state = 'published')
+ review_state = 'published',
+ effective={ "query": [startDate, endDate],
+ "range": "minmax"})
if num_of_entries > 0:
results = results[:num_of_entries]
@@ -175,7 +177,6 @@
date = DateTime.DateTime(dateString)
year = str(date.year())
month = str(date.mm())
- day = str(date.dd())
if self.archive_type != 'root':
print "You can only build paths in a root archive"
@@ -197,13 +198,9 @@
path, month, title=month, archive_type='month', date=dateString )
path = getattr(path.aq_inner.aq_explicit, month)
- if not hasattr(path.aq_inner.aq_explicit, day):
- self.portal_types.constructContent('WeblogArchive',
- path, day, title=day, archive_type='day', date=dateString)
-
- path = getattr(path.aq_inner.aq_explicit, day)
return path
+
security.declareProtected(permissions.View, 'getModifiedDate')
def getModifiedDate(self):
""" Dirty Convenience method for accessing the effective modification date from syndication.py.
Added: Quills/branches/maurits-traversal/archive.py
==============================================================================
--- (empty file)
+++ Quills/branches/maurits-traversal/archive.py Fri Nov 10 21:47:27 2006
@@ -0,0 +1,235 @@
+#
+# Authors: Maurits van Rees <m.van.rees at zestsoftware.nl>
+#
+# Copyright 2006, Maurits van Rees
+#
+# Adapted from topic.py.
+#
+# This file is part of Quills
+#
+# Quills is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Quills is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Quills; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+###############################################################################
+
+# Standard library imports
+from types import StringTypes
+
+# Zope 3 imports
+from zope.interface import implements
+
+# Zope 2 imports
+from Acquisition import Implicit, aq_base
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass
+
+# CMF imports
+from Products.CMFCore.utils import getToolByName
+
+# CMFPlone imports
+# utils.normalizeString is only available in Plone 2.5.
+# For now, we just use PloneTool.normalizeString, which is available in both
+# 2.1 and 2.5.
+#from Products.CMFPlone.utils import normalizeString
+
+# Product imports
+from interfaces import IWeblogArchive
+from acquiringactions import AcquiringActionProvider
+from DateTime import DateTime
+
+class Archive(AcquiringActionProvider, Implicit):
+ """Implementation of I as a transient wrapper around a simple keyword.
+ """
+
+ implements(IWeblogArchive)
+
+ security = ClassSecurityInfo()
+ security.declareObjectProtected('View')
+
+ def __init__(self, period):
+ # period is expected to be something like:
+ # ['2006', '11', '01'] but possibly just '2006' or
+ # ['2006', '11', 'some-entry-id'].
+ self.archive_type = 'root'
+ if isinstance(period, StringTypes):
+ self.period = [period,]
+ else:
+ self.period = period
+
+ # Set year
+ self.year = None
+
+ if len(self.period) > 0:
+ self.year = period[0]
+ try:
+ self.year = int(self.year)
+ self.archive_type = 'year'
+ except ValueError:
+ pass
+
+ # Set start and end date of period.
+ if self.year is None:
+ self.startDate = None
+ self.endDate = None
+ else:
+ startYear = self.year
+ endYear = self.year
+ # Set month
+ self.month = 0
+ if len(self.period) > 1:
+ self.month = period[1]
+ try:
+ self.month = int(self.month)
+ self.archive_type = 'month'
+ except ValueError:
+ self.month = 0
+
+ # Set day
+ self.day = 0
+ if len(self.period) > 2:
+ self.day = period[2]
+ try:
+ self.day = int(self.day)
+ self.archive_type = 'day'
+ except ValueError:
+ self.day = 0
+
+ if self.month == 0:
+ startMonth = 1
+ endMonth = 12
+ else:
+ startMonth = self.month
+ endMonth = self.month
+ if self.day == 0:
+ startDay = 1
+ if DateTime.isLeapYear(DateTime(self.year,1,1)):
+ leap = 1
+ else:
+ leap = 0
+ endDay = DateTime._month_len[leap][endMonth]
+ else:
+ startDay = self.day
+ endDay = self.day
+
+ startDate = DateTime(startYear, startMonth, startDay)
+ self.startDate = DateTime.earliestTime(startDate)
+ endDate = DateTime(endYear, endMonth, endDay)
+ self.endDate = DateTime.latestTime(endDate)
+
+ # We will cache catalog queries for performance reasons.
+ # This should not cost anything as these objects only last for the
+ # duration of a REQUEST anyway.
+ self.results = None
+
+ security.declareProtected('View', 'getId')
+ def getId(self):
+ """See ITopic.
+ """
+ return self.period[0]
+
+ def getImage(self):
+ """See ITopic.
+ """
+ return None
+
+ security.declareProtected('View', 'getTitle')
+ def getTitle(self):
+ """See ITopic.
+ """
+ return ''
+
+ security.declareProtected('View', 'title_or_id')
+ def title_or_id(self):
+ """See ITopic.
+ """
+ return self.getId()
+
+ security.declareProtected('View', 'getDescription')
+ def getDescription(self):
+ """See ITopic.
+ """
+ return ''
+
+ def getArchiveListing(self):
+ """Get a listing of all sub-archives"""
+ return []
+ contentFilter={
+ 'portal_type': 'WeblogArchive',
+ 'sort_on' : 'created',
+ 'sort_order' : 'reverse',
+ }
+ brains = self.getFolderContents(batch=True,
+ contentFilter=contentFilter)
+ return [brain.getObject() for brain in brains]
+
+ def getArchiveEntryListing(self):
+ """Get a listing of all entries in this archive node"""
+ return []
+ contentFilter={'portal_type': 'WeblogEntry',
+ 'sort_on': 'effective',
+ 'sort_order': 'reverse'}
+ brains = self.getFolderContents(batch=False,
+ contentFilter=contentFilter)
+ return [brain.getObject() for brain in brains]
+
+ security.declareProtected('View', 'getLazyEntries')
+ def getLazyEntries(self):
+ """See ITopic.
+ """
+ # Try to return the cached query if possible
+ if self.results is not None:
+ return self.results
+ weblog = self.quills_tool.getParentWeblog(self)
+ path = '/'.join(weblog.getPhysicalPath())
+ if self.startDate:
+ effectiveQuery = { "query": [self.startDate, self.endDate],
+ "range": "minmax"}
+ else:
+ effective = None
+ self.results = self.portal_catalog(
+ meta_type='WeblogEntry',
+ path={'query':path, 'level': 0},
+ sort_on = 'effective',
+ effective = effectiveQuery,
+ sort_order = 'reverse',
+ review_state = 'published')
+ return self.results
+
+ def getNumberOfEntries(self):
+ """simple counter method for lazy entries"""
+ return len(self.getLazyEntries())
+
+ def __str__(self):
+ """String representation of the Topic"""
+ return self.period[0]
+
+ def __len__(self):
+ """Return the number of posts in this topic.
+ """
+ # Make sure we've got the results
+ self.getLazyEntries()
+ return len(self.results)
+
+ def getLastModified(self):
+ """See ITopic.
+ """
+ # Make sure we've got the results for this topic
+ self.getLazyEntries()
+ if self.results:
+ return self.results[0].modified
+ else:
+ # Just to be explicit about it
+ return None
+
+
+InitializeClass(Archive)
Modified: Quills/branches/maurits-traversal/configure.zcml
==============================================================================
--- Quills/branches/maurits-traversal/configure.zcml (original)
+++ Quills/branches/maurits-traversal/configure.zcml Fri Nov 10 21:47:27 2006
@@ -6,6 +6,7 @@
<five:traversable class=".WeblogEntry.WeblogEntry" />
<five:traversable class=".WeblogArchive.WeblogArchive" />
<five:traversable class=".topic.Topic" />
+ <five:traversable class=".archive.Archive" />
<include file="trackback.zcml" />
<include file="syndication.zcml" />
@@ -22,6 +23,7 @@
<five:defaultViewable class=".topic.Topic" />
+ <five:defaultViewable class=".archive.Archive" />
<browser:page
for=".interfaces.IWeblog"
@@ -42,6 +44,12 @@
permission="zope2.View"
name="index.html" />
+ <browser:page
+ for=".interfaces.IWeblogArchive"
+ template="skins/Quills/weblogarchive_view.pt"
+ permission="zope2.View"
+ name="index.html" />
+
<browser:defaultView
for=".interfaces.ITopic"
name="index.html" />
Modified: Quills/branches/maurits-traversal/interfaces.py
==============================================================================
--- Quills/branches/maurits-traversal/interfaces.py (original)
+++ Quills/branches/maurits-traversal/interfaces.py Fri Nov 10 21:47:27 2006
@@ -86,3 +86,7 @@
class IAuthorsTopic(ITopic):
"""Represents a topic that queries based on authors (aka 'Creators').
"""
+
+class IWeblogArchive(Interface):
+ """An archive folder for a weblog.
+ """
Modified: Quills/branches/maurits-traversal/skins/Quills/weblog_view.pt
==============================================================================
--- Quills/branches/maurits-traversal/skins/Quills/weblog_view.pt (original)
+++ Quills/branches/maurits-traversal/skins/Quills/weblog_view.pt Fri Nov 10 21:47:27 2006
@@ -4,8 +4,8 @@
metal:use-macro="here/main_template/macros/master"
i18n:domain="quills">
+<!-- tal:define="dummy python:request.RESPONSE.setHeader('Last-Modified', here.getModifiedDate().toZone('GMT').rfc822());" -->
<metal:block fill-slot="head_slot"
- tal:define="dummy python:request.RESPONSE.setHeader('Last-Modified', here.getModifiedDate().toZone('GMT').rfc822());"
>
<metal:macro use-macro="here/quills_header_macros/macros/feed-links" />
</metal:block>
@@ -39,10 +39,10 @@
<i tal:content="here/UID"/>
</p>
- <div id="content-weblog">
- <metal:macro
- use-macro="context/weblog_macros/macros/list-entries"/>
- </div>
+<!-- <div id="content-weblog"> -->
+<!-- <metal:macro -->
+<!-- use-macro="context/weblog_macros/macros/list-entries"/> -->
+<!-- </div> -->
</div>
</body>
Modified: Quills/branches/maurits-traversal/skins/Quills/weblogarchive_view.pt
==============================================================================
--- Quills/branches/maurits-traversal/skins/Quills/weblogarchive_view.pt (original)
+++ Quills/branches/maurits-traversal/skins/Quills/weblogarchive_view.pt Fri Nov 10 21:47:27 2006
@@ -5,8 +5,8 @@
xmlns:tal="http://xml.zope.org/namespaces/tal"
i18n:domain="quills">
+<!-- tal:define="dummy python:request.RESPONSE.setHeader('Last-Modified', here.getModifiedDate().toZone('GMT').rfc822());" -->
<metal:block fill-slot="head_slot"
- tal:define="dummy python:request.RESPONSE.setHeader('Last-Modified', here.getModifiedDate().toZone('GMT').rfc822());"
>
<metal:macro use-macro="here/quills_header_macros/macros/feed-links" />
</metal:block>
Modified: Quills/branches/maurits-traversal/traversal.py
==============================================================================
--- Quills/branches/maurits-traversal/traversal.py (original)
+++ Quills/branches/maurits-traversal/traversal.py Fri Nov 10 21:47:27 2006
@@ -10,25 +10,23 @@
# Product imports
from topic import Topic, AuthorsTopic
-
+from WeblogEntry import WeblogEntry
+from archive import Archive
class SubpathTraverser(Traverser):
def traverse(self, path, default=_marker, request=None):
- clear_name_stack = False
- # path looks like ['topics'], or similar...
- if path[0] in ['topics', 'authors']:
- clear_name_stack = True
- path = path + request['TraversalRequestNameStack']
+ path = path + request['TraversalRequestNameStack']
obj = super(SubpathTraverser, self).traverse(path, default, request)
- if clear_name_stack:
- request['TraversalRequestNameStack'][:] = []
+ request['TraversalRequestNameStack'][:] = []
return obj
class WeblogTraversable(FiveTraversable):
"""Intercepts traversal for IWeblogs, but only for 'topics'.
Everything else is left untouched.
+
+ On second thought: also touch everything else. ;-)
"""
def traverse(self, name, furtherPath):
@@ -39,6 +37,11 @@
topic_class = Topic
elif name == 'authors':
topic_class = AuthorsTopic
+ elif isArchiveFolder(name):
+ topic_class = Archive
+ if name != 'archive':
+ furtherPath = [name] + furtherPath
+ name = 'archive'
else:
# We ignore it and do default traversing.
return super(WeblogTraversable, self).traverse(name, furtherPath)
@@ -48,10 +51,10 @@
# Find the REQUEST
REQUEST = getattr(self.context, 'REQUEST', None)
view_name = name
- if len(subpath) == 0:
+ if len(subpath) == 0 and not isArchiveFolder(name):
# No subpath to eat, so just lookup the 'name' view for context
return zapi.getView(self.context, view_name, REQUEST)
- elif subpath[-1].startswith('@@'):
+ elif len(subpath) > 0 and subpath[-1].startswith('@@'):
# A view has explicitly been requested, so make that the
# view_name (stripping off the leading @@ which causes view
# lookups to fail otherwise).
@@ -74,3 +77,26 @@
while furtherPath:
furtherPath.pop()
return subpath
+
+def isArchiveFolder(name):
+ """Test is 'name' is an archive folder.
+
+ This is True when:
+ - name == 'archive'
+ - name is a year
+ """
+ if name == 'archive':
+ return True
+ try:
+ year = int(name)
+ except ValueError:
+ return False
+ else:
+ from DateTime import DateTime
+ try:
+ tryDate = DateTime(year,1,1)
+ except:
+ # Bad year
+ return False
+ else:
+ return True
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Collective-checkins mailing list
Collective-checkins at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/collective-checkins
- Previous message: [quills-dev] [Collective-checkins] r33379 - Quills/branches/maurits-traversal
- Next message: [quills-dev] [Collective-checkins] r33381 - Quills/branches/maurits-traversal
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the quills-dev mailing list