[Python-checkins] r60862 - in tracker/instances/jobs: detectors/sendmail.py detectors/statusauditor.py html/offer.item.html html/page.html schema.py

martin.v.loewis python-checkins at python.org
Sat Feb 16 19:05:17 CET 2008


Author: martin.v.loewis
Date: Sat Feb 16 19:05:17 2008
New Revision: 60862
Modified:
 tracker/instances/jobs/detectors/sendmail.py
 tracker/instances/jobs/detectors/statusauditor.py
 tracker/instances/jobs/html/offer.item.html
 tracker/instances/jobs/html/page.html
 tracker/instances/jobs/schema.py
Log:
Implement all known requirements.
Modified: tracker/instances/jobs/detectors/sendmail.py
==============================================================================
--- tracker/instances/jobs/detectors/sendmail.py	(original)
+++ tracker/instances/jobs/detectors/sendmail.py	Sat Feb 16 19:05:17 2008
@@ -186,5 +186,6 @@
 
 
 def init(db):
+ return
 db.offer.react('set', sendmail)
 db.offer.react('create', sendmail)
Modified: tracker/instances/jobs/detectors/statusauditor.py
==============================================================================
--- tracker/instances/jobs/detectors/statusauditor.py	(original)
+++ tracker/instances/jobs/detectors/statusauditor.py	Sat Feb 16 19:05:17 2008
@@ -1,95 +1,75 @@
+import os, roundup.date
+
 def init_status(db, cl, nodeid, newvalues):
 """ Make sure the status is set on new offers"""
 
 if newvalues.has_key('status') and newvalues['status']:
+ if newvalues['status'] == posted:
+ raise ValueError, "You can only set the offer to submitted, not posted"
 return
 
 new_id = db.status.lookup('submitted')
 newvalues['status'] = new_id
 
 
-def block_resolution(db, cl, nodeid, newvalues):
- """ If the offer has blockers, don't allow it to be resolved."""
-
- if nodeid is None:
- dependencies = []
- else:
- dependencies = cl.get(nodeid, 'dependencies')
- dependencies = newvalues.get('dependencies', dependencies)
-
- # don't do anything if there's no blockers or the status hasn't
- # changed
- if not dependencies or not newvalues.has_key('status'):
+def audit_status(db, cl, nodeid, newvalues):
+ "Prevent regular users from posting their offers themselves."
+ user = db.getuid()
+ if newvalues.get('status') != posted:
 return
-
- # format the info
- u = db.config.TRACKER_WEB
- s = ', '.join(['<a href="%soffer%s">%s</a>'%(u,id,id) for id in dependencies])
- if len(dependencies) == 1:
- s = 'offer %s is'%s
+ if db.user.get(user, 'roles').lower().find('editor') != -1:
+ # Ok if an editor posted it; set the posting date
+ newvalues['posted'] = roundup.date.Date()
 else:
- s = 'offers %s are'%s
-
- # ok, see if we're trying to resolve
- if newvalues.get('status') and newvalues['status'] == db.status.lookup('closed'):
- raise ValueError, "This offer can't be closed until %s closed."%s
-
-
-def resolve(db, cl, nodeid, newvalues):
- """Make sure status, resolution, and superseder values match."""
-
- status_change = newvalues.get('status')
- status_close = status_change and newvalues['status'] == db.status.lookup('closed')
-
- # Make sure resolution and superseder get only set when status->close
- if not status_change or not status_close:
- if newvalues.get('resolution') or newvalues.get('superseder'):
- raise ValueError, "resolution and superseder must only be set when a offer is closed"
-
- # Make sure resolution is set when status->close
- if status_close:
- if not newvalues.get('resolution'):
- raise ValueError, "resolution must be set when a offer is closed"
-
- # Make sure superseder is set when resolution->duplicate
- if newvalues['resolution'] == db.resolution.lookup('duplicate'):
- if not newvalues.get('superseder'):
- raise ValueError, "please provide a superseder when closing a offer as 'duplicate'"
-
-
-
-def resolve_dependencies(db, cl, nodeid, oldvalues):
- """ When we resolve an offer that's a blocker, remove it from the
- blockers list of the offer(s) it blocks."""
-
- newstatus = cl.get(nodeid,'status')
-
- # no change?
- if oldvalues.get('status', None) == newstatus:
- return
-
- closed_id = db.status.lookup('closed')
-
- # interesting?
- if newstatus != closed_id:
- return
+ # reject posts attempted by mere users
+ raise ValueError, "You must not set the status to 'posted'."
 
