Mercurial > mozilla > hg > dogfood
annotate dogdish/dispatcher.py @ 13:71f9f68986b5
directory scanning + caching
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Wed, 17 Oct 2012 10:56:38 -0700 |
parents | 234c2427e52b |
children | cffb6f681b59 |
rev | line source |
---|---|
1 | 1 #!/usr/bin/env python |
2 | |
0 | 3 """ |
1 | 4 dogdish |
7
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
5 https://bugzilla.mozilla.org/show_bug.cgi?id=800118 |
0 | 6 """ |
7 | |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
8 import fnmatch |
8 | 9 import os |
4 | 10 import sys |
0 | 11 from urlparse import urlparse |
4 | 12 from webob import Request |
0 | 13 from webob import Response, exc |
11 | 14 from ConfigParser import RawConfigParser as ConfigParser |
0 | 15 |
8 | 16 here = os.path.dirname(os.path.abspath(__file__)) |
17 | |
11 | 18 |
19 class Application(object): | |
20 """class for storing application.ini data""" | |
21 | |
22 def __init__(self, filename): | |
23 """ | |
24 - filename : path to an application.ini file | |
25 """ | |
26 | |
27 ### request handlers | |
28 | |
0 | 29 class Handler(object): |
9 | 30 """abstract handler object for a request""" |
1 | 31 |
0 | 32 def __init__(self, request): |
33 self.request = request | |
34 self.application_path = urlparse(request.application_url)[2] | |
35 | |
36 def link(self, path=(), permanant=False): | |
37 if isinstance(path, basestring): | |
38 path = [ path ] | |
39 path = [ i.strip('/') for i in path ] | |
40 if permanant: | |
41 application_url = [ self.request.application_url ] | |
42 else: | |
43 application_url = [ self.application_path ] | |
44 path = application_url + path | |
45 return '/'.join(path) | |
46 | |
47 def redirect(self, location): | |
48 raise exc.HTTPSeeOther(location=location) | |
49 | |
50 class Get(Handler): | |
9 | 51 """handle GET requests""" |
0 | 52 |
9 | 53 # template for response body |
0 | 54 body = """<?xml version="1.0"?> |
55 <updates> | |
56 <update type="minor" appVersion="19.0a1" version="19.0a1" extensionVersion="19.0a1" buildID="20121010114416" licenseURL="http://www.mozilla.com/test/sample-eula.html" detailsURL="http://www.mozilla.com/test/sample-details.html"> | |
9 | 57 <patch type="complete" URL="http://update.boot2gecko.org/nightly/b2g_update_2012-10-10_114416.mar%(query)s" hashFunction="SHA512" hashValue="84edb1f53891cf983bc0f6066d31492f43e2d063aaceb05e1c51876f4fde81635afeb7ce3203dee6f65dd59be0cae5c73c49093b625c99acd4118000ad72dda8" size="42924805"/> |
0 | 58 </update> |
59 </updates>""" | |
60 | |
9 | 61 ### methods for request handler |
62 | |
0 | 63 @classmethod |
64 def match(cls, request): | |
65 return request.method == 'GET' | |
66 | |
67 def __call__(self): | |
7
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
68 body = self.body |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
69 query = {} |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
70 dogfood_id = self.request.GET.get('dogfood_id') |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
71 if dogfood_id: |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
72 query['dogfooding_prerelease_id'] = dogfood_id |
7
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
73 |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
74 # build query string |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
75 if query: |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
76 query = '?' + '&'.join(['%s=%s' % (key, value) for key, value in query.items()]) |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
77 else: |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
78 query = '' |
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
79 |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
80 # template variables |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
81 variables = dict(query=query) |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
82 |
1 | 83 return Response(content_type='text/xml', |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
84 body=body % variables) |
0 | 85 |
86 class Dispatcher(object): | |
9 | 87 """web application""" |
88 | |
0 | 89 |
90 ### class level variables | |
8 | 91 defaults = {'directory': here} |
0 | 92 |
93 def __init__(self, **kw): | |
11 | 94 |
95 # set defaults | |
0 | 96 for key in self.defaults: |
97 setattr(self, key, kw.get(key, self.defaults[key])) | |
98 self.handlers = [ Get ] | |
11 | 99 self.updates = {} |
100 self.current_update = None | |
13
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
101 self.current_stamp = '0000-00-00_000000' |
0 | 102 |
11 | 103 # scan directory |
104 self.scan() | |
105 | |
0 | 106 def __call__(self, environ, start_response): |
11 | 107 """WSGI application""" |
108 | |
0 | 109 request = Request(environ) |
110 for h in self.handlers: | |
111 if h.match(request): | |
112 handler = h(request) | |
113 break | |
114 else: | |
115 handler = exc.HTTPNotFound | |
116 res = handler() | |
117 return res(environ, start_response) | |
118 | |
11 | 119 def scan(self): |
120 """scan the directory for updates""" | |
13
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
121 prefix = 'b2g_update_' |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
122 suffix = '.mar' |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
123 contents = [i for i in os.listdir(self.directory) |
13
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
124 if i.startswith(prefix) and i.endswith(suffix)] |
12
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
125 contents = set(contents) |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
126 new = contents.difference(self.updates.keys()) |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
127 if not new: |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
128 # directory contents unchanged from cached values |
234c2427e52b
beginnings of a scan function
Jeff Hammel <jhammel@mozilla.com>
parents:
11
diff
changeset
|
129 return |
11 | 130 |
13
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
131 for update in new: |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
132 stamp = update[len(prefix):-len(suffix)] |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
133 application_ini = 'application_%s.ini' % stamp |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
134 application_ini = os.path.join(self.directory, application_ini) |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
135 assert os.path.exists(application_ini) |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
136 self.updates[update] = Application(application_ini) |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
137 if stamp > self.current_stamp: |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
138 self.current_update = update |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
139 self.current_stamp = stamp |
71f9f68986b5
directory scanning + caching
Jeff Hammel <jhammel@mozilla.com>
parents:
12
diff
changeset
|
140 |
0 | 141 def main(args=sys.argv[1:]): |
142 """CLI entry point""" | |
143 | |
11 | 144 # imports for CLI |
0 | 145 import optparse |
146 from wsgiref import simple_server | |
147 | |
11 | 148 # parse CLI options |
0 | 149 parser = optparse.OptionParser() |
150 parser.add_option('-p', '--port', dest='port', | |
151 default=8080, type='int', | |
152 help="port to serve on") | |
11 | 153 parser.add_option('-d', '--directory', dest='directory', |
154 default=os.getcwd(), | |
155 help="directory of update files") | |
0 | 156 options, args = parser.parse_args() |
157 | |
11 | 158 # create the app |
159 app = Dispatcher(directory=options.directory) | |
0 | 160 |
11 | 161 # serve the app |
7
65d0a1153864
a stub that sorta does something
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
162 print "http://localhost:%s/" % options.port |
0 | 163 server = simple_server.make_server(host='0.0.0.0', port=options.port, app=app) |
164 server.serve_forever() | |
165 | |
166 if __name__ == '__main__': | |
167 main() |