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

Last change on this file since 1587 was 1587, checked in by chervol, 14 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
Line 
1import os
2import socket
3import sys
4from time import time
5from paste.script.appinstall import Installer as BaseInstaller
6from paste.fileapp import FileApp
7from paste import urlparser
8from paste import request
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()
29        path_parts = path.split('/')
30        if len(path_parts) > 1 and path_parts[1] == "favicon.ico":
31            return HTTPNotFound()(environ, start_response)
32        filename = self.checkCache(path)
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
40        if not (path[-3:] in ['tgz','.gz','egg','zip','exe','cfg']): 
41            pth1 = pth + 'index.html'
42        else:
43            pth = '/'.join(pth.split('/')[:-1])
44        if not os.path.exists(pth1):
45            webmirror(pth,1,self.index_url+path,0,1)
46        elif int(time()) - os.path.getmtime(pth1) > 3600:
47            webmirror(pth,1,self.index_url+path,0,1)
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)
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):
79                start_response('200 OK', [('Content-Type', 'text/html')])
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
108        names = [i for i in os.listdir(path) if not i.startswith('.')]
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
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)
144"""
Note: See TracBrowser for help on using the repository browser.