- # yes - find all the dependend offers, if any, and remove me from
- # their dependency list
- offers = cl.find(dependencies=nodeid)
- for offerid in offers:
- dependencies = cl.get(offerid, 'dependencies')
- if nodeid in dependencies:
- dependencies.remove(nodeid)
- cl.set(offerid, dependencies=dependencies)
+def inner_generate(db, cl):
+ filename = os.path.join(db.config.HOME,
+ db.config.options['TEMPLATES'].get(),
+ "posted.txt")
+ f = open(filename, "w")
+ for offer in cl.filter(None, {'status':posted},
+ sort=[('-','posted')]):
+ offer = cl.getnode(offer)
+ head = ""
+ if offer.organization_url:
+ head += "`"
+ head += offer.organization
+ if offer.organization_url:
+ head += "`__"
+ if offer.agency:
+ head += " [AGENCY]"
+ head += " (%s)" % offer.location
+ print >>f, head
+ print >>f, "="*len(head)
+ print >>f
+ print >>f, "*Posted: %s*" % offer.posted.pretty()
+ print >>f
+ if offer.description:
+ print >>f, "**Job Description**:", db.msg.get(offer.description,
+ 'content')
+ print >>f
+ if offer.python_used_for:
+ print >>f, "**What Python is used for**:", \
+ db.msg.get(offer.python_used_for, 'content')
+ print >>f
+ print >>f, '----------'
+ print >>f
+ 
+ f.close()
+
+def generate(db, cl, nodeid, oldvalues):
+ if cl.get(nodeid, 'status') == posted:
+ inner_generate(db,cl)
 
 
 def init(db):
+ global posted
+ posted = db.status.lookup('posted')
 # fire before changes are made
 db.offer.audit('create', init_status)
-# db.offer.audit('create', block_resolution)
-# db.offer.audit('set', block_resolution)
-# db.offer.audit('set', resolve)
+ db.offer.audit('set', audit_status)
 
 # adjust after changes are committed
-# db.offer.react('set', resolve_dependencies)
+ db.offer.react('set', generate)
Modified: tracker/instances/jobs/html/offer.item.html
==============================================================================
--- tracker/instances/jobs/html/offer.item.html	(original)
+++ tracker/instances/jobs/html/offer.item.html	Sat Feb 16 19:05:17 2008
@@ -40,14 +40,13 @@
 <input type="hidden" name="@template" value="item"/>
 <input type="hidden" name="@required" value="title,organization"/>
 <fieldset><legend>Posted content</legend>
-<span tal:replace="structure context/submit">submit button</span>
 <table class="form">
 
 <tr>
 <th class="required" i18n:translate="">Title:</th>
- <td tal:condition="context/is_edit_ok"
+ <td tal:condition="context/title/is_edit_ok"
 tal:content="structure python:context.title.field(size=60)">Title</td>
- <td tal:condition="not:context/is_edit_ok">
+ <td tal:condition="not:context/title/is_edit_ok">
 <span tal:content="structure context/title/plain"/>
 <input type="hidden" name="title" tal:attributes="value context/title">
 </td>
@@ -55,9 +54,9 @@
 
 <tr>
 <th>Company</th>
- <td tal:condition="context/is_edit_ok"
+ <td tal:condition="context/organization/is_edit_ok"
 tal:content="structure python:context.organization.field(size=60)"></td>
- <td tal:condition="not:context/is_edit_ok">
+ <td tal:condition="not:context/organization/is_edit_ok">
 <span tal:content="structure context/organization/plain"/>
 <input type="hidden" name="title" tal:attributes="value context/organization">
 </td>
@@ -65,33 +64,57 @@
 
 <tr>
 <th>Company URL (optional)</th>
- <td tal:condition="context/is_edit_ok"
+ <td tal:condition="context/organization_url/is_edit_ok"
 tal:content="structure python:context.organization_url.field(size=60)">OK</td>
- <td tal:condition="not:context/is_edit_ok">
- <span tal:content="structure context/organization/plain"/>
+ <td tal:condition="not:context/organization_url/is_edit_ok">
+ <span tal:content="structure context/organization_url/plain"/>
 <input type="hidden" name="title" tal:attributes="value context/organization_url">
 </td>
 </tr>
 
