116 req = wsgirequest(env, respond) |
116 req = wsgirequest(env, respond) |
117 self.run_wsgi(req) |
117 self.run_wsgi(req) |
118 return req |
118 return req |
119 |
119 |
120 def run_wsgi(self, req): |
120 def run_wsgi(self, req): |
121 def header(**map): |
121 |
122 header_file = cStringIO.StringIO( |
122 self.refresh() |
123 ''.join(self.t("header", encoding=self.encoding, **map))) |
123 |
124 msg = mimetools.Message(header_file, 0) |
124 # expand form shortcuts |
125 req.header(msg.items()) |
125 |
126 yield header_file.read() |
126 shortcuts = { |
127 |
127 'cl': [('cmd', ['changelog']), ('rev', None)], |
128 def rawfileheader(**map): |
128 'sl': [('cmd', ['shortlog']), ('rev', None)], |
129 req.header([('Content-type', map['mimetype']), |
129 'cs': [('cmd', ['changeset']), ('node', None)], |
130 ('Content-disposition', 'filename=%s' % map['file']), |
130 'f': [('cmd', ['file']), ('filenode', None)], |
131 ('Content-length', str(len(map['raw'])))]) |
131 'fl': [('cmd', ['filelog']), ('filenode', None)], |
132 yield '' |
132 'fd': [('cmd', ['filediff']), ('node', None)], |
133 |
133 'fa': [('cmd', ['annotate']), ('filenode', None)], |
134 def footer(**map): |
134 'mf': [('cmd', ['manifest']), ('manifest', None)], |
135 yield self.t("footer", **map) |
135 'ca': [('cmd', ['archive']), ('node', None)], |
136 |
136 'tags': [('cmd', ['tags'])], |
137 def motd(**map): |
137 'tip': [('cmd', ['changeset']), ('node', ['tip'])], |
138 yield self.config("web", "motd", "") |
138 'static': [('cmd', ['static']), ('file', None)] |
139 |
139 } |
140 def expand_form(form): |
140 |
141 shortcuts = { |
141 for k in shortcuts.iterkeys(): |
142 'cl': [('cmd', ['changelog']), ('rev', None)], |
142 if k in req.form: |
143 'sl': [('cmd', ['shortlog']), ('rev', None)], |
143 for name, value in shortcuts[k]: |
144 'cs': [('cmd', ['changeset']), ('node', None)], |
144 if value is None: |
145 'f': [('cmd', ['file']), ('filenode', None)], |
145 value = req.form[k] |
146 'fl': [('cmd', ['filelog']), ('filenode', None)], |
146 req.form[name] = value |
147 'fd': [('cmd', ['filediff']), ('node', None)], |
147 del req.form[k] |
148 'fa': [('cmd', ['annotate']), ('filenode', None)], |
148 |
149 'mf': [('cmd', ['manifest']), ('manifest', None)], |
149 # work with CGI variables to create coherent structure |
150 'ca': [('cmd', ['archive']), ('node', None)], |
150 # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME |
151 'tags': [('cmd', ['tags'])], |
151 |
152 'tip': [('cmd', ['changeset']), ('node', ['tip'])], |
152 req.url = req.env['SCRIPT_NAME'] |
153 'static': [('cmd', ['static']), ('file', None)] |
153 if not req.url.endswith('/'): |
154 } |
154 req.url += '/' |
155 |
155 if req.env.has_key('REPO_NAME'): |
156 for k in shortcuts.iterkeys(): |
156 req.url += req.env['REPO_NAME'] + '/' |
157 if form.has_key(k): |
157 |
158 for name, value in shortcuts[k]: |
158 if req.env.get('PATH_INFO'): |
159 if value is None: |
159 parts = req.env.get('PATH_INFO').strip('/').split('/') |
160 value = form[k] |
160 repo_parts = req.env.get('REPO_NAME', '').split('/') |
161 form[name] = value |
161 if parts[:len(repo_parts)] == repo_parts: |
162 del form[k] |
162 parts = parts[len(repo_parts):] |
163 |
163 query = '/'.join(parts) |
164 def rewrite_request(req): |
164 else: |
165 '''translate new web interface to traditional format''' |
165 query = req.env['QUERY_STRING'].split('&', 1)[0] |
166 |
166 query = query.split(';', 1)[0] |
167 req.url = req.env['SCRIPT_NAME'] |
167 |
168 if not req.url.endswith('/'): |
168 # translate user-visible url structure to internal structure |
169 req.url += '/' |
169 |
170 if req.env.has_key('REPO_NAME'): |
170 args = query.split('/', 2) |
171 req.url += req.env['REPO_NAME'] + '/' |
171 if 'cmd' not in req.form and args and args[0]: |
172 |
|
173 if req.env.get('PATH_INFO'): |
|
174 parts = req.env.get('PATH_INFO').strip('/').split('/') |
|
175 repo_parts = req.env.get('REPO_NAME', '').split('/') |
|
176 if parts[:len(repo_parts)] == repo_parts: |
|
177 parts = parts[len(repo_parts):] |
|
178 query = '/'.join(parts) |
|
179 else: |
|
180 query = req.env['QUERY_STRING'].split('&', 1)[0] |
|
181 query = query.split(';', 1)[0] |
|
182 |
|
183 if req.form.has_key('cmd'): |
|
184 # old style |
|
185 return |
|
186 |
|
187 args = query.split('/', 2) |
|
188 if not args or not args[0]: |
|
189 return |
|
190 |
172 |
191 cmd = args.pop(0) |
173 cmd = args.pop(0) |
192 style = cmd.rfind('-') |
174 style = cmd.rfind('-') |
193 if style != -1: |
175 if style != -1: |
194 req.form['style'] = [cmd[:style]] |
176 req.form['style'] = [cmd[:style]] |
195 cmd = cmd[style+1:] |
177 cmd = cmd[style+1:] |
|
178 |
196 # avoid accepting e.g. style parameter as command |
179 # avoid accepting e.g. style parameter as command |
197 if hasattr(webcommands, cmd): |
180 if hasattr(webcommands, cmd): |
198 req.form['cmd'] = [cmd] |
181 req.form['cmd'] = [cmd] |
199 |
182 |
200 if args and args[0]: |
183 if args and args[0]: |
247 port = port != default_port and (":" + port) or "" |
211 port = port != default_port and (":" + port) or "" |
248 urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port) |
212 urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port) |
249 staticurl = self.config("web", "staticurl") or req.url + 'static/' |
213 staticurl = self.config("web", "staticurl") or req.url + 'static/' |
250 if not staticurl.endswith('/'): |
214 if not staticurl.endswith('/'): |
251 staticurl += '/' |
215 staticurl += '/' |
|
216 |
|
217 # some functions for the templater |
|
218 |
|
219 def header(**map): |
|
220 header_file = cStringIO.StringIO( |
|
221 ''.join(self.t("header", encoding=self.encoding, **map))) |
|
222 msg = mimetools.Message(header_file, 0) |
|
223 req.header(msg.items()) |
|
224 yield header_file.read() |
|
225 |
|
226 def rawfileheader(**map): |
|
227 req.header([('Content-type', map['mimetype']), |
|
228 ('Content-disposition', 'filename=%s' % map['file']), |
|
229 ('Content-length', str(len(map['raw'])))]) |
|
230 yield '' |
|
231 |
|
232 def footer(**map): |
|
233 yield self.t("footer", **map) |
|
234 |
|
235 def motd(**map): |
|
236 yield self.config("web", "motd", "") |
|
237 |
|
238 def sessionvars(**map): |
|
239 fields = [] |
|
240 if req.form.has_key('style'): |
|
241 style = req.form['style'][0] |
|
242 if style != self.config('web', 'style', ''): |
|
243 fields.append(('style', style)) |
|
244 |
|
245 separator = req.url[-1] == '?' and ';' or '?' |
|
246 for name, value in fields: |
|
247 yield dict(name=name, value=value, separator=separator) |
|
248 separator = ';' |
|
249 |
|
250 style = self.config("web", "style", "") |
|
251 if req.form.has_key('style'): |
|
252 style = req.form['style'][0] |
|
253 mapfile = style_map(self.templatepath, style) |
252 |
254 |
253 if not self.reponame: |
255 if not self.reponame: |
254 self.reponame = (self.config("web", "name") |
256 self.reponame = (self.config("web", "name") |
255 or req.env.get('REPO_NAME') |
257 or req.env.get('REPO_NAME') |
256 or req.url.strip('/') or self.repo.root) |
258 or req.url.strip('/') or self.repo.root) |