source: products/quintagroup.distrpoxy/trunk/quintagroup/distproxy/wsgi.py @ 1587

Last change on this file since 1587 was 1587, checked in by chervol, 11 years ago

added refresh of index.hmtl if it is older the 1 hour

  • Property svn:eol-style set to native
File size: 5.6 KB
RevLine 
[1066]1import os
2import socket
3import sys
[1587]4from time import time
[1066]5from paste.script.appinstall import Installer as BaseInstaller
6from paste.fileapp import FileApp
[1082]7from paste import urlparser
8from paste import request
[1066]9from paste.httpexceptions import HTTPNotFound
10from spider import webmirror
11
12class PackageProxyApp(object):
13
14    def __init__(self, index_url=None, pack_dir=None):
15        if not index_url: 
16            print "No repository index provided"
17            sys.exit()
18        if not pack_dir:
19            print "No packages cache directory provided"
20            sys.exit()
21        if not os.path.isdir(pack_dir):
22            print 'You must create the %r directory' % pack_dir
23            sys.exit()
24        self.index_url = index_url
25        self.pack_dir = pack_dir
26
27    def __call__(self, environ, start_response):
28        path = environ.get('PATH_INFO', '').strip()
[1083]29        path_parts = path.split('/')
30        if len(path_parts) > 1 and path_parts[1] == "favicon.ico":
[1082]31            return HTTPNotFound()(environ, start_response)
32        filename = self.checkCache(path)
[1066]33        if filename is None:
34            return HTTPNotFound()(environ, start_response)
35        return FileApp(filename)(environ, start_response)
36
37    def checkCache(self, path):   
38        pth = self.pack_dir + path
39        pth1 = pth
[1260]40        if not (path[-3:] in ['tgz','.gz','egg','zip','exe','cfg']): 
[1066]41            pth1 = pth + 'index.html'
42        else:
43            pth = '/'.join(pth.split('/')[:-1])
44        if not os.path.exists(pth1):
[1082]45            webmirror(pth,1,self.index_url+path,0,1)
[1587]46        elif int(time()) - os.path.getmtime(pth1) > 3600:
47            webmirror(pth,1,self.index_url+path,0,1)
[1066]48        if pth1:
49            return pth1
50        return pth
51
52def app_factory(global_config, **local_conf):
53    # Grab config from wsgi .ini file. If not specified, config.py's values
54    # take over.
55    pack_dir = local_conf.get('pack_directory', None)
56    index_url = local_conf.get('index', None)
57    return PackageProxyApp(index_url, pack_dir)
[1082]58
59class StaticURLParser(urlparser.StaticURLParser):
60
61    def __call__(self, environ, start_response):
62        path_info = environ.get('PATH_INFO', '')
63        if not path_info:
64            return self.add_slash(environ, start_response)
65        if path_info == '/':
66            # @@: This should obviously be configurable
67            filename = 'index.html'
68        else:
69            filename = request.path_info_pop(environ)
70        full = os.path.normcase(os.path.normpath(
71            os.path.join(self.directory, filename)))
72        if os.path.sep != '/':
73            full = full.replace('/', os.path.sep)
74        if self.root_directory is not None and not full.startswith(self.root_directory):
75            # Out of bounds
76            return self.not_found(environ, start_response)
77        if not os.path.exists(full):
78            if full.endswith('index.html') and not os.path.isfile(full):
[1083]79                start_response('200 OK', [('Content-Type', 'text/html')])
[1082]80                return [self.get_index_html()]
81            return self.not_found(environ, start_response)
82        if os.path.isdir(full):
83            # @@: Cache?
84            child_root = self.root_directory is not None and \
85                self.root_directory or self.directory
86            return self.__class__(full, root_directory=child_root,
87                                  cache_max_age=self.cache_max_age)(environ,
88                                                                   start_response)
89        if environ.get('PATH_INFO') and environ.get('PATH_INFO') != '/':
90            return self.error_extra_path(environ, start_response)
91        if_none_match = environ.get('HTTP_IF_NONE_MATCH')
92        if if_none_match:
93            mytime = os.stat(full).st_mtime
94            if str(mytime) == if_none_match:
95                headers = []
96                ETAG.update(headers, mytime)
97                start_response('304 Not Modified', headers)
98                return [''] # empty body
99
100        fa = self.make_app(full)
101        if self.cache_max_age:
102            fa.cache_control(max_age=self.cache_max_age)
103        return fa(environ, start_response)
104
105    def get_index_html(self):
106        path = self.directory
107        # create sorted lists of directories and files
[1083]108        names = [i for i in os.listdir(path) if not i.startswith('.')]
[1082]109        dirs = [i for i in names if os.path.isdir(os.path.join(path, i))]
110        dirs.sort()
111        files = [i for i in names if os.path.isfile(os.path.join(path, i))]
112        files.sort()
113        names = dirs + files
114        links = '\n'.join(['<li><a href="%s">%s</a></li>' %  (i, i) for i in names])
115        template = open(os.path.join(os.path.dirname(__file__), 'index.html')).read()
116        return template % {'path': path[len(self.root_directory):], 'links': links}
117
118def make_static(global_conf, document_root, cache_max_age=None):
119    """
120    Return a WSGI application that serves a directory (configured
121    with document_root)
122
123    cache_max_age - integer specifies CACHE_CONTROL max_age in seconds
124    """
125    if cache_max_age is not None:
126        cache_max_age = int(cache_max_age)
127    return StaticURLParser(
128        document_root, cache_max_age=cache_max_age)
129
130
[1066]131"""
132class Installer(BaseInstaller):
133    use_cheetah = False
134    config_file = 'deployment.ini_tmpl'
135
136    def config_content(self, command, vars):
137        import pkg_resources
138        module = 'collective.eggproxy'
139        if pkg_resources.resource_exists(module, self.config_file):
140            return self.template_renderer(
141                pkg_resources.resource_string(module, self.config_file),
142                vars,
143                filename=self.config_file)
[1260]144"""
Note: See TracBrowser for help on using the repository browser.