[Zope3-checkins] CVS: Zope3/src/zope/app/demo/jobboard - __init__.py:1.1 browser.py:1.1 browser_views.png:1.1 configure.zcml:1.1 edit.pt:1.1 interfaces.py:1.1 job.py:1.1 joblist.gif:1.1 joblist.png:1.1 joblistview.pt:1.1 jobview.pt:1.1 preview.pt:1.1 review.pt:1.1 tests.py:1.1 thanks.pt:1.1

Nathan Yergler nathan at yergler.net
Thu Mar 11 08:07:12 EST 2004


Update of /cvs-repository/Zope3/src/zope/app/demo/jobboard
In directory cvs.zope.org:/tmp/cvs-serv8707/jobboard

Added Files:
	__init__.py browser.py browser_views.png configure.zcml 
	edit.pt interfaces.py job.py joblist.gif joblist.png 
	joblistview.pt jobview.pt preview.pt review.pt tests.py 
	thanks.pt 
Log Message:
Moving jobboard demo from Products3/demo/jobboard.


=== Added File Zope3/src/zope/app/demo/jobboard/__init__.py ===


=== Added File Zope3/src/zope/app/demo/jobboard/browser.py ===
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserView
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent, ObjectModifiedEvent


from job import Job

class JobCreateView(BrowserView):
    """ class to create job entries

    >>> from job import JobList
    >>> from zope.publisher.browser import TestRequest
    >>> from zope.app.tests.placelesssetup import setUp, tearDown
    >>> setUp()
    >>> class TestJobList:
    ...    context = None
    ...    def add(self, myObj):
    ...         self.tempStorage = myObj

    >>> 
    >>> request = TestRequest()
    >>> joblist = TestJobList()
    >>> view = JobCreateView(joblist, request)
    >>> myThanksPage = view.create(submitter='sree', summary='my job summary',
    ...                  description='my desc', contact = 'sree')
    >>> joblist.tempStorage.summary
    'my job summary'
    >>> tearDown()
    """
    edit = ViewPageTemplateFile('edit.pt')

    preview = ViewPageTemplateFile('preview.pt')

    thanks = ViewPageTemplateFile('thanks.pt')

    def create(self, submitter='', summary='', description='', contact=''):
        # Validation code should go here
        job = Job(submitter, summary, description, contact)
        self.context.add(job)
        publish(self.context,ObjectModifiedEvent(self.context))
        return self.thanks()
        
        
################################

class ApproveJobsView(BrowserView):
    """ class to Approve existing job entries

    >>> from job import JobList
    >>> from zope.publisher.browser import TestRequest
    >>> from zope.app.tests.placelesssetup import setUp, tearDown
    >>> setUp()
    >>> 
    >>> request = TestRequest(form={'1':'approve','2':'discard'})
    >>> class TestJobList:
    ...    context = None
    ...    tempStorage = []
    ...    def add(self, myObj):
    ...         self.tempStorage.append( myObj)

    >>> joblist = JobList()

    >>> view = JobCreateView(joblist, request)
    >>> myThanksPage = view.create(submitter='sree', summary='my job summary',
    ...                  description='my desc', contact = 'sree')
    >>> myThanksPage = view.create(submitter='sree2', summary='my summaryy2',
    ...                  description='my desc2', contact = 'sree2')
    >>> approvedview = ApproveJobsView(joblist, request)
    >>> approvedview.approve()
    >>> request.response.getHeader('location')
    '.'
    >>> joblist['1'].state
    'approved'
    >>> joblist['2'].state
    Traceback (most recent call last):
    ...
    KeyError: 2
    >>> tearDown()
    """
    review = ViewPageTemplateFile('review.pt')

    def approve(self):
        form = self.request.form

        for jobid in form:
            try:
               job = self.context[jobid]
            except:
               pass

            action = form[jobid]
            if action == 'approve':
                job.approve()
            elif action == 'discard':
                del self.context[jobid]

        response = self.request.response
        if self.context.getPendingIds():
            response.redirect('review.html')
        else:
            response.redirect('.')
        publish(self.context,ObjectModifiedEvent(self.context))