-<tr tal:condition="context/is_edit_ok">
+<tr>
+ <th>We are a job agency</th>
+ <td tal:condition="context/agency/is_edit_ok"
+ tal:content="structure context/agency/field">OK</td>
+ <td tal:condition="not:context/agency/is_edit_ok">
+ <span tal:content="structure context/agency/plain"/>
+ <input type="hidden" name="title" tal:attributes="value context/agency">
+ </td>
+</tr>
+
+<tr>
+ <th>Job Location</th>
+ <td tal:condition="context/location/is_edit_ok"
+ tal:content="structure python:context.location.field(size=60)">OK</td>
+ <td tal:condition="not:context/location/is_edit_ok">
+ <span tal:content="structure context/location/plain"/>
+ <input type="hidden" name="title" tal:attributes="value context/location">
+ </td>
+</tr>
+
+<tr tal:define="curval python:context.description and context.description.content">
 <th><tal:block i18n:translate="">Description</tal:block>:</th>
- <td tal:define="curval python:context.description and context.description.content">
+ <td tal:condition="context/description/is_edit_ok">
 <input type="hidden" name="@link at description" value="msg-1">
 <textarea tal:content="request/form/msg-1 at content/value | curval"
 name="msg-1 at content" rows="10" cols="72"></textarea>
 </td>
+ <td tal:condition="not:context/description/is_edit_ok" tal:content="curval"/>
 </tr>
 
-<tr tal:condition="context/is_edit_ok">
+<tr tal:define="curval python:context.python_used_for and context.python_used_for.content">
 <th><tal:block i18n:translate="">What Python is used for</tal:block>:</th>
- <td tal:define="curval python:context.python_used_for and context.python_used_for.content">
+ <td tal:condition="context/description/is_edit_ok">
 <input type="hidden" name="@link at python_used_for" value="msg-2">
 <textarea tal:content="request/form/msg-2 at content/value | curval"
 name="msg-2 at content" cols="72"></textarea>
 </td>
+ <td tal:condition="not:context/python_used_for/is_edit_ok"
+ tal:content="curval"/>
 </tr>
-
 </table>
+<span tal:condition="context/title/is_edit_ok"
+ tal:replace="structure context/submit">submit button</span>
 </fieldset>
 </form>
 
Modified: tracker/instances/jobs/html/page.html
==============================================================================
--- tracker/instances/jobs/html/page.html	(original)
+++ tracker/instances/jobs/html/page.html	Sat Feb 16 19:05:17 2008
@@ -201,6 +201,8 @@
 <div id="body-main">
 <div id="content">
 <div id="breadcrumb"><span metal:define-slot="body_title">body title</span></div>
+<h1 style="color:red">This is a demo installation. Do not use it for real jobs.</h1>
+
 <p tal:condition="options/error_message | nothing" class="error-message"
 tal:repeat="m options/error_message" tal:content="structure m" />
 <p tal:condition="options/ok_message | nothing" class="ok-message">
Modified: tracker/instances/jobs/schema.py
==============================================================================
--- tracker/instances/jobs/schema.py	(original)
+++ tracker/instances/jobs/schema.py	Sat Feb 16 19:05:17 2008
@@ -67,10 +67,12 @@
 offer = IssueClass(db, "offer",
 organization=String(),
 organization_url=String(),
+ location=String(),
 agency=Boolean(),
 description=Link('msg'),
 python_used_for=Link('msg'),
 status=Link('status'),
+ posted=Date()
 )
 
 #
@@ -167,12 +169,29 @@
 description='User can report and discuss offers')
 db.security.addPermissionToRole('User', p)
 
+# Users may edit their offers before they get posted
+def edit_unposted(db, userid, itemid):
+ status = db.offer.get(itemid, 'status')
+ status = db.status.get(status, 'name')
+ if status == 'posted':
+ return False
+ return own_offer(db, userid, itemid)
+
 p = db.security.addPermission(name='Edit', klass='offer',
 properties=('title','organization',
 'organization_url', 'agency',
 'description', 'python_used_for',
- 'messages', 'files', 'nosy'),
- description='User can add and discuss offers')
+ 'messages', 'files'),
+ description='User can edit unposted offers',
+ check=edit_unposted)
+db.security.addPermissionToRole('User', p)
+
+# Users can edit the status always (e.g. to withdraw an issue);
+# an auditor will make sure they don't change it to "posted".
+p = db.security.addPermission(name='Edit', klass='offer',
+ properties=('status','nosy'),
+ description='User can change the status of their offers',
+ check=own_offer)
 db.security.addPermissionToRole('User', p)
 
 db.security.addPermissionToRole('User', 'SB: May Report Misclassified')
@@ -278,7 +297,7 @@
 # Note permissions settings for file and msg above (due to spambayes
 # integration).
 
-for cl in 'offer', 'status':
+for cl in 'status',:
 db.security.addPermissionToRole('Anonymous', 'View', cl)
 
 # Allow users to see the realname


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /