Commits

Donald Stufft committed 7946a3d

Start the port of the UX over to Werkzeug with /mirrors/

Comments (0)

Files changed (2)

templates/standard_template.pt

 
               <ul class="level-two">
 
-                <tal:for-nav repeat="link app/navlinks_html">
+                <tal:for-nav repeat="link navlinks_html">
                   <span tal:replace="structure link"/>
                 </tal:for-nav>
 		<li><a href="/pypi?:action=browse&amp;c=533&amp;show=all">Python 3 Packages</a></li>
             <div id="document-floating">
 
             <div id="document-navigation" style="overflow-y: auto; max-height: 15em; overflow-x: hidden;">
-		<tal:if-not-user condition="not: app/loggedin">
+		<tal:if-not-user condition="not: request/user/authenticated">
                   <h4>Not Logged In</h4>
 
                   <ul>
-		    <li tal:condition="app/username"><a tal:attributes="href python:app.link_action('clear_auth')">Clear Basic Auth</a></li>
+		    <li tal:condition="request/user/username"><a tal:attributes="href python:app.link_action('clear_auth')">Clear Basic Auth</a></li>
                     <li><a tal:attributes="href python: app.link_action('login')">Login</a></li>
                     <li><a tal:attributes="href python: app.link_action('register_form')">Register</a></li>
                     <li><a tal:attributes="href python: app.link_action('forgotten_password_form')">Lost Login?</a></li>
 
 		</tal:if-not-user>
 
-		<tal:if-user condition="app/loggedin">
+		<tal:if-user condition="request/user/authenticated">
 
-                  <h4>Welcome <span tal:replace="app/username"/></h4>
+                  <h4>Welcome <span tal:replace="request/user/username"/></h4>
                   <li>
                     <a tal:attributes="href python:app.link_action('user_form')">Your details</a>
                     (<a tal:attributes="href python:app.link_action('logout')">Logout</a>)
                   </li>
 