=== Added File Zope3/src/zope/app/demo/jobboard/browser_views.png ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/demo/jobboard/configure.zcml ===
<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:browser="http://namespaces.zope.org/browser"
    xmlns:i18n="http://namespaces.zope.org/i18n"
    i18n_domain="jobboardi18n"
    >

<content class="zopeproducts.demo.jobboard.job.JobList">
  <implements interface="zope.app.interfaces.annotation.IAttributeAnnotatable"
  />
  <factory
      id="zopeproducts.demo.jobboard.job.JobList"
      title="I18n Job List"
      />
  <allow interface=".interfaces.IJobList" />
  <implements interface="zope.app.container.interfaces.IItemContainer" />
</content>

<browser:addMenuItem
    title="I18N Job Board"
    description="Internationalized board for posting and searching jobs."
    class="zopeproducts.demo.jobboard.job.JobList"
    permission="zope.ManageContent"
    />

<content class=".job.Job">
  <allow interface="zopeproducts.demo.jobboard.interfaces.IJob" />
</content>

<browser:page
    name="index.html"
    for="zopeproducts.demo.jobboard.interfaces.IJobList"
    template="joblistview.pt"
    permission="zope.View"
    />

<browser:pages
    for="zopeproducts.demo.jobboard.interfaces.IJobList"
    class=".browser.JobCreateView"
    permission="zope.View"
    >

  <browser:page name="edit.html"     attribute="edit" />
  <browser:page name="preview.html"  attribute="preview" />
  <browser:page name="create.method" attribute="create" />
</browser:pages>

<browser:page
    name="index.html"
    for="zopeproducts.demo.jobboard.interfaces.IJob"
    template="jobview.pt"
    permission="zope.View"
    />

<browser:pages
    for="zopeproducts.demo.jobboard.job.IJobList"
    class=".browser.ApproveJobsView"
    permission="zope.ManageContent"
    >

  <browser:page name="review.html"    attribute="review" />
  <browser:page name="approve.method" attribute="approve" />
</browser:pages>

<browser:icon
    name="zmi_icon"
    for="zopeproducts.demo.jobboard.interfaces.IJobList"
    file="./joblist.gif"
    />

<i18n:registerTranslations directory="./locale" />

</configure>


=== Added File Zope3/src/zope/app/demo/jobboard/edit.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="enter-new-job-data">Enter new job data</title>
</head>
<body>
<h1 i18n:translate="enter-new-job-data">Enter new job data</h1>

<p i18n:translate="when-done">When you are done, press the Preview
button below.</p>

    <form action="preview.html" method="post">
    <table border=0>
    <tr><td i18n:translate="contributor-email">Contributor email:</td>
	<td><input name="submitter" value="" size="60"
	     tal:attributes="value request/submitter|nothing" />
	</td>
    </tr>
    <tr><td i18n:translate="one-line-summary">One-line summary:</td>
	<td><input name="summary" value="" size="60"
	     tal:attributes="value request/summary|nothing" />
	</td>
    </tr>
    <tr><td i18n:translate="full-description">Full description (no HTML):</td>
	<td><textarea name="description" cols=60 rows=10 wrap="hard"
	    ><span tal:replace="request/description|nothing">Description</span>
	    </textarea>
	</td>
    </tr>
    <tr><td i18n:translate="contact">Contact (where to apply):</td>
	<td><input name="contact" value="" size="60"
	     tal:attributes="value request/contact|nothing" />
	</td>
    </tr>
    <tr><td i18n:translate="salary">Salary Range:</td>
	<td><input name="salary" value="" size="60"
	     tal:attributes="value request/salary|nothing" />
	</td>
    </tr>
    <tr>
	<td><span i18n:translate="startdate">Start Date</span><br>
	(<span tal:replace="python:request.locale.dates.getFormatter('date', 'short').getPattern()" />)</td>
	<td><input name="startdate" value="" size="60"
	     tal:attributes="value request/startdate|nothing" />
	</td>
    </tr>
    <tr><td colspan="2">
	<input type="submit" value="Preview" i18n:attributes="value=Preview">
	</td>
    </tr>
    </table>
    </form>

