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

Last change on this file since 1260 was 1260, checked in by crchemist, 15 years ago

added cfg to known file extensions

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