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, 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))