Scheduled event notification for Plone
by
antonh
—
last modified
07-Sep-06 11:48 AM
One of the great things about open source communities is that you rarely have to reinvent the wheel. I want to add a feature to a Plone site which automatically emails certain people 6 weeks before an event starts (stored in an Event portal type). To this end there are a number of resources already available. All I have to do is assemble them...
Perhaps the simplest method is to use Cron to trigger a Zope URL which
kicks off the script. Here is an example for packing the Zope database
thanks to phd:
#! /usr/local/bin/python -O
username="superuser"
password="PASSWORD" # this is only example, of course
zope="http://my.site/Zope"
import sys, urllib
class NoGUI_URLopener(urllib.FancyURLopener):
def __init__(self, username, password, *args):
apply(urllib.FancyURLopener.__init__, (self,) + args)
self.username = username
self.password = password
self.asked = 0
def prompt_user_passwd(self, host, realm):
if self.asked:
raise "Unauthorised"
else:
self.asked = 1
return self.username, self.password
try:
days = sys.argv[1]
except:
days = 7
urllib._urlopener = NoGUI_URLopener(username, password)
urllib.urlretrieve("%s/Control_Panel/Database/manage_pack?days:float=%s" % (zope, days))
Of course, you might not be that keen to store your admin account's
details in a plain text file on your server. But it certainly sets out
the right idea.
There is also Xron - the in-Zope equivalent of Cron.
Another improvement over the above script is to use PloneMaintenance
in conjunction with Cron or Xron - PloneMaintenance will handle
the sequential execution of a number of maintenance tasks. Have a look
at the README for some great advice...
Sending an email before event
There is a
script on ZopeLabs
which sends an email on expiry of all elements in the catalog. So with
a little bit of modification, this should do the trick as well. For
completeness, I'm including it here:
from DateTime import DateTime
for r in context.portal_catalog():
date1 = r.expires #the expiration date
date2 = context.ZopeTime() #the current date
t = int(date1.earliestTime()-date2.earliestTime()) #the integer difference between dates
print t
if t==14: #if there is 14 days between dates...
contentObject = r.getObject() #get object via catalog
objectHistory=contentObject.portal_workflow.getInfoFor(contentObject, 'review_history')
thisRevision=objectHistory[-1]
nowDate=thisRevision['time'].aCommon()
authorComment=thisRevision['comments']
mailList=[]
try:
mailhost=getattr(context, context.portal_url.superValues('Mail Host')[0].id)
except:
raise AttributeError, "Cannot find a Mail Host object"
mMsg = 'An item you created on the website is nearing expiry.\n\nPlease update the item.\n\nThis email was generated and sent by the COMESA website.\n\n'
mMsg += 'Title: ' + contentObject.TitleOrId() + '\n\n'
mMsg += 'Description: ' + contentObject.Description() + '\n\n'
mMsg += contentObject.absolute_url() + '\n'
#mMsg += 'Author: ' + contentObject.Creator()
mMsg += 'Author comment:' + authorComment + '\n\n'
mTo = context.portal_membership.getMemberById(contentObject.Creator()).email
mFrom = 'Webmaster@comesa.int'
mSubj = 'Website item nearing expiration date'
mailhost.send(mMsg, mTo, mFrom, mSubj) #send email to author
elif t==0: #else if expiration date=today's date
contentObject = r.getObject() #get object via catalog
try: #change review_state to expired
context.portal_workflow.doActionFor(contentObject, 'expire')
except:
print 'didnt change state' #this is here just in case
return printed
Cool!
#! /usr/bin/python -O
zope="http://myhost/notifyExpiredDocuments?__ac_name=admin&__ac_password=PASS"
import sys, urllib
urllib.urlretrieve(url=zope)