[Checkins] SVN: Sandbox/luciano/kirbi/src/kirbi/ integrated all forms with a new form template

Luciano Ramalho luciano at ramalho.org
Thu Aug 16 21:49:40 EDT 2007


Log message for revision 78887:
  integrated all forms with a new form template
  

Changed:
  U   Sandbox/luciano/kirbi/src/kirbi/app.py
  U   Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt
  U   Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt
  U   Sandbox/luciano/kirbi/src/kirbi/book.py
  U   Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt
  A   Sandbox/luciano/kirbi/src/kirbi/form.pt
  U   Sandbox/luciano/kirbi/src/kirbi/interfaces.py
  U   Sandbox/luciano/kirbi/src/kirbi/pac.py
  U   Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt
  U   Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt
  U   Sandbox/luciano/kirbi/src/kirbi/static/master.css
  U   Sandbox/luciano/kirbi/src/kirbi/user.py

-=-
Modified: Sandbox/luciano/kirbi/src/kirbi/app.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app.py	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app.py	2007-08-17 01:49:39 UTC (rev 78887)
@@ -10,6 +10,10 @@
 PAC_NAME = u'pac'
 USER_FOLDER_NAME = u'u'
 
+grok.define_permission('kirbi.Join')
+grok.define_permission('kirbi.EditBook')
+grok.define_permission('kirbi.DeleteBook')
+
 class Kirbi(grok.Application, grok.Container):
     """Peer-to-peer library system."""
     def __init__(self):
@@ -40,4 +44,5 @@
 
 class Master(grok.View):
     """The master page template macro."""
+    # register this view for all objects
     grok.context(Interface)

Modified: Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app_templates/index.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -4,12 +4,6 @@
 </head>
 <body>
   <span metal:fill-slot="content_title">Collective catalog</span>
-  <span metal:fill-slot="content_actions">
-    <form class="search" tal:attributes="action view/pac_url">
-        <input type="text" name="query">
-        <input type="submit" name="submit" value="search">
-    </form>
-  </span>
 
   <div metal:fill-slot="content">
 

Modified: Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/app_templates/master.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -20,6 +20,7 @@
 
 </head>
 <body onload=setfocus()>
+
   <div class="top">
     <a tal:attributes="href python:view.application_url()">
         <img tal:attributes="src static/circulante-logo-transp-212x51.png"
@@ -52,7 +53,14 @@
               (not logged in)
            </span>
         </span>
-        <span metal:define-slot="content_actions" />
+        <span metal:define-slot="content_actions">
+          <form class="search" tal:attributes="action python:view.application_url('pac')">
+              <input type="text" name="query">
+              <input type="submit" name="submit" value="search">
+          </form>
+        </span>
+        
+        
       </span>
     </div>
     <div class="content">

Modified: Sandbox/luciano/kirbi/src/kirbi/book.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/book.py	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/book.py	2007-08-17 01:49:39 UTC (rev 78887)
@@ -240,11 +240,13 @@
         for key, value in kwargs.items():
             setattr(self,key,value)
 
-
 class Edit(grok.EditForm):
-    # XXX: only the site manager should be able to edit a book
-    pass
+    grok.require('kirbi.EditBook')
 
+    form_fields = grok.AutoFields(IBook)
+    template = grok.PageTemplateFile('form.pt')
+    form_title = u'Edit book record'
+
 class Display(grok.DisplayForm):
     pass
 
@@ -261,12 +263,14 @@
         self.isbn13 = self.context.isbn13
         self.creator_search_url =  self.application_url('pac')+'?query=cr:'
         self.subjects = ', '.join(self.context.subjects)
-        if self.context.source and self.context.source_item_id:
+        if (self.context.source_url and self.context.source
+                                    and self.context.source_item_id):
             self.source = '%s #%s' % (self.context.source,
                                      self.context.source_item_id)
+            self.source_url = self.context.source_url
         else:
             self.source = self.context.source
-        self.source_url = self.context.source_url
+            self.source_url = None
 
     def coverUrl(self):
         cover_name = 'covers/large/'+self.context.__name__+'.jpg'

Modified: Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/book_templates/index.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -6,12 +6,6 @@
 </head>
 <body>
   <span metal:fill-slot="content_title">Book details</span>      
-  <span metal:fill-slot="content_actions">
-    <form class="search" action="../pac">
-        <input type="text" name="query">
-        <input type="submit" name="submit" value="search">
-    </form>
-  </span>
 
   <div metal:fill-slot="content">
 

Added: Sandbox/luciano/kirbi/src/kirbi/form.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/form.pt	                        (rev 0)
+++ Sandbox/luciano/kirbi/src/kirbi/form.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -0,0 +1,46 @@
+<html metal:use-macro="context/@@master/page">
+<body>
+
+    <span metal:fill-slot="content_title"
+        tal:content="view/form_title|string:Form"></span>
+    
+    <div metal:fill-slot="content">
+    
+        <form class="edit-form" enctype="multipart/form-data" method="post"
+            action="." tal:attributes="action request/URL">
+        
+        <h1 tal:content="view/label" i18n:translate="">Edit something</h1>
+        
+        <div class="summary" tal:condition="view/status"
+             tal:content="view/status" i18n:translate="">Status</div>
+        
+        <div class="row" tal:repeat="widget view/widgets">
+          <div class="label">
+            <label for="field.name" title="The widget's hint"
+                   tal:attributes="for widget/name; title widget/hint"
+                   tal:content="widget/label" i18n:translate=""
+                   i18n:attributes="title">Label</label>
+          </div>
+        
+          <div tal:condition="widget/error"
+               tal:content="structure widget/error">Error</div>
+        
+          <div class="field">
+            <input tal:replace="structure widget" />
+          </div>
+        </div>
+        
+        <div class="row">
+          <div class="label">&nbsp;</div>
+          <div class="field">
+            <span class="actionButtons" tal:condition="view/availableActions">
+              <input tal:repeat="action view/actions"
+                     tal:replace="structure action/render"
+                     />
+            </span>
+          </div>
+        </div>    
+        </form>
+    </div>
+</body>
+</html>

Modified: Sandbox/luciano/kirbi/src/kirbi/interfaces.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/interfaces.py	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/interfaces.py	2007-08-17 01:49:39 UTC (rev 78887)
@@ -10,7 +10,15 @@
                             required=False)
     password = schema.Password(title=u"Password",
                             required=True)
+    password_confirmation = schema.Password(title=u"Confirm password",
+                            required=True)
 
+    @invariant
+    def passwordConfirm(user):
+        if (user.password != user.password_confirmation):
+            raise Invalid(u'The password and confirmation do not match.')
+
+
 class InvalidISBN(schema.ValidationError):
     """This is not a valid ISBN-10 or ISBN-13"""
 
@@ -47,7 +55,7 @@
                             value_type=schema.TextLine(),
                             default=())
             
-    source = schema.TextLine(title=u"Record source",
+    source = schema.TextLine(title=u"Metadata source",
                              required=False,
                              description=u"Name of the source of this record.")
     source_url = schema.URI(title=u"Source URL",
@@ -62,7 +70,7 @@
     @invariant
     def titleOrIsbnGiven(book):
         if (not book.title or not book.title.strip()) and (not book.isbn):
-            raise Invalid('Either the title or the ISBN must be given.')
+            raise Invalid(u'Either the title or the ISBN must be given.')
 
 class ICopy(Interface):
     """An exemplar of a book."""

Modified: Sandbox/luciano/kirbi/src/kirbi/pac.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac.py	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac.py	2007-08-17 01:49:39 UTC (rev 78887)
@@ -138,13 +138,18 @@
 
         self.results = sorted(results, key=attrgetter('filing_title'))
 
-
 class AddBook(grok.AddForm):
+    grok.require('kirbi.EditBook')
 
-    form_fields = grok.AutoFields(Book)
+    form_fields = grok.AutoFields(IBook).omit(*['source','source_url',
+                                                'source_item_id'])
+    template = grok.PageTemplateFile('form.pt')
+    form_title = u'Add book'
 
-    @grok.action('Add book')
+    @grok.action('Save book')
     def add(self, **data):
+        ### XXX: investigate why the source data is not being recorded
+        data['source'] = self.request.principal.getLogin()
         book = Book()
         self.applyData(book, **data)
         self.context.addBook(book)

Modified: Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac_templates/addbooks.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -7,12 +7,6 @@
 </head>
 <body>
   <span metal:fill-slot="content_title">Collective catalog</span>
-  <span metal:fill-slot="content_actions">
-    <form class="search" action=".">
-        <input type="text" name="query">
-        <input type="submit" name="submit" value="search">
-    </form>
-  </span>
   <div metal:fill-slot="content">
   <table><tr>
     <td valign="top">

Modified: Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/pac_templates/index.pt	2007-08-17 01:49:39 UTC (rev 78887)
@@ -7,12 +7,6 @@
 </head>
 <body>
   <span metal:fill-slot="content_title">Collective catalog</span>
-  <span metal:fill-slot="content_actions">
-    <form class="search" action=".">
-        <input type="text" name="query">
-        <input type="submit" name="submit" value="search">
-    </form>
-  </span>
   <div metal:fill-slot="content">
 
     <h3 tal:content="view/results_title">999 items matched the query</h3>

Modified: Sandbox/luciano/kirbi/src/kirbi/static/master.css
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/static/master.css	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/static/master.css	2007-08-17 01:49:39 UTC (rev 78887)
@@ -58,7 +58,6 @@
     color: gray;
 }
 dt { font-size: 12pt; }
-th { font-size: 10pt; }
 dd { font-size: 11pt; }
 
 div.content_menu {
@@ -98,7 +97,7 @@
     font-family: sans-serif;
     font-weight: bold;
 }
-th {
+th, .label {
     font-family: sans-serif;
     font-weight: bold;
     font-size: 10pt;
@@ -124,3 +123,20 @@
 .error {
     color: red;
 }
+
+form .row {
+    clear: both;
+    margin: 3px;
+}
+
+form .label {
+    float: left;
+    width: 10em;
+    padding: 7px;
+}
+
+form .field {
+    width: 40em;
+    float: left;
+    padding: 7px;
+}
\ No newline at end of file

Modified: Sandbox/luciano/kirbi/src/kirbi/user.py
===================================================================
--- Sandbox/luciano/kirbi/src/kirbi/user.py	2007-08-17 00:49:04 UTC (rev 78886)
+++ Sandbox/luciano/kirbi/src/kirbi/user.py	2007-08-17 01:49:39 UTC (rev 78887)
@@ -22,7 +22,7 @@
         user = self.get(id)
         if user is not None:
             given_hash = sha.new(credentials['password']).hexdigest()
-            if user.password == given_hash:
+            if user.password_hash == given_hash:
                 return IPrincipalInfo(self[id])
 
 class User(grok.Container):
@@ -34,23 +34,34 @@
         >>> alice = User('alice', u'Alice Cooper', u'headless-chicken')
         >>> IUser.providedBy(alice)
         True
-        >>> alice.password
-        'f030ff587c602e0e9a68aba75f41c51a0dc22c62'
         >>> alice.name_and_login()
         u'Alice Cooper (alice)'
+        
+    The password is not saved, only a SHA hash::
+
+        >>> alice.password is None
+        True
+        >>> alice.password_hash
+        'f030ff587c602e0e9a68aba75f41c51a0dc22c62'
+
     """
 
     implements(IUser)
 
     login = u''
     name = u''
-    password = ''
+    password_hash = ''
 
-    def __init__(self, login, name, password):
+    def __init__(self, login, name, password, password_confirmation=None):
         super(User, self).__init__()
         self.login = login
         self.name = name
-        self.password = sha.new(password).hexdigest()
+        if ((password_confirmation is not None)
+                and password != password_confirmation):
+            raise ValueError, u'Password and confirmation do not match'
+        self.password_hash = sha.new(password).hexdigest()
+        # we don't want to store the clear password
+        self.password = self.password_confirmation = None
 
     def name_and_login(self):
         if self.name:
@@ -106,12 +117,16 @@
         return "This should log you out (but doesn't yet)."
 
 class Join(grok.AddForm):
+    """User registration form"""
     grok.context(UserFolder)
-    """User registration form"""
 
     form_fields = grok.AutoFields(IUser)
+    template = grok.PageTemplateFile('form.pt')
+    form_title = u'User registration'
 
-    @grok.action('Add entry')
+    ### XXX: find out how to display message of the Invalid exception raised
+    ### by the password confirmation invariant (see interfaces.IUser)
+    @grok.action('Save')
     def add(self, **data):
         login = data['login']
         self.context[login] = User(**data)



More information about the Checkins mailing list