</body>
</html>


=== Added File Zope3/src/zope/app/demo/jobboard/interfaces.py ===
from zope.interface import Interface
from zope.interface import Attribute

class IJob(Interface):
    """Interface for the basic Job"""

    submitter = Attribute("submitter",
                          "Email address of the submitter")

    summary = Attribute("summary",
                        "One-line summary of the job")

    description = Attribute("description",
                            "Longer description of the job")

    contact = Attribute("contact",
                        "Email address to contact about the job")

    state = Attribute("state",
                      "Current state of the job listing.\n"
                      "The possible values are defined in JobState.")    

    salary = Attribute("salary",
                       "Salary range offered for the job.")

    startdate = Attribute("startdate",
                          "Job start date")

    def approve():
        "Moves the job state to Approved"


class JobState:
    """Possible values of IJob.state."""
    PendingApproval = "pending approval"
    Approved = "approved"
    
    
##############################################################
#
#
#
#
##############################################################

class IJobList(Interface):

    def __getitem__(jobid):
        """Returns the job with the given jobid"""

    def query(state):
        """Returns a list of Job ids"""

    def getApprovedIds():
        """Returns a sequence of ids for job that are in the approved state
        """

    def getPendingIds():
        """Returns a sequence of ids for jobs that are in the pending state
        """

    def add(job):
        """Add a Job object to the list.

        Returns the id assigned to the job.
        """

    def __delitem__(jobid):
        """Removes the Job object with the given id from the list.

        Raises KeyError if the jobid is not in the list.
        """


=== Added File Zope3/src/zope/app/demo/jobboard/job.py ===
"""
Job.py
"""


from persistence import Persistent
from interfaces import IJob, JobState, IJobList
from zope.interface import implements


class Job(Persistent):
    """ Job Class

    >>> myJob = Job(submitter='my name', summary='my summary',
    ...             description='my description',contact='my contact',
    ...             salary='111', startdate='10/01/2003')
    >>> myJob.summary
    'my summary'
    >>> myJob.state
    'pending approval'
    >>> myJob.approve()
    >>> myJob.state
    'approved'
    """
    
    implements(IJob)
   
        
    def __init__(self, submitter, summary, description,
                 contact, salary=None, startdate=None):
        self.submitter = submitter
        self.summary = summary
        self.description = description
        self.contact = contact
        self.state = JobState.PendingApproval
        self.salary = salary
        self.startdate = startdate

    def approve(self):
        """Moves the job state to approved"""
        self.state = JobState.Approved



##########################################################################



from persistence.dict import PersistentDict
from zope.app.event import publish
from zope.app.event.objectevent import ObjectCreatedEvent

class JobList(Persistent):
    """ the Joblist class manages the creation, deletion of job list and
    can display the object ids which are in specific states

    >>> from job import Job
    >>> joblist = JobList()
    >>> myJob1 = Job(submitter='my name', summary='my summary',
    ...             description='my description',contact='my contact',
    ...             salary='111', startdate='10/01/2003')
    >>> myJob2 = Job(submitter='my name2', summary='my summary2',
    ...             description='my description2',contact='my contact2',
    ...             salary='222', startdate='20/12/2003')

    >>> joblist.add(myJob1)
    '1'
    >>> joblist.add(myJob2)
    '2'
    >>> joblist.getPendingIds()
    ['1', '2']
    >>> joblist.query('pending approval')
    ['1', '2']
    >>> myJob1.approve()
    >>> joblist.getPendingIds()
    ['2']
    >>> joblist.getApprovedIds()
    ['1']
    """
    implements(IJobList)


    def __init__(self):
        self._lastid = 0
        self._jobs = PersistentDict()

    def add(self, job):
        self._lastid += 1
        jobid = self._lastid
        self._jobs[jobid] = job
        # stringified for parity with query
        # this can return an int when query can also return an int
        return str(jobid)

    def __delitem__(self, jobid):
        # accept stringified job ids, see add()
        try:
            jobid = int(jobid)
        except ValueError:
            raise KeyError, jobid
        del self._jobs[jobid]

    def query(self, state):
        ids = [jobid
               for jobid, job in self._jobs.items()
               if job.state == state]
        ids.sort()
        # this should work returning a list of ints,
        # but it exposes a bug in PageTemplates
        return map(str, ids)

    def __getitem__(self, jobid):
        # accept stringified job ids, see add()
        try:
            jobid = int(jobid)
        except ValueError:
            raise KeyError, jobid
        return self._jobs[jobid]

    def getPendingIds(self):
        return self.query(JobState.PendingApproval)
        
        
    def allIds(self):
        return  self._jobs.items()
        #ids.sort()
        # this should work returning a list of ints,
        # but it exposes a bug in PageTemplates
        #return map(str, ids)

    def getApprovedIds(self):
        return self.query(JobState.Approved)