-                  <tal:let define="packages python:app.store.user_packages(app.username)">
+                  <tal:let define="packages python:app.store.user_packages(request.user.username)">
                     <tal:if-packages condition="packages">
                       <li>
 			Your packages:
 
         # Configure URL Routing
         self.url_map = routing.Map([
+            # Package Discovery API
             routing.Submount("/simple", [
                 routing.Rule("/", endpoint="simple_index", methods=["GET"]),
                 routing.Rule("/<package>/",
                 endpoint="serversig", methods=["GET"]),
             routing.Rule("/packages/<path:filename>",
                 endpoint="packages", methods=["GET"]),
+
+            # UX
+            routing.Rule("/mirrors/", endpoint="mirrors", methods=["GET"]),
         ])
 
+    @property
+    def url_path(self):
+        return self.config.url
+
     def run(self, request):
         """
         Run the request, handling all uncaught errors and finishing off
         """
         Figure out what the request is, and farm off to the appropriate handler
         """
+        request.user = User(
+            authenticated=False,
+            username="Anonymous",
+            last_login=None,
+        )
+
         with store.Store(self.config, queue=self.queue) as database:
             # Find which endpoint we are using
             urls = self.url_map.bind_to_environ(request.environ)
             # Dispatch to the endpoint
             return getattr(self, "do_%s" % endpoint)(request, database, **args)
 
-
-            if script_name == '/mirrors':
-                return self.mirrors(request, database)
             if script_name == '/security':
                 return self.security(request, database)
             if script_name == '/daytime':
 
         return request
 
+    def render_template(self, request, database, filename, **options):
+        options.setdefault("norobots", False)
+        options.setdefault("keywords",
+            "python programming language object oriented web free source "
+            "package index download software",
+        )
+        options.setdefault("description",
+            "The Python Package Index is a repository of software for the "
+            "Python programming language.",
+        )
+
+        options["providers"] = self.get_providers()
+        options["FULL_PATH_INFO"] = request.path
+
+        template_dir = os.path.join(os.path.dirname(__file__), "templates")
+
+        context = {
+            "request": request,
+            "data": options,
+            "app": self,
+            "standard_template": PyPiPageTemplate(
+                "standard_template.pt",
+                template_dir,
+            ),
+            "navlinks_html": self.navlinks_html(
+                request.user,
+                database,
+                options.get("nav_current"),
+            ),
+        }
+
+        template = PyPiPageTemplate(filename, template_dir)
+        content = template(**context)
+
+        return content
+
     # these are inserted at the top of the standard template if set
     error_message = None
     ok_message = None
         self.handler.end_headers()
         self.handler.wfile.write(payload)
 
-    def write_template(self, filename, headers={}, **options):
-        context = {}
-        options.setdefault('norobots', False)
-        options.setdefault('keywords', 'python programming language object'
-            ' oriented web free source package index download software')
-        options.setdefault('description', 'The Python Package Index is a'
-            ' repository of software for the Python programming language.')
-        options['providers'] = self.get_providers()
-        context['data'] = options
-        context['app'] = self
-        fpi = self.config.url+self.env.get('PATH_INFO',"")
-        try:
-            options['FULL_PATH_INFO'] = fpi.decode("utf-8")
-        except UnicodeError:
-            raise NotFound, fpi + ' is not utf-8 encoded'
-
-        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)
-
-        # dynamic insertion of CSRF token into FORMs
-        if '"POST"' in content and self.authenticated:
-            token = '<input type="hidden" name="CSRFToken" value="%s">' % (
-                    self.store.get_token(self.username),)
-            temp = content.split('\n')
-            edit = ((i, l) for i, l in enumerate(content.split('\n')) if
-                    '"POST"' in l)
-            try:
-                for index, line in edit:
-                    while not line.endswith('>'):
-                        index += 1
-                        line = temp[index]
-                    # count spaces to align entry nicely
-                    spaces = len(line.lstrip()) - len(line)
-                    temp[index] = "\n".join((line, ' ' * spaces + token))
-                content = '\n'.join(temp)
-            except IndexError:
-                # this should not happen with correct HTML syntax
-                # the try is 'just in case someone does something stupid'
-                pass
-
-        self.handler.send_response(200, 'OK')
-        if 'content-type' in options:
-            self.handler.set_content_type(options['content-type'])
-        else:
-            self.handler.set_content_type('text/html; charset=utf-8')
-        if self.usercookie:
-            if self.url_machine.startswith('https'):
-                secure = ';secure'
-            else:
-                secure = ''
-
-            self.handler.send_header('Set-Cookie',
-                'pypi=%s;path=/%s' % (self.usercookie, secure))
-        for k,v in headers.items():
-            self.handler.send_header(k, v)
-        self.handler.end_headers()
-        self.wfile.write(content.encode('utf-8'))
-
     def fail(self, message, title="Python Package Index", code=400,
             heading=None, headers={}, content=''):
         ''' Indicate to the user that something has failed.
         ('packages_rss', 'RSS (newest 40 packages)'),
         ('role_form', 'Admin'),
     )
-    def navlinks_html(self):
+    def navlinks_html(self, user, database, nav_current):
         links = []
         for action_name, desc in self.navlinks:
             desc = desc.replace(' ', '&nbsp;')
             if action_name == 'role_form' and (
-                not self.username or not self.store.has_role('Admin', '')):
+                not user.username or not database.has_role('Admin', '')):
                 continue
 
             cssclass = ''
-            if action_name == self.nav_current:
+            if action_name == nav_current:
                 cssclass = 'selected'
             links.append('<li class="%s"><a class="%s" href="%s">%s</a></li>' %
                          (cssclass, cssclass, self.link_action(action_name), desc))
         version = cgi.escape(version)
         return u'<a href="%s">%s&nbsp;%s</a>'%(url, name, version)
 
-    def mirrors(self):
-        ''' display the list of mirrors
-        '''
-        options = {'title': 'PyPI Mirrors'}
-        self.write_template('mirrors.pt', **options)
+    def do_mirrors(self, request, database):
+        """
+        display the list of mirrors
+        """
+        return Response(
+            self.render_template(request, database, "mirrors.pt",
+                title="PyPI Mirrors",
+            ),
+            content_type="text/html",
+        )
 
     def security(self):
         ''' display the list of mirrors