def run_wsgi(self, req): try: try: #log.debug("Inside HgRedmine::run_wsgi : " + str(req.env)) db = connect(self.dsn) self.refresh() self.findrepos(db) virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) ctype = templater.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] static = templater.templatepath('static') return (staticfile(static, fname, req),) self._user_login(db, req) # top-level index #if not virtual: ## only administrators can list repositories #if self._is_admin(req): #req.respond(HTTP_OK, ctype) #return self.makeindex(req, tmpl) #else: #self._send_challenge(req) # navigate to hgweb project_id = virtual.split('/')[0] repos = dict(self.repos) real = repos.get(project_id) if real: req.env['REPO_NAME'] = project_id try: repo = hg.repository(self.ui.copy(), str(real)) self._setup_repo(db, repo, project_id) #log.debug("Calling HgWebRedmine with " + str(self.realm) + str(repo)) return HgwebRedmine(db, self.realm, repo).run_wsgi(req) except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except error.RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def clean_style(self): """ Checks the style to see if a path is returned by mercurial's templater. If no path is returned then the style is assumed to be invalid or not installed. """ from mercurial.templater import templatepath if not templatepath(self.cleaned_data["style"]): raise forms.ValidationError(_("'%s' is not an available style." % self.cleaned_data["style"])) return self.cleaned_data["style"]
def static(web, req, tmpl): fname = req.form['file'][0] # a repo owner may set web.static in .hg/hgrc to get any file # readable by the user running the CGI script static = web.config("web", "static", None, untrusted=False) if not static: tp = web.templatepath or templater.templatepath() if isinstance(tp, str): tp = [tp] static = [os.path.join(p, 'static') for p in tp] return [staticfile(static, fname, req)]
def static_file(request, file_name): # Handle static files static = templater.templatepath('static') response = HttpResponse() url = request.path req = HgRequestWrapper( request, response, script_name=url, ) response.write(''.join([each for each in (common.staticfile(static, file_name, req))])) return response
def run_wsgi(self, req): try: try: virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) try: ctype = tmpl('mimetype', encoding=util._encoding) ctype = templater.stringify(ctype) except KeyError: # old templates with inline HTTP headers? if 'mimetype' in tmpl: raise header = tmpl('header', encoding=util._encoding) header_file = cStringIO.StringIO( templater.stringify(header)) msg = mimetools.Message(header_file, 0) ctype = msg['content-type'] # a static file if virtual.startswith('static/') or 'static' in req.form: static = os.path.join(templater.templatepath(), 'static') if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] req.write(staticfile(static, fname, req)) return # top-level index elif not virtual: req.respond(HTTP_OK, ctype) req.write(self.makeindex(req, tmpl)) return # nested indexes and hgwebs repos = dict(self.repos) while virtual: real = repos.get(virtual) if real: req.env['REPO_NAME'] = virtual try: repo = hg.repository(self.parentui, real) hgweb(repo).run_wsgi(req) return except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def templater(self, req): def header(**map): header = tmpl('header', encoding=util._encoding, **map) if 'mimetype' not in tmpl: # old template with inline HTTP headers header_file = cStringIO.StringIO(templater.stringify(header)) msg = mimetools.Message(header_file, 0) header = header_file.read() yield header def footer(**map): yield tmpl("footer", **map) def motd(**map): if self.motd is not None: yield self.motd else: yield config('web', 'motd', '') def config(section, name, default=None, untrusted=True): return self.parentui.config(section, name, default, untrusted) if self._baseurl is not None: req.env['SCRIPT_NAME'] = self._baseurl url = req.env.get('SCRIPT_NAME', '') if not url.endswith('/'): url += '/' staticurl = config('web', 'staticurl') or url + 'static/' if not staticurl.endswith('/'): staticurl += '/' style = self.style if style is None: style = config('web', 'style', '') if 'style' in req.form: style = req.form['style'][0] if self.stripecount is None: self.stripecount = int(config('web', 'stripes', 1)) mapfile = style_map(templater.templatepath(), style) tmpl = templater.templater(mapfile, templatefilters.filters, defaults={ "header": header, "footer": footer, "motd": motd, "url": url, "staticurl": staticurl }) return tmpl
def run_wsgi(self, req): try: try: virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) try: ctype = tmpl('mimetype', encoding=util._encoding) ctype = templater.stringify(ctype) except KeyError: # old templates with inline HTTP headers? if 'mimetype' in tmpl: raise header = tmpl('header', encoding=util._encoding) header_file = cStringIO.StringIO(templater.stringify(header)) msg = mimetools.Message(header_file, 0) ctype = msg['content-type'] # a static file if virtual.startswith('static/') or 'static' in req.form: static = os.path.join(templater.templatepath(), 'static') if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] req.write(staticfile(static, fname, req)) return # top-level index elif not virtual: req.respond(HTTP_OK, ctype) req.write(self.makeindex(req, tmpl)) return # nested indexes and hgwebs repos = dict(self.repos) while virtual: real = repos.get(virtual) if real: req.env['REPO_NAME'] = virtual try: repo = hg.repository(self.parentui, real) hgweb(repo).run_wsgi(req) return except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def run_wsgi(self, req): try: try: self.refresh() virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) ctype = templater.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] static = self.ui.config("web", "static", None, untrusted=False) if not static: tp = self.templatepath or templater.templatepath() if isinstance(tp, str): tp = [tp] static = [os.path.join(p, 'static') for p in tp] staticfile(static, fname, req) return [] # top-level index elif not virtual: req.respond(HTTP_OK, ctype) return self.makeindex(req, tmpl) # nested indexes and hgwebs repos = dict(self.repos) virtualrepo = virtual while virtualrepo: real = repos.get(virtualrepo) if real: req.env['REPO_NAME'] = virtualrepo try: # ensure caller gets private copy of ui repo = hg.repository(self.ui.copy(), real) return hgweb(repo).run_wsgi(req) except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except error.RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def templater(self, req): def header(**map): header = tmpl('header', encoding=util._encoding, **map) if 'mimetype' not in tmpl: # old template with inline HTTP headers header_file = cStringIO.StringIO(templater.stringify(header)) msg = mimetools.Message(header_file, 0) header = header_file.read() yield header def footer(**map): yield tmpl("footer", **map) def motd(**map): if self.motd is not None: yield self.motd else: yield config('web', 'motd', '') def config(section, name, default=None, untrusted=True): return self.parentui.config(section, name, default, untrusted) if self._baseurl is not None: req.env['SCRIPT_NAME'] = self._baseurl url = req.env.get('SCRIPT_NAME', '') if not url.endswith('/'): url += '/' staticurl = config('web', 'staticurl') or url + 'static/' if not staticurl.endswith('/'): staticurl += '/' style = self.style if style is None: style = config('web', 'style', '') if 'style' in req.form: style = req.form['style'][0] if self.stripecount is None: self.stripecount = int(config('web', 'stripes', 1)) mapfile = style_map(templater.templatepath(), style) tmpl = templater.templater(mapfile, templatefilters.filters, defaults={"header": header, "footer": footer, "motd": motd, "url": url, "staticurl": staticurl}) return tmpl
def run_wsgi(self, req): try: try: db, self.placeholder = connect(self.dsn) self.refresh() self.findrepos(db) virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) ctype = templater.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] static = templater.templatepath('static') return (staticfile(static, fname, req),) self._user_login(db, req) # top-level index if not virtual: # nobody can list repositories self._send_challenge(req) # navigate to hgweb repository_path = '/'.join(virtual.split('/')[0:2]) repos = dict(self.repos) real = repos.get(repository_path) if real: req.env['REPO_NAME'] = repository_path req.env['PROJECT_ID'], req.env['PROJECT_OWNER_ID'] = self._project_info_from_repo_path(db, repository_path) try: repo = hg.repository(self.ui, real) self._setup_repo(db, repo, repository_path) return HgwebWide(db, self.placeholder, self.realm, repo).run_wsgi(req) except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except error.RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def __init__(self, repo, name=None): if isinstance(repo, str): parentui = ui.ui(report_untrusted=False, interactive=False) self.repo = hg.repository(parentui, repo) else: self.repo = repo hook.redirect(True) self.mtime = -1 self.reponame = name self.archives = 'zip', 'gz', 'bz2' self.stripecount = 1 # a repo owner may set web.templates in .hg/hgrc to get any file # readable by the user running the CGI script self.templatepath = self.config("web", "templates", templater.templatepath(), untrusted=False)
def __init__(self, repo, name=None): if isinstance(repo, str): parentui = ui.ui(report_untrusted=False, interactive=False) self.repo = hg.repository(parentui, repo) else: self.repo = repo hook.redirect(True) self.mtime = -1 self.reponame = name self.archives = 'zip', 'gz', 'bz2' self.stripecount = 1 self._capabilities = None # a repo owner may set web.templates in .hg/hgrc to get any file # readable by the user running the CGI script self.templatepath = self.config("web", "templates", templater.templatepath(), untrusted=False)
def run_wsgi(self, req): try: try: self.refresh() virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) ctype = templater.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] static = templater.templatepath('static') return (staticfile(static, fname, req), ) # top-level index elif not virtual: req.respond(HTTP_OK, ctype) return self.makeindex(req, tmpl) # nested indexes and hgwebs repos = dict(self.repos) virtualrepo = virtual while virtualrepo: real = repos.get(virtualrepo) if real: req.env['REPO_NAME'] = virtualrepo try: repo = hg.repository(self.ui, real) return hgweb(repo).run_wsgi(req) except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except error.RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def run_wsgi(self, req): try: try: self.refresh() virtual = req.env.get("PATH_INFO", "").strip('/') tmpl = self.templater(req) ctype = tmpl('mimetype', encoding=encoding.encoding) ctype = templater.stringify(ctype) # a static file if virtual.startswith('static/') or 'static' in req.form: if virtual.startswith('static/'): fname = virtual[7:] else: fname = req.form['static'][0] static = templater.templatepath('static') return (staticfile(static, fname, req),) # top-level index elif not virtual: req.respond(HTTP_OK, ctype) return self.makeindex(req, tmpl) # nested indexes and hgwebs repos = dict(self.repos) virtualrepo = virtual while virtualrepo: real = repos.get(virtualrepo) if real: req.env['REPO_NAME'] = virtualrepo try: repo = hg.repository(self.ui, real) return hgweb(repo).run_wsgi(req) except IOError, inst: msg = inst.strerror raise ErrorResponse(HTTP_SERVER_ERROR, msg) except error.RepoError, inst: raise ErrorResponse(HTTP_SERVER_ERROR, str(inst))
def templater(self): def header(**map): yield tmpl('header', encoding=util._encoding, **map) def footer(**map): yield tmpl("footer", **map) def motd(**map): if self.motd is not None: yield self.motd else: yield config('web', 'motd', '') def config(section, name, default=None, untrusted=True): return self.parentui.config(section, name, default, untrusted) url = self._baseurl if not url.endswith('/'): url += '/' staticurl = url + 'static/' style = self.style if style is None: style = config('web', 'style', '') style = self.request.get("style", style) if self.stripecount is None: self.stripecount = int(config('web', 'stripes', 1)) mapfile = style_map(templater.templatepath(), style) tmpl = templater.templater(mapfile, templatefilters.filters, defaults={"header": header, "footer": footer, "motd": motd, "url": url, "staticurl": staticurl}) return tmpl
def repo_detail(request, username, pattern): """ Repository detail view. """ repo_name = pattern.split('/')[0] repo = get_object_or_404(Repository, slug=repo_name, owner__username=username) """ Instance the hgweb wrapper """ response = HttpResponse() hgr = HgRequestWrapper(request, response, script_name=repo.get_absolute_url()) """ Authenticate on all requests. To authenticate only against 'POST' requests """ realm = hgwebproxy_settings.AUTH_REALM mercurial_request = is_mercurial(request) if mercurial_request: """ If a slash is not present, would be added a slash regardless of APPEND_SLASH django setting since hgweb returns 404 if it isn't present. """ if not request.path.endswith('/'): new_url = [request.get_host(), request.path + '/'] if new_url[0]: newurl = "%s://%s%s" % ( request.is_secure() and 'https' or 'http', new_url[0], urlquote(new_url[1])) else: newurl = urlquote(new_url[1]) if request.GET: newurl += '?' + request.META['QUERY_STRING'] return HttpResponseRedirect(newurl) authed = basic_auth(request, realm, repo) else: if not repo.can_browse(request.user): raise PermissionDenied(_("You do not have access to this repository")) authed = request.user.username if not authed: response.status_code = 401 response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm if request.META['REQUEST_METHOD']=='POST' and request.META['QUERY_STRING'].startswith("cmd=unbundle"): # drain request, this is a fix/workaround for http://mercurial.selenic.com/btw/issue1876 hgr.drain() return response else: hgr.set_user(authed) hgserve = hgweb(str(repo.location)) hgserve.reponame = repo.slug # TODO: is it Possible to charge the settings just for one time? hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame)) hgserve.repo.ui.setconfig('web', 'description', smart_str(repo.description)) hgserve.repo.ui.setconfig('web', 'contact', smart_str(repo.owner.get_full_name())) hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive) if os.path.exists(hgwebproxy_settings.STYLES_PATH): template_paths = templater.templatepath() template_paths.insert(0, hgwebproxy_settings.STYLES_PATH) hgserve.repo.ui.setconfig('web', 'templates', template_paths) hgserve.templatepath = hgserve.repo.ui.config('web', 'templates', template_paths) if hgwebproxy_settings.ALLOW_CUSTOM_STYLE: hgserve.repo.ui.setconfig('web', 'style', repo.style) else: hgserve.repo.ui.setconfig('web', 'style', hgwebproxy_settings.DEFAULT_STYLE) hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url()) hgserve.repo.ui.setconfig('web', 'allow_push', authed) #Allow push to the current user hgserve.repo.ui.setconfig('web', 'staticurl', hgwebproxy_settings.STATIC_URL) if settings.DEBUG: hgserve.repo.ui.setconfig('web', 'push_ssl', 'false') else: hgserve.repo.ui.setconfig('web', 'push_ssl', repo.allow_push_ssl) # Catch hgweb error to show as Django Exceptions try: response.write(''.join(each for each in hgserve.run_wsgi(hgr))) except KeyError: return HttpResponseServerError('Mercurial has crashed', mimetype='text/html') if mercurial_request: return response # make sure we return the response without wrapping if content-type is # either a binary stream or text/plain (for raw changesets). if response['content-type'].split(';')[0] in ('application/octet-stream', 'text/plain'): return response context = { 'content': response.content, 'reponame' : hgserve.reponame, 'static_url' : hgwebproxy_settings.STATIC_URL, 'slugpath': request.path.replace(repo.get_absolute_url(), ''), 'is_root': request.path == repo.get_absolute_url(), 'repo': repo, } if request.path.endswith(repo_name + '/rss-log') or request.path.endswith(repo_name + '/atom-log'): return HttpResponse(response.content, mimetype='application/xml') else: return render_to_response("hgwebproxy/wrapper.html", context, RequestContext(request))
def is_template(template): #TODO: Load project mercurial styles if templatepath(template): return True else: return False
def repo_detail(request, username, pattern): """ Repository detail view. """ repo_name = pattern.split('/')[0] repo = get_object_or_404(Repository, slug=repo_name, owner__username=username) """ Instance the hgweb wrapper """ response = HttpResponse() hgr = HgRequestWrapper(request, response, script_name=repo.get_absolute_url()) """ Authenticate on all requests. To authenticate only against 'POST' requests """ realm = hgwebproxy_settings.AUTH_REALM mercurial_request = is_mercurial(request) if mercurial_request: """ If a slash is not present, would be added a slash regardless of APPEND_SLASH django setting since hgweb returns 404 if it isn't present. """ if not request.path.endswith('/'): new_url = [request.get_host(), request.path + '/'] if new_url[0]: newurl = "%s://%s%s" % (request.is_secure() and 'https' or 'http', new_url[0], urlquote(new_url[1])) else: newurl = urlquote(new_url[1]) if request.GET: newurl += '?' + request.META['QUERY_STRING'] return HttpResponseRedirect(newurl) authed = basic_auth(request, realm, repo) else: if not repo.can_browse(request.user): raise PermissionDenied( _("You do not have access to this repository")) authed = request.user.username if not authed: response.status_code = 401 response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm if request.META['REQUEST_METHOD'] == 'POST' and request.META[ 'QUERY_STRING'].startswith("cmd=unbundle"): # drain request, this is a fix/workaround for http://mercurial.selenic.com/btw/issue1876 hgr.drain() return response else: hgr.set_user(authed) hgserve = hgweb(str(repo.location)) hgserve.reponame = repo.slug # TODO: is it Possible to charge the settings just for one time? hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame)) hgserve.repo.ui.setconfig('web', 'description', smart_str(repo.description)) hgserve.repo.ui.setconfig('web', 'contact', smart_str(repo.owner.get_full_name())) hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive) if os.path.exists(hgwebproxy_settings.STYLES_PATH): template_paths = templater.templatepath() template_paths.insert(0, hgwebproxy_settings.STYLES_PATH) hgserve.repo.ui.setconfig('web', 'templates', template_paths) hgserve.templatepath = hgserve.repo.ui.config('web', 'templates', template_paths) if hgwebproxy_settings.ALLOW_CUSTOM_STYLE: hgserve.repo.ui.setconfig('web', 'style', repo.style) else: hgserve.repo.ui.setconfig('web', 'style', hgwebproxy_settings.DEFAULT_STYLE) hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url()) hgserve.repo.ui.setconfig('web', 'allow_push', authed) #Allow push to the current user hgserve.repo.ui.setconfig('web', 'staticurl', hgwebproxy_settings.STATIC_URL) if settings.DEBUG: hgserve.repo.ui.setconfig('web', 'push_ssl', 'false') else: hgserve.repo.ui.setconfig('web', 'push_ssl', repo.allow_push_ssl) # Catch hgweb error to show as Django Exceptions try: response.write(''.join(each for each in hgserve.run_wsgi(hgr))) except KeyError: return HttpResponseServerError('Mercurial has crashed', mimetype='text/html') if mercurial_request: return response # make sure we return the response without wrapping if content-type is # either a binary stream or text/plain (for raw changesets). if response['content-type'].split(';')[0] in ('application/octet-stream', 'text/plain'): return response context = { 'content': response.content, 'reponame': hgserve.reponame, 'static_url': hgwebproxy_settings.STATIC_URL, 'slugpath': request.path.replace(repo.get_absolute_url(), ''), 'is_root': request.path == repo.get_absolute_url(), 'repo': repo, } if request.path.endswith(repo_name + '/rss-log') or request.path.endswith(repo_name + '/atom-log'): return HttpResponse(response.content, mimetype='application/xml') else: return render_to_response("hgwebproxy/wrapper.html", context, RequestContext(request))
def repo_detail(request, pattern): slug = pattern.split('/')[0] repo = get_object_or_404(Repository, slug=slug) response = HttpResponse() hgr = HgRequestWrapper( request, response, script_name=repo.get_absolute_url(), ) """ Authenticate on all requests. To authenticate only against 'POST' requests, uncomment the line below the comment. Currently, repositories are only viewable by authenticated users. If authentication is only done on 'POST' request, then repositories are readable by anyone. but only authenticated users can push. """ realm = hgwebproxy_settings.AUTH_REALM # Change if you want. if is_mercurial(request): # This is a request by a mercurial client # If slash not present then add slash regardless of APPEND_SLASH setting # since hgweb returns 404 if it isn't present. if not request.path.endswith('/'): new_url = [request.get_host(), request.path+'/'] if new_url[0]: newurl = "%s://%s%s" % ( request.is_secure() and 'https' or 'http', new_url[0], urlquote(new_url[1])) else: newurl = urlquote(new_url[1]) if request.GET: newurl += '?' + request.META['QUERY_STRING'] return HttpResponsePermanentRedirect(newurl) authed = basic_auth(request, realm, repo) else: # This is a standard web request if not repo.has_view_permission(request.user): raise PermissionDenied(_("You do not have access to this repository")) authed = request.user.username #if not request.user.is_authenticated(): # return HttpResponseRedirect('%s?next=%s' % # (settings.LOGIN_URL,request.path)) #else: # authed = request.user.username if not authed: response.status_code = 401 response['WWW-Authenticate'] = '''Basic realm="%s"''' % realm return response else: hgr.set_user(authed) """ Run the `hgwebdir` method from Mercurial directly, with our incognito request wrapper, output will be buffered. Wrapped in a try:except: since `hgweb` *can* crash. Mercurial now sends the content through as a generator. We need to iterate over the output in order to get all of the content """ template_dir = os.path.join(os.path.dirname(__file__), 'templates') hgserve = hgweb(str(repo.location)) hgserve.reponame = repo.slug if hgwebproxy_settings.TEMPLATE_PATHS is not None: hgserve.templatepath = hgwebproxy_settings.TEMPLATE_PATHS hgserve.repo.ui.setconfig('web', 'description', smart_str(repo.description)) hgserve.repo.ui.setconfig('web', 'name', smart_str(hgserve.reponame)) # encode('utf-8') FIX "decoding Unicode is not supported" exception on mercurial hgserve.repo.ui.setconfig('web', 'contact', smart_str(repo.owner.get_full_name())) hgserve.repo.ui.setconfig('web', 'allow_archive', repo.allow_archive) # Set the style style = repo.style or hgwebproxy_settings.STYLE if not templater.templatepath(style): raise ImproperlyConfigured(_("'%s' is not an available style. Please check the HGPROXY_STYLE property in your settings.py" % style)) hgserve.repo.ui.setconfig('web', 'style', style) hgserve.repo.ui.setconfig('web', 'baseurl', repo.get_absolute_url() ) # Allow push to the current user hgserve.repo.ui.setconfig('web', 'allow_push', authed) #Allow serving static content from a seperate URL if not settings.DEBUG: hgserve.repo.ui.setconfig('web', 'staticurl', hgwebproxy_settings.STATIC_URL) if settings.DEBUG or hgwebproxy_settings.ALLOW_HTTP_PUSH: # Allow pushing in using http when debugging hgserve.repo.ui.setconfig('web', 'push_ssl', 'false') # Allow hgweb errors to propagate response.write(''.join([each for each in hgserve.run_wsgi(hgr)])) return response
def repo_list(request): # Handle repo_detail u = ui.ui() u.setconfig('ui', 'report_untrusted', 'off') u.setconfig('ui', 'interactive', 'off') #stripecount = u.config('web', 'stripes', 1) stripecount = 1 response = HttpResponse() #TODO: Is this right? url = request.path if not url.endswith('/'): url += '/' def header(**map): yield tmpl('header', encoding=encoding.encoding, **map) def footer(**map): yield tmpl("footer", **map) def motd(**map): yield "" def archivelist(ui, nodeid, url): # TODO: support archivelist if 1 == 2: yield "" sortdefault = 'name', False def entries(sortcolumn="", descending=False, subdir="", **map): rows = [] parity = common.paritygen(stripecount) for repo in Repository.objects.has_view_permission(request.user): contact = smart_str(repo.owner.get_full_name()) lastchange = (common.get_mtime(repo.location), util.makedate()[1]) row = dict(contact=contact or "unknown", contact_sort=contact.upper() or "unknown", name=smart_str(repo.name), name_sort=smart_str(repo.name), url=repo.get_absolute_url(), description=smart_str(repo.description) or "unknown", description_sort=smart_str(repo.description.upper()) or "unknown", lastchange=lastchange, lastchange_sort=lastchange[1]-lastchange[0], archives=archivelist(u, "tip", url)) if (not sortcolumn or (sortcolumn, descending) == sortdefault): # fast path for unsorted output row['parity'] = parity.next() yield row else: rows.append((row["%s_sort" % sortcolumn], row)) if rows: rows.sort() if descending: rows.reverse() for key, row in rows: row['parity'] = parity.next() yield row defaultstaticurl = request.path + 'static/' staticurl = hgwebproxy_settings.STATIC_URL or defaultstaticurl if not settings.DEBUG else defaultstaticurl if hgwebproxy_settings.TEMPLATE_PATHS is not None: hgserve.templatepath = hgwebproxy_settings.TEMPLATE_PATHS vars = {} start = url[-1] == '?' and '&' or '?' sessionvars = webutil.sessionvars(vars, start) if not templater.templatepath(hgwebproxy_settings.STYLE): raise ImproperlyConfigured(_("'%s' is not an available style. Please check the HGPROXY_STYLE property in your settings.py" % hgwebproxy_settings.STYLE)) mapfile = templater.stylemap(hgwebproxy_settings.STYLE) if isinstance(mapfile, tuple): mapfile = mapfile[1] tmpl = templater.templater(mapfile, defaults={"header": header, "footer": footer, "motd": motd, "url": url, "staticurl": staticurl, "sessionvars": sessionvars}) #Support for descending, sortcolumn etc. sortable = ["name", "description", "contact", "lastchange"] sortcolumn, descending = sortdefault if 'sort' in request.GET: sortcolumn = request.GET['sort'] descending = sortcolumn.startswith('-') if descending: sortcolumn = sortcolumn[1:] if sortcolumn not in sortable: sortcolumn = "" sort = [("sort_%s" % column, "%s%s" % ((not descending and column == sortcolumn) and "-" or "", column)) for column in sortable] chunks = tmpl("index", entries=entries, subdir="", sortcolumn=sortcolumn, descending=descending, **dict(sort)) for chunk in chunks: response.write(chunk) return response
template = templater.parsestring(template) except SyntaxError: template = templater.parsestring(template, quoted=False) else: style = util.expandpath(ui.config('ui', 'style', '')) elif template: try: template = templater.parsestring(template, quoted=False) except SyntaxError, e: raise util.Abort('bad template: %s' % e.args[0]) mapfile = None if style and not template: mapfile = style if not os.path.split(mapfile)[0]: mapname = (templater.templatepath('map-cmdline.' + mapfile) or templater.templatepath(mapfile)) if mapname: mapfile = mapname if style or template: should_format = False long_format = True flags = True elif long_format: if ui.verbose: template = ['{mode|lsmode}\0{author}'] else: template = ['{mode|lsmode}\0{author|user}'] align_columns = ['ll']