Commits

Tarek Ziadé  committed 5a8b7e2

supporting PEP 345 fields in the requests

  • Participants
  • Parent commits 2fe00e2

Comments (0)

Files changed (4)

         journal entry.
         '''
         date = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
-
         cursor = self.get_cursor()
         # see if we're inserting or updating a package
         if not self.has_package(name):
                 old.append('classifiers')
 
             # get old classifiers list
-            for col in ('requires', 'provides', 'obsoletes'):
+            for col in ('requires', 'provides', 'obsoletes', 'requires_dist',
+                        'provides_dist', 'obsoletes_dist', 'requires_python',
+                        'requires_external', 'project_url'):
                 relationships[col] = self.get_release_relationships(name,
                     version, col)
                 relationships[col].sort()
                     (name, version, trove_id))
 
         # handle relationship specifiers
-        for col in ('requires', 'provides', 'obsoletes'):
+        for col in ('requires', 'provides', 'obsoletes', 'requires_dist',
+                    'provides_dist', 'obsoletes_dist', 'requires_python',
+                    'requires_external', 'project_url'):
             if not info.has_key(col) or relationships.get(col, []) == info[col]:
                 continue
             safe_execute(cursor, '''delete from release_%s where name=%%s
 
     def get_package_requires_dist(self, name, version):
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select specifier from release_requires_dist 
+        safe_execute(cursor, '''select specifier from release_requires_dist
             where name=%s and version=%s ''', (name, version))
         packages = []
         for package in cursor.fetchall():
 
     def get_package_provides_dist(self, name, version):
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select specifier from release_provides_dist 
+        safe_execute(cursor, '''select specifier from release_provides_dist
             where name=%s and version=%s ''', (name, version))
         packages = []
         for package in cursor.fetchall():
 
     def get_package_project_url(self, name, version):
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select specifier from release_project_url 
+        safe_execute(cursor, '''select specifier from release_project_url
             where name=%s and version=%s ''', (name, version))
         project_urls = []
         for project in cursor.fetchall():
 
         # delete ancillary table entries
         for tab in ('files', 'provides', 'requires', 'obsoletes',
-                'classifiers'):
+                'classifiers', 'requires_dist', 'provides_dist',
+                'obsoletes_dist', 'requires_python', 'requires_external',
+                'project_url'):
             safe_execute(cursor, '''delete from release_%s where
                 name=%%s and version=%%s'''%tab, (name, version))
         safe_execute(cursor, 'delete from description_urls where name=%s and version=%s',
         safe_execute(cursor, '''insert into journals (name, version, action,
                 submitted_date, submitted_by, submitted_from) values
                 (%s, %s, %s, %s, %s, %s)''', (name, version, 'remove', date,
-                                              self.username, self.userip))        
+                                              self.username, self.userip))
 
     def remove_package(self, name):
         ''' Delete an entire package from the database.
 
         # delete ancillary table entries
         for tab in ('files', 'provides', 'requires', 'obsoletes',
-                'classifiers'):
+                'classifiers', 'requires_dist', 'provides_dist',
+                'obsoletes_dist', 'requires_python', 'requires_external',
+                'project_url'):
             safe_execute(cursor, 'delete from release_%s where name=%%s'%tab,
                 (name, ))
 
         '''Copy a user-s rating of package name from one version to another;
         return the comment if any'''
         cursor = self.get_cursor()
-        safe_execute(cursor, '''insert into ratings(name,version,user_name,date,rating) 
+        safe_execute(cursor, '''insert into ratings(name,version,user_name,date,rating)
                      select name,%s,user_name,now(),rating from ratings
                      where name=%s and version=%s and user_name=%s''',
                      (toversion, name, fromversion, self.username))
         if cid:
             cid = cid[0]
             safe_execute(cursor, '''insert into comments(rating, user_name, date, message, in_reply_to)
-                     select currval('ratings_id_seq'), user_name, date, message, in_reply_to 
+                     select currval('ratings_id_seq'), user_name, date, message, in_reply_to
                      from comments where id=%s''', (cid,))
             safe_execute(cursor, '''insert into comments_journal(name, version, id, submitted_by, date, action)
-                     values(%s, %s, currval('comments_id_seq'), %s, now(), %s)''', (name, toversion, 
+                     values(%s, %s, currval('comments_id_seq'), %s, now(), %s)''', (name, toversion,
                      self.username, 'copied %s' % cid))
 
             safe_execute(cursor, '''select message from comments
         safe_execute(cursor, """insert into comments_journal(name, version, id, submitted_by, date, action)
         select %s, %s, id, %s, now(), 'deleted' from ratings where user_name=%s and name=%s and version=%s""",
                      (name, version, self.username, self.username, name, version))
-        safe_execute(cursor, "delete from ratings where user_name=%s and name=%s and version=%s", 
+        safe_execute(cursor, "delete from ratings where user_name=%s and name=%s and version=%s",
                      (self.username, name, version))
 
     _Rating=FastResultRow('id! date! user rating!')
     def get_ratings(self, name, version):
         '''Return ratings,messages for a release.'''
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select id, date, user_name, rating from ratings 
+        safe_execute(cursor, '''select id, date, user_name, rating from ratings
                      where name=%s and version=%s order by date''', (name, version))
         res = cursor.fetchall()
         safe_execute(cursor, '''select c.id, c.rating, c.user_name, c.date, c.message, c.in_reply_to from
     def has_rating(self, name, version):
         '''Check whether user has rated this release'''
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select count(*) from ratings 
+        safe_execute(cursor, '''select count(*) from ratings
                      where user_name=%s and name=%s and version=%s''', (self.username, name, version))
         return cursor.fetchall()[0][0]
 
     def latest_rating(self, name):
         '''Return the user-s latest rating on any release, or None.'''
         cursor = self.get_cursor()
-        safe_execute(cursor, '''select version from ratings 
+        safe_execute(cursor, '''select version from ratings
                      where user_name=%s and name=%s order by date desc limit 1''', (self.username, name))
         res = cursor.fetchone()
         if res:
         '''
         cursor = self.get_cursor()
         safe_execute(cursor, 'insert into sshkeys(name, key) values(%s, %s)', (username, key))
-        
+
     def delete_sshkey(self, id):
         '''Delete an SSH key given by ID.
         '''

File templates/display.pt

  </li>
 
 
+
  <li tal:condition="data/requires_dist | nothing">
    <strong>Requires</strong>
    <ul class="nodot">
    </ul>
  </li>
 
+
+
  <li tal:condition="data/roles/Owner | nothing">
   <strong>Package Index Owner:</strong>
   <span tal:content="python:', '.join(data['roles']['Owner'])" />

File templates/standard_template.pt

 <?xml version="1.0" encoding="UTF-8"?>
 <metal:macro define-macro="page"
-             xmlns="http://www.w3.org/1999/xhtml" 
+             xmlns="http://www.w3.org/1999/xhtml"
              xmlns:tal="http://xml.zope.org/namespaces/tal"
              xmlns:metal="http://xml.zope.org/namespaces/metal">
   <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
        <link media="screen" tal:attributes="href string:${app/config/pydotorg}styles/largestyles.css" type="text/css" rel="alternate stylesheet" title="large text" />
        <link media="screen" tal:attributes="href string:${app/config/pydotorg}styles/defaultfonts.css" type="text/css" rel="alternate stylesheet" title="default fonts" />
        <link rel="stylesheet" media="screen" href="/css/docutils.css" type="text/css"/>
-      
+
        <metal:slot define-slot="head" />
 
        <style type="text/css" rel="stylesheet">
 	 -moz-border-radius-topleft: 12px;
 	 -moz-border-radius-bottomright: 12px;
 	 }
-	 
+
 	 #document-project-url ul
 	 {
 	 list-style: none;
 	 background: none;
 	 width: auto;
 	 font-size: 103%;
-	 font-family: Verdana, Geneva, "Bitstream Vera Sans", Helvetica, sans-serif; 
+	 font-family: Verdana, Geneva, "Bitstream Vera Sans", Helvetica, sans-serif;
 	 }
-	 
-	 #document-project-url a:link, #document-project-url a:visited 
+
+	 #document-project-url a:link, #document-project-url a:visited
 	 {
 	 color:#3C4B6B;
 	 text-decoration:  none;
 	 }
-	 
+
 	 #document-project-url a:hover
 	 {
 	 color: #000000;
 	 text-decoration: underline;
 	 }
-	 
+
 	 #document-project-url h4 a:link, #document-project-url  h4 a:visited
 	 {
 	 color: #FFFFFF;
 	 }
-	 
+
 
 	 #document-project-url h4 a:hover
 	 {
 	 color: #FFFFFF;
-	 
+
 	 }
 	 #document-project-url form {
 	 margin:12px;
 <!-- XXX: reinstate this       <div id="screen-switcher"></div> -->
       </div>
       <div id="left-hand-navigation">
-        
+
         <!--  Main Menu NEED LEVEL TWO HEADER AND FOOTER -->
         <div id="menu">
-          <ul class="level-one">            
+          <ul class="level-one">
             <li class="selected">
               <a class="selected" tal:attributes="href app/url_path">Package Index</a>
-            
+
               <ul class="level-two">
-                
+
                 <tal:for-nav repeat="link app/navlinks_html">
                   <span tal:replace="structure link"/>
                 </tal:for-nav>
             </li>
 
 
-            
+
 
             <li class=""><a href="http://www.python.org/about" class="" title="About The Python Language">About</a>
             </li><li class=""><a href="http://www.python.org/news" class="" title="">News</a>
             </li><li class=""><a href="http://www.python.org/doc" class="" title="">Documentation</a>
             </li><li class=""><a href="http://www.python.org/download" title="">Download</a>
-            
+
 
             </li><li class=""><a href="http://www.python.org/community" class="" title="">Community</a>
             </li><li class=""><a href="http://www.python.org/psf" class="" title="Python Software Foundation">Foundation</a>
           </li>
           </ul>
         </div>
-              
+
       </div>
       <div id="content-body">
         <div id="body-main">
             <div id="breadcrumb">
               <a tal:attributes="href app/url_path">Package Index</a>
               <tal:block condition="exists:data/version">
-                <span class="breadcrumb-separator">&gt;</span> 
+                <span class="breadcrumb-separator">&gt;</span>
                 <a tal:content="data/title" tal:attributes="href python:app.packageURL(data['name'], data['version'])"></a>
               </tal:block>
-              
+
             </div>
 
 	    <div id="document-floating" class="floating-box">
                       </tal:block>
                     </li>
                   </ul>
-		  
+
 		</tal:if-not-user>
-		
+
 		<tal:if-user condition="app/loggedin">
 
                   <h4>Welcome <span tal:replace="app/username"/></h4>
                   <li>
                     <a tal:attributes="href python:app.link_action('user_form')">Your details</a>
                   </li>
-		  
+
                   <tal:let define="packages python:app.store.user_packages(app.username)">
                     <tal:if-packages condition="packages">
                       <li>
 			Your packages:
                       </li>
-                      <ul>                      
+                      <ul>
 			<li>
                           <tal:block repeat="pkg_info packages">
                             <a tal:attributes="href python: app.link_action('pkg_edit', name=pkg_info[0])"
                     <a tal:attributes="href python:app.link_action('logout')">Logout</a>
                   </li>
 		</tal:if-user>
-            
+
             </div>
 
 	    <tal:block condition="data/project_url | nothing">
 	      <div id="document-project-url" class="floating-box">
-		<h4>Project-URL</h4>
+		<h4>Project Links</h4>
 		<ul>
 		  <tal:block tal:repeat="project data/project_url">
-		    <li>
-		      <a tal:content="python:project[0]" tal:attributes="href python:project[1]"></a>
+          <li>
+            <a tal:content="python:project[0]" tal:attributes="href python:project[1]"></a>
 		    </li>
 		  </tal:block>
 		</ul>
               <h1 tal:content="data/title"></h1>
 
               <metal:slot define-slot="body">
-                
+
                 This template has not replaced its body slot.
-                
+
               </metal:slot>
-              
+
             </div>
 
 
           </div>
           <div id="footer"><div id="credits">
             <a href="http://www.python.org/about/website">Website maintained by the Python community</a><br />
-            <a href="http://www.xs4all.com/" title="Web and email hosting provided by xs4all, Netherlands">hosting by xs4all</a> / 
+            <a href="http://www.xs4all.com/" title="Web and email hosting provided by xs4all, Netherlands">hosting by xs4all</a> /
             <a href="http://www.pollenation.net/" title="Design and content management system by Pollenation Internet, Yorkshire">design by pollenation</a>
           </div>
           Copyright © 1990-2010, <a href="http://www.python.org/psf">Python Software Foundation</a><br />
         template_dir = os.path.join(os.path.dirname(__file__), 'templates')
         context['standard_template'] = PyPiPageTemplate(
             "standard_template.pt", template_dir)
-
         template = PyPiPageTemplate(filename, template_dir)
         content = template(**context)
 
     def display_pkginfo(self, name=None, version=None):
         '''Reconstruct and send a PKG-INFO metadata file.
         '''
-
+        # XXX tarek need to add 1.2 support here
+        #
         info, name, version = self._get_pkg_info(name, version)
         if not info:
             return self.fail('No such package / version',
 
         # Compute rating data
         has_rated = self.loggedin and self.store.has_rating(name, version)
-        latest_rating = self.loggedin and self.store.latest_rating(name)        
+        latest_rating = self.loggedin and self.store.latest_rating(name)
         ratings, comments = self.store.get_ratings(name, version)
         total = 0.0
         hcomments = [] # as a hierarchy
                         rating = ', %s points' % rating
                 else:
                     rating = ''
-                result.append("<li>%s (%s%s):<br/>%s %s" % 
+                result.append("<li>%s (%s%s):<br/>%s %s" %
                                 (c['user'], date, rating, message, reply))
                 if children:
                     result.extend(render_comments(children, False))
             data['platform'] = ','.join(data['platform'])
 
         # make sure relationships are lists
-        for name in ('requires', 'provides', 'obsoletes'):
+        for name in ('requires', 'provides', 'obsoletes',
+                     'requires_dist', 'provides_dist',
+                     'obsoletes_dist', 'requires_python',
+                     'requires_external', 'project_url'):
             if data.has_key(name) and not isinstance(data[name],
                     types.ListType):
                 data[name] = [data[name]]
             v = self.form[k]
             if k == '_pypi_hidden':
                 v = v == '1'
-            elif k in ('requires', 'provides', 'obsoletes'):
+            elif k in ('requires', 'provides', 'obsoletes',
+                       'requires_dist', 'provides_dist',
+                       'obsoletes_dist', 'requires_python',
+                       'requires_external', 'project_url'):
                 if not isinstance(v, list):
                     v = [x.strip() for x in re.split('\s*[\r\n]\s*', v)]
                 else:
             data[k.lower()] = v
 
         # make sure relationships are lists
-        for name in ('requires', 'provides', 'obsoletes'):
+        for name in ('requires', 'provides', 'obsoletes',
+                     'requires_dist', 'provides_dist',
+                     'obsoletes_dist', 'requires_python',
+                     'requires_external', 'project_url'):
             if data.has_key(name) and not isinstance(data[name],
                     types.ListType):
                 data[name] = [data[name]]
             except ValueError, message:
                 raise ValueError, 'Bad "provides" syntax: %s'%message
 
+        # XXX tarek todo : check PEP 345 fields
+        #
         # check classifiers
         if data.has_key('classifiers'):
             d = {}
         if not self.form.has_key('msg'):
             raise FormError
         comment = self.store.get_comment(self.form['msg'])
-        self.write_template('comment.pt', title='Reply to comment', 
+        self.write_template('comment.pt', title='Reply to comment',
                             comment=comment)
 
     def addcomment(self):
         comment_email(self.store, name, version, self.username, comment, [orig['user']])
 
         return self.display(name=name, version=version)
-        
+
 
     def delcomment(self):
         if not self.authenticated:
         return self.register_form()
 
     def rp_discovery(self):
-        payload = '''<xrds:XRDS  
-                xmlns:xrds="xri://$xrds"  
-                xmlns="xri://$xrd*($v*2.0)">  
-                <XRD>  
-                     <Service priority="1">  
-                              <Type>http://specs.openid.net/auth/2.0/return_to</Type>  
-                              <URI>%s</URI>  
-                     </Service>  
-                </XRD>  
+        payload = '''<xrds:XRDS
+                xmlns:xrds="xri://$xrds"
+                xmlns="xri://$xrd*($v*2.0)">
+                <XRD>
+                     <Service priority="1">
+                              <Type>http://specs.openid.net/auth/2.0/return_to</Type>
+                              <URI>%s</URI>
+                     </Service>
+                </XRD>
                 </xrds:XRDS>
         ''' % (self.config.url+'?:action=openid_return')
         self.handler.send_response(200)