18 def __init__(self, config, parentui=None): |
18 def __init__(self, config, parentui=None): |
19 def cleannames(items): |
19 def cleannames(items): |
20 return [(util.pconvert(name).strip('/'), path) |
20 return [(util.pconvert(name).strip('/'), path) |
21 for name, path in items] |
21 for name, path in items] |
22 |
22 |
23 self.parentui = parentui |
23 self.parentui = parentui or ui.ui(report_untrusted=False, |
|
24 interactive = False) |
24 self.motd = None |
25 self.motd = None |
25 self.style = None |
26 self.style = None |
26 self.stripecount = None |
27 self.stripecount = None |
27 self.repos_sorted = ('name', False) |
28 self.repos_sorted = ('name', False) |
28 if isinstance(config, (list, tuple)): |
29 if isinstance(config, (list, tuple)): |
83 if self.motd is not None: |
84 if self.motd is not None: |
84 yield self.motd |
85 yield self.motd |
85 else: |
86 else: |
86 yield config('web', 'motd', '') |
87 yield config('web', 'motd', '') |
87 |
88 |
88 parentui = self.parentui or ui.ui(report_untrusted=False, |
|
89 interactive=False) |
|
90 |
|
91 def config(section, name, default=None, untrusted=True): |
89 def config(section, name, default=None, untrusted=True): |
92 return parentui.config(section, name, default, untrusted) |
90 return self.parentui.config(section, name, default, untrusted) |
93 |
91 |
94 url = req.env.get('SCRIPT_NAME', '') |
92 url = req.env.get('SCRIPT_NAME', '') |
95 if not url.endswith('/'): |
93 if not url.endswith('/'): |
96 url += '/' |
94 url += '/' |
97 |
95 |
112 "footer": footer, |
110 "footer": footer, |
113 "motd": motd, |
111 "motd": motd, |
114 "url": url, |
112 "url": url, |
115 "staticurl": staticurl}) |
113 "staticurl": staticurl}) |
116 |
114 |
|
115 try: |
|
116 try: |
|
117 virtual = req.env.get("PATH_INFO", "").strip('/') |
|
118 if virtual.startswith('static/'): |
|
119 static = os.path.join(templater.templatepath(), 'static') |
|
120 fname = virtual[7:] |
|
121 req.write(staticfile(static, fname, req)) |
|
122 elif virtual: |
|
123 repos = dict(self.repos) |
|
124 while virtual: |
|
125 real = repos.get(virtual) |
|
126 if real: |
|
127 req.env['REPO_NAME'] = virtual |
|
128 try: |
|
129 repo = hg.repository(self.parentui, real) |
|
130 hgweb(repo).run_wsgi(req) |
|
131 return |
|
132 except IOError, inst: |
|
133 raise ErrorResponse(500, inst.strerror) |
|
134 except hg.RepoError, inst: |
|
135 raise ErrorResponse(500, str(inst)) |
|
136 |
|
137 # browse subdirectories |
|
138 subdir = virtual + '/' |
|
139 if [r for r in repos if r.startswith(subdir)]: |
|
140 self.makeindex(req, tmpl, subdir) |
|
141 return |
|
142 |
|
143 up = virtual.rfind('/') |
|
144 if up < 0: |
|
145 break |
|
146 virtual = virtual[:up] |
|
147 |
|
148 req.respond(404, tmpl("notfound", repo=virtual)) |
|
149 else: |
|
150 if req.form.has_key('static'): |
|
151 static = os.path.join(templater.templatepath(), "static") |
|
152 fname = req.form['static'][0] |
|
153 req.write(staticfile(static, fname, req)) |
|
154 else: |
|
155 self.makeindex(req, tmpl) |
|
156 except ErrorResponse, err: |
|
157 req.respond(err.code, tmpl('error', error=err.message or '')) |
|
158 finally: |
|
159 tmpl = None |
|
160 |
|
161 def makeindex(self, req, tmpl, subdir=""): |
|
162 |
117 def archivelist(ui, nodeid, url): |
163 def archivelist(ui, nodeid, url): |
118 allowed = ui.configlist("web", "allow_archive", untrusted=True) |
164 allowed = ui.configlist("web", "allow_archive", untrusted=True) |
119 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]: |
165 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]: |
120 if i[0] in allowed or ui.configbool("web", "allow" + i[0], |
166 if i[0] in allowed or ui.configbool("web", "allow" + i[0], |
121 untrusted=True): |
167 untrusted=True): |
140 for name, path in self.repos: |
186 for name, path in self.repos: |
141 if not name.startswith(subdir): |
187 if not name.startswith(subdir): |
142 continue |
188 continue |
143 name = name[len(subdir):] |
189 name = name[len(subdir):] |
144 |
190 |
145 u = ui.ui(parentui=parentui) |
191 u = ui.ui(parentui=self.parentui) |
146 try: |
192 try: |
147 u.readconfig(os.path.join(path, '.hg', 'hgrc')) |
193 u.readconfig(os.path.join(path, '.hg', 'hgrc')) |
148 except Exception, e: |
194 except Exception, e: |
149 u.warn(_('error reading %s/.hg/hgrc: %s\n' % (path, e))) |
195 u.warn(_('error reading %s/.hg/hgrc: %s\n' % (path, e))) |
150 continue |
196 continue |
194 rows.reverse() |
240 rows.reverse() |
195 for key, row in rows: |
241 for key, row in rows: |
196 row['parity'] = parity.next() |
242 row['parity'] = parity.next() |
197 yield row |
243 yield row |
198 |
244 |
199 def makeindex(req, subdir=""): |
245 sortable = ["name", "description", "contact", "lastchange"] |
200 sortable = ["name", "description", "contact", "lastchange"] |
246 sortcolumn, descending = self.repos_sorted |
201 sortcolumn, descending = self.repos_sorted |
247 if req.form.has_key('sort'): |
202 if req.form.has_key('sort'): |
248 sortcolumn = req.form['sort'][0] |
203 sortcolumn = req.form['sort'][0] |
249 descending = sortcolumn.startswith('-') |
204 descending = sortcolumn.startswith('-') |
250 if descending: |
205 if descending: |
251 sortcolumn = sortcolumn[1:] |
206 sortcolumn = sortcolumn[1:] |
252 if sortcolumn not in sortable: |
207 if sortcolumn not in sortable: |
253 sortcolumn = "" |
208 sortcolumn = "" |
254 |
209 |
255 sort = [("sort_%s" % column, |
210 sort = [("sort_%s" % column, |
256 "%s%s" % ((not descending and column == sortcolumn) |
211 "%s%s" % ((not descending and column == sortcolumn) |
257 and "-" or "", column)) |
212 and "-" or "", column)) |
258 for column in sortable] |
213 for column in sortable] |
259 req.write(tmpl("index", entries=entries, subdir=subdir, |
214 req.write(tmpl("index", entries=entries, subdir=subdir, |
260 sortcolumn=sortcolumn, descending=descending, |
215 sortcolumn=sortcolumn, descending=descending, |
261 **dict(sort))) |
216 **dict(sort))) |
|
217 |
|
218 try: |
|
219 try: |
|
220 virtual = req.env.get("PATH_INFO", "").strip('/') |
|
221 if virtual.startswith('static/'): |
|
222 static = os.path.join(templater.templatepath(), 'static') |
|
223 fname = virtual[7:] |
|
224 req.write(staticfile(static, fname, req)) |
|
225 elif virtual: |
|
226 repos = dict(self.repos) |
|
227 while virtual: |
|
228 real = repos.get(virtual) |
|
229 if real: |
|
230 req.env['REPO_NAME'] = virtual |
|
231 try: |
|
232 repo = hg.repository(parentui, real) |
|
233 hgweb(repo).run_wsgi(req) |
|
234 return |
|
235 except IOError, inst: |
|
236 raise ErrorResponse(500, inst.strerror) |
|
237 except hg.RepoError, inst: |
|
238 raise ErrorResponse(500, str(inst)) |
|
239 |
|
240 # browse subdirectories |
|
241 subdir = virtual + '/' |
|
242 if [r for r in repos if r.startswith(subdir)]: |
|
243 makeindex(req, subdir) |
|
244 return |
|
245 |
|
246 up = virtual.rfind('/') |
|
247 if up < 0: |
|
248 break |
|
249 virtual = virtual[:up] |
|
250 |
|
251 req.respond(404, tmpl("notfound", repo=virtual)) |
|
252 else: |
|
253 if req.form.has_key('static'): |
|
254 static = os.path.join(templater.templatepath(), "static") |
|
255 fname = req.form['static'][0] |
|
256 req.write(staticfile(static, fname, req)) |
|
257 else: |
|
258 makeindex(req) |
|
259 except ErrorResponse, err: |
|
260 req.respond(err.code, tmpl('error', error=err.message or '')) |
|
261 finally: |
|
262 tmpl = None |
|