Index: /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser.py	(revision 5775)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser.py	(revision 5775)
@@ -0,0 +1,222 @@
+##
+## browser.py
+## Login : <uli@pu.smp.net>
+## Started on  Sun Jun 27 11:03:10 2010 Uli Fouquet
+## $Id$
+## 
+## Copyright (C) 2010 Uli Fouquet
+## This program 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.
+## 
+## This program 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 this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""UI components for JAMB tables.
+"""
+import grok
+
+from zope.formlib.widgets import FileWidget
+from waeup.sirp.browser import (
+    WAeUPPage, WAeUPEditFormPage, WAeUPAddFormPage,
+    WAeUPDisplayFormPage, NullValidator)
+from waeup.sirp.browser.pages import LoginPage
+from waeup.sirp.interfaces import IWAeUPObject
+from waeup.sirp.applicants.jambtables.util import get_applicant_data
+from waeup.sirp.applicants.interfaces import (
+    IApplicant, IApplicantPrincipal, IApplicantPDEEditData)
+from waeup.sirp.widgets.passportwidget import (
+    PassportWidget, PassportDisplayWidget
+    )
+#from zope.formlib.objectwidget import ObjectWidget
+from zope.formlib.sequencewidget import ListSequenceWidget, SequenceDisplayWidget
+from zope.formlib.widget import CustomWidgetFactory
+from waeup.sirp.applicants import ResultEntry
+from waeup.sirp.widgets.objectwidget import (
+    WAeUPObjectWidget, WAeUPObjectDisplayWidget)
+from waeup.sirp.widgets.multilistwidget import (
+    MultiListWidget, MultiListDisplayWidget)
+from waeup.sirp.image.browser.widget import (
+    ThumbnailWidget, EncodingImageFileWidget,
+    )
+
+results_widget = CustomWidgetFactory(
+    WAeUPObjectWidget, ResultEntry)
+
+results_display_widget = CustomWidgetFactory(
+    WAeUPObjectDisplayWidget, ResultEntry)
+
+#list_results_widget = CustomWidgetFactory(
+#    ListSequenceWidget, subwidget=results_widget)
+
+list_results_widget = CustomWidgetFactory(
+    MultiListWidget, subwidget=results_widget)
+
+list_results_display_widget = CustomWidgetFactory(
+    MultiListDisplayWidget, subwidget=results_display_widget)
+
+#class ApplicationsPage(WAeUPPage):
+#    grok.context(IApplicantContainer)
+#    grok.name('index')
+#    title = 'Applications'
+#    pnav = 1
+#    
+#    def getApplications(self):
+#        """Get a list of all stored applications.
+#        """
+#        for key, val in self.context.items():
+#            url = self.url(val)
+#            yield(dict(url=url, name=key))
+
+#class AddApplicant(WAeUPAddFormPage):
+#    grok.context(IApplicantContainer)
+#    grok.name('add')
+#    form_fields = grok.AutoFields(IApplicant)
+#    form_fields['fst_sit_results'].custom_widget = list_results_widget
+#    form_fields['passport'].custom_widget = EncodingImageFileWidget
+#    label = 'Add Applicant'
+#    title = 'Add Applicant'
+#    pnav = 1
+#
+#    @grok.action('Add applicant')
+#    def addApplicant(self, **data):
+#        from waeup.sirp.jambtables.applicants import Applicant
+#        applicant = Applicant()
+#        self.applyData(applicant, **data)
+#        # XXX: temporarily disabled.
+#        #self.context[applicant.reg_no] = applicant
+#        try:
+#            self.context[applicant.access_code] = applicant
+#        except KeyError:
+#            self.flash('The given access code is already in use!')
+#            return
+#        self.redirect(self.url(self.context))
+
+class DisplayApplicant(WAeUPDisplayFormPage):
+    grok.context(IApplicant)
+    grok.name('index')
+    form_fields = grok.AutoFields(IApplicant)
+    form_fields['fst_sit_results'].custom_widget = list_results_display_widget
+    #form_fields['passport'].custom_widget = PassportDisplayWidget
+    form_fields['passport'].custom_widget = ThumbnailWidget
+    label = 'Applicant'
+    title = 'Applicant'
+    pnav = 1
+
+class EditApplicant(WAeUPEditFormPage):
+    grok.context(IApplicant)
+    grok.name('edit')
+    form_fields = grok.AutoFields(IApplicantPDEEditData)
+    #form_fields['passport'].custom_widget = FileWidget
+    #form_fields['passport'].custom_widget = PassportWidget
+    form_fields['passport'].custom_widget = EncodingImageFileWidget
+    grok.template('form_edit_pde')
+
+    def update(self):
+        super(EditApplicant, self).update()
+        print self.request.form
+        return
+    
+    @property
+    def label(self):
+        # XXX: Use current/upcoming session
+        return 'Apply for Post UDE Screening Test (2009/2010)'
+    title = 'Edit Application'
+    pnav = 1
+
+    @grok.action('Save')
+    def save(self, **data):
+        self.applyData(self.context, **data)
+        self.context._p_changed = True
+        return
+
+    @grok.action('Final Submit')
+    def finalsubmit(self, **data):
+        self.applyData(self.context, **data)
+        self.context._p_changed = True
+        # XXX: Lock the form for editing...
+        return
+
+class Login_PDE(LoginPage):
+    grok.context(IWAeUPObject)
+    grok.name('login_pde')
+
+    title = 'PDE Login'
+    pnav = 1
+
+    def update(self):
+        """Validate credentials and redirect or show error.
+
+        The real validation is done by an pluggable authentication
+        utility (PAU). Here we only check, whether correct credentials
+        were entered by looking up the principal status of the
+        request: If the user authenticated successfully, we get an
+        applicant principal. Otherwise we get the unauthenticated
+        principal.
+        """
+        formfields = ['form.ac_number', 'form.jamb_reg_no',
+                      'form.ac_series', 'form.prefix',]
+
+        self.reg_no = self.request.form.get('form.jamb_reg_no', '')
+        self.ac_series = self.request.form.get('form.ac_series', '')
+        self.ac_number = self.request.form.get('form.ac_number', '')
+
+        for required_field in formfields:
+            if required_field not in self.request.form.keys():
+                return
+        self.reg_no = self.request.form['form.jamb_reg_no']
+        self.ac_series = self.request.form['form.ac_series']
+        self.ac_number = self.request.form['form.ac_number']
+        principal = self.request.principal
+        if not IApplicantPrincipal.providedBy(principal):
+            self.flash('You entered invalid credentials')
+            return
+        if hasattr(principal, 'reg_no'):
+            if not principal.reg_no is None:
+                
+                site = grok.getSite()
+                applications = site['applications']
+                application = applications[principal.reg_no]
+                self.redirect(self.url(application, '@@edit'))
+        return
+
+    def getCurrentSession(self):
+        """Get the current session.
+
+        XXX: This should be computed or retrieved from elsewhere.
+
+        `session` here means an academic session, not a browser
+        session.
+        """
+        return u'2010/2011'
+
+    def getDeadline(self):
+        """Get application submission deadline.
+
+        XXX: This should be computed or retrieved from elsewhere.
+        """
+        return u"""Application submission deadline is at Midnight on Friday,
+                   01. October 2010. No application will be treated
+                   after the deadline."""
+
+    def getApplicantData(self, reg_no, ac):
+        """Validate credentials and return applicant data.
+
+        Returns tuple ``(<APPLICANT_ENTRY>, <ACCESSCODE>) on
+        successful validation and ``None`` else.
+
+        We expect a JAMB registration number and an access code in
+        format ``PUDE-XXX-XXXXXXXXXX``.
+
+        See
+        :func:`waeup.sirp.jambtables.util.get_applicant_data`
+        for details.
+        """
+        return get_applicant_data(reg_no, ac)
Index: /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/applicationspage.pt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/applicationspage.pt	(revision 5775)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/applicationspage.pt	(revision 5775)
@@ -0,0 +1,8 @@
+<div>
+  <div tal:repeat="entry view/getApplications">
+    <a href=""
+       tal:attributes="href entry/url"
+       tal:content="entry/name"
+       >Some Entry</a>
+  </div>
+</div>
Index: /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/form_edit_pde.pt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/form_edit_pde.pt	(revision 5775)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/form_edit_pde.pt	(revision 5775)
@@ -0,0 +1,89 @@
+<form action="." tal:attributes="action request/URL" method="post"
+      class="edit-form" enctype="multipart/form-data">
+
+  <h2 i18n:translate=""
+    tal:condition="view/label"
+    tal:content="view/label">Label</h2>
+
+  <div class="form-status"
+    tal:define="status view/status"
+    tal:condition="status">
+
+    <div i18n:translate="" tal:content="view/status">
+      Form status summary
+    </div>
+
+    <ul class="errors" tal:condition="view/errors">
+      <li tal:repeat="error view/error_views">
+         <span tal:replace="structure error">Error Type</span>
+      </li>
+    </ul>
+  </div>
+
+  <table class="form-fields">
+    <tbody>
+      <tal:block repeat="widget view/widgets">
+        <tr>
+          <td class="label" tal:define="hint widget/hint">
+            <label tal:condition="python:hint"
+                   tal:attributes="for widget/name">
+              <span class="required" tal:condition="widget/required"
+              >*</span><span i18n:translate=""
+                             tal:content="widget/label">label</span>
+            </label>
+            <label tal:condition="python:not hint"
+                   tal:attributes="for widget/name">
+              <span class="required" tal:condition="widget/required"
+              >*</span><span i18n:translate=""
+                             tal:content="widget/label">label</span>
+            </label>
+          </td>
+          <td class="field">
+            <div class="widget" tal:content="structure widget">
+              <input type="text" />
+            </div>
+            <div class="error" tal:condition="widget/error">
+              <span tal:replace="structure widget/error">error</span>
+            </div>
+          </td>
+        </tr>
+      </tal:block>
+      <tr>
+	<td colspan="2">
+	  <input type="checkbox" name="confirm" />
+	  <label for="confirm"></label>
+<span>
+	    I confirm that the Passport Photograph uploaded on this form
+            is a true picture of me.
+	  </span>
+	</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <div id="actionsView">
+    <span class="actionButtons" tal:condition="view/availableActions">
+      <input tal:repeat="action view/actions"
+             tal:replace="structure action/render"
+             />
+    </span>
+  </div>
+</form>
+
+<br />
+
+<div class="block">
+  <h3>Instructions</h3>
+  <ul class="list">
+    <li>
+      Enter your JAMB Registration Number and the Application PIN.
+    </li>
+    <li>
+      Fill the form and upload your Passport Photograph with red background
+      in jpg format.
+    </li>
+    <li>
+      Save and preview picture.  * Press the 'Final Submit' button.
+    </li>
+  </ul>
+</div>
Index: /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/login_pde.pt
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/login_pde.pt	(revision 5775)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/applicants/browser_templates/login_pde.pt	(revision 5775)
@@ -0,0 +1,56 @@
+<h3>
+  Apply for Post UDE Screening Test 
+  (<span tal:replace="view/getCurrentSession">2010/2011</span>)
+</h3>
+<div>
+  This Login is for applicants only, that went through PDE screening!
+</div>
+<form method="POST">
+  <table>
+    <tbody>
+      <tr>
+	<td width="30%"><label for="reg_no">JAMB Registration Number</label></td>
+	<td>
+	  <input type="text" name="form.jamb_reg_no"
+		 value="" tal:attributes="value view/reg_no" /></td>
+      </tr>
+      <tr>
+	<input type="hidden" name="form.prefix" value="PUDE" />
+	<td><label for="form.ac_series">Access Code</label></td>
+	<td>
+	  PUDE-<input name="form.ac_series" type="text" size="3" maxlength="3"
+	              value="" tal:attributes="value view/ac_series"
+	  />-<input name="form.ac_number" type="text" size="10" maxlength="10"
+	            value="" tal:attributes="value view/ac_number" />
+	</td>
+      </tr>
+      <tr>
+	<td colspan="2">
+	  <input type="submit" name="show" value="Show Application Record" />
+	</td>
+      </tr>
+    </tbody>
+  </table>
+</form>
+
+<div>
+  Instructions:
+  <ul class="list">
+    <li>
+      Enter your JAMB Registration Number and the Application PIN.
+    </li>
+    <li>
+      Fill the form and upload your Passport Photograph with red
+      background in jpg format.
+    </li>
+    <li>
+      Save and preview picture.
+    </li>
+    <li>
+      Press the 'Final Submit' button.
+    </li>
+  </ul>
+</div>
+<div class="error" tal:content="view/getDeadline">
+  The deadline is NOW
+</div>