=== Added File Zope3/src/zope/app/demo/jobboard/joblist.gif ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/demo/jobboard/joblist.png ===
  <Binary-ish file>

=== Added File Zope3/src/zope/app/demo/jobboard/joblistview.pt ===
<HTML i18n:domain="jobboard">
<HEAD>
<TITLE i18n:translate="job-board-title">Job Board</TITLE>
</HEAD>
<BODY>
<h1 i18n:translate="job-board-title">Job Board</h1>

<A href="edit.html" i18n:translate="submit-new-job">Submit a new job</A>

<H2 i18n:translate="job-listings">Job Listings</H2>

<table>

<tr tal:repeat="jobid context/getApprovedIds">
    <td>
    <a href="jobid" tal:attributes="href jobid">
    <span tal:replace="context/?jobid/summary">A job summary</span></A>
    </td>
</tr>
</table>

<!-- XXX this should only appear if the user has the proper permissions -->
<h2 i18n:translate="other-operations">Other operations</h2>
<a href="review.html"
   i18n:translate="approve-submitted-jobs">Approve submitted jobs</a>

</BODY>
</HTML>


=== Added File Zope3/src/zope/app/demo/jobboard/jobview.pt ===
<html i18n:domain="jobboard">
<head>
<title tal:content="context/summary">Job summary goes here</title>
</head>
<body>

  <h3 tal:content="context/summary">Job summary goes here</h3>

  <table border=0>
  <tr><td i18n:translate="full-description">Description:</td>
      <td>
      <pre tal:content="context/description">Full descripion goes here
      (multiple lines)
      </pre>
      </td>
  </tr>
  <tr><td i18n:translate="contact">Contact:</td>
      <td><a href="user at host.com"
             tal:attributes="href string:mailto:${context/contact}"
             tal:content="context/contact">user at host.com</a></td>
  </tr>
  <tr><td i18n:translate="salary">Salary Range:</td>
      <td tal:content="context/salary"></td>
  </tr>
  <tr><td i18n:translate="startdate">Start date:</td>
      <td><span tal:omit-tag=""  tal:condition="exists: context/startdate" 
tal:content="context/startdate"/></td>
  </tr>

  </table>

  <table border=0>
      <tr><td>
      <a href=".." i18n:translate="back-to-jobs">Back to jobs</a>
      </td></tr>
  </table>

</body>
</html>



=== Added File Zope3/src/zope/app/demo/jobboard/preview.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="preview-new-job-data">Preview new job data</title>
</head>

<body>

<h1 i18n:translate="preview-new-job-data">Preview New Job Data</h1>

<p i18n:translate="instructions">This is what your job will look like
once it is approved by the site manager.  To change your submission
now, use your browser's Back button and resubmit the form.  To submit
now, click on the Submit button below.
</p>

<p i18n:translate="verify">Your contact email address is recorded as
<span i18n:name="email">
<a href="user at host.com"
   tal:attributes="href string:mailto:${request/submitter}"
   tal:content="request/submitter">
   user at host.com</a></span>.
This address will not be published on the website, but we will use it
to reach you if we have questions about your submission.  Job seekers
will contact the address you provide in the Contact field.
</p>

<!-- p tal:condition="view/error"
   tal:content="view/error">Error messages go here</p -->

<hr>

  <h3 tal:content="request/summary">Job summary goes here</h3>

  <table border="0">
  <tr>
      <td>
      <pre tal:content="request/description">Full descripion goes here
      (multiple lines)
      </pre>
      </td>
  <tr><td i18n:translate="">Contact:</td>
      <td><a href="user at host.com"
             tal:attributes="href string:mailto:${request/contact}"
	    tal:content="request/contact">user at host.com</a></td>
  </tr>
    <tr><td i18n:translate="salary">Salary Range:</td>
	<td tal:content="request/salary">
	</td>
    </tr>
    <tr><td i18n:translate="startdate">Start Date:</td>
	<td tal:content="request/startdate">
	</td>
    </tr>

  </table>

<hr>

    <form action="create.method" method="post">

	<input name="submitter" type="hidden" value=""
               tal:attributes="value request/submitter" />
	<input name="summary" type="hidden" value=""
               tal:attributes="value request/summary" />
	<input name="description" type="hidden" value=""
               tal:attributes="value request/description" />
	<input name="contact" type="hidden" value=""
               tal:attributes="value request/contact" />
	<input name="salary" type="hidden" value=""
	       tal:attributes="value request/salary" />
	<input name="startdate" type="hidden" value=""
	       tal:attributes="value request/startdate" />

	<input type="submit" name="submit" value="Submit"
	       i18n:attributes="value Submit"/>
	
	<input type="submit" name="edit" value="Edit"
	       i18n:attributes="value Edit" />

    </form>

</body>
</html>


=== Added File Zope3/src/zope/app/demo/jobboard/review.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="approve-title">Approve submitted jobs</title>
</head>
<body>

<h1 i18n:translate="approve-title">Approve Submitted Jobs</h1>

    <form action="approve.method" method="post">
    <table border=0>
    <tr><th colspan=3 i18n:translate="">Action</th>
        <th rowspan=2 i18n:translate="">Summary</th>
    </tr>
    <tr><th i18n:translate="">Defer</th>
	<th i18n:translate="">Approve</th>
	<th i18n:translate="">Discard</th>
    </tr>
    <tr tal:repeat="jobid context/getPendingIds"
        style="text-align:center">
        <div tal:define="job context/?jobid">
        <td><input type="radio" checked
                   tal:attributes="name jobid"></td>
        <td><input type="radio" value="approve"
                   tal:attributes="name jobid"></td>
        <td><input type="radio" value="discard"
                   tal:attributes="name jobid"></td>
        <td><a href="jobid" tal:attributes="href jobid"
               tal:content="job/summary">A job summary </a>

            (<a href="user at host.com"
                tal:attributes="href string:mailto:${job/submitter}"
             ><span tal:replace="job/submitter">user at host.com</span></a>)

        </td>
        </div>
    </tr>
    <tr><td colspan="3">
        <input type="submit" value="Submit" i18n:attributes="value=Submit">
        <a href="." i18n:translate="back-to-summary">Back to summary</a>
    </td></tr>
    </table>
    </form>

</body>
</html>


=== Added File Zope3/src/zope/app/demo/jobboard/tests.py ===
import unittest, doctest




def test_suite():
    
    return unittest.TestSuite((
        doctest.DocTestSuite('zopeproducts.demo.jobboard.job'),
        doctest.DocTestSuite('zopeproducts.demo.jobboard.browser'),
        ))

if __name__ == '__main__': unittest.main()


=== Added File Zope3/src/zope/app/demo/jobboard/thanks.pt ===
<html i18n:domain="jobboard">
<head>
<title i18n:translate="thank-you-title">Thank you for your job
submission</title>
</head>
<body>
<h1 i18n:translate="thank-you-title">Thank you for your job submission</h1>

<p i18n:translate="thank-you-wherenext">Our site manager will review
and publish it shortly.  Please use one of the following links to
continue to use our site:
</p>

<ul>

<li><a href="/" i18n:translate="back-to-site-home">Back to site home</a>

<p><li><a href="." i18n:translate="back-to-job-board">Back to job board</a>

<p><li><a href="edit.html" i18n:translate="submit-another">Submit
another job</a>

</ul>

</body>
</html>




More information about the Zope3-Checkins mailing list