def version_get(self, user, index, name, version): stage = self.getstage(user, index) name = ensure_unicode(name) version = ensure_unicode(version) metadata = stage.get_projectconfig(name) if not metadata: abort(404, "project %r does not exist" % name) verdata = metadata.get(version, None) if not verdata: abort(404, "version %r does not exist" % version) if json_preferred(): apireturn(200, type="versiondata", result=verdata) # if html show description and metadata rows = [] for key, value in sorted(verdata.items()): if key == "description": continue if isinstance(value, list): value = html.ul([html.li(x) for x in value]) rows.append(html.tr(html.td(key), html.td(value))) title = "%s/: %s-%s metadata and description" % ( stage.name, name, version) content = stage.get_description(name, version) #css = "https://pypi.python.org/styles/styles.css" return simple_html_body(title, [html.table(*rows), py.xml.raw(content)], extrahead= [html.link(media="screen", type="text/css", rel="stylesheet", title="text", href="https://pypi.python.org/styles/styles.css")] ).unicode(indent=2)
def version_get(self, user, index, name, version): stage = self.getstage(user, index) name = ensure_unicode(name) version = ensure_unicode(version) metadata = stage.get_projectconfig(name) if not metadata: abort(404, "project %r does not exist" % name) verdata = metadata.get(version, None) if not verdata: abort(404, "version %r does not exist" % version) if json_preferred(): apireturn(200, type="versiondata", result=verdata) # if html show description and metadata rows = [] for key, value in sorted(verdata.items()): if key == "description": continue if isinstance(value, list): value = html.ul([html.li(x) for x in value]) rows.append(html.tr(html.td(key), html.td(value))) title = "%s/: %s-%s metadata and description" % (stage.name, name, version) content = stage.get_description(name, version) #css = "https://pypi.python.org/styles/styles.css" return simple_html_body( title, [html.table(*rows), py.xml.raw(content)], extrahead=[ html.link(media="screen", type="text/css", rel="stylesheet", title="text", href="https://pypi.python.org/styles/styles.css") ]).unicode(indent=2)
def iter_projects(xom): for user in xom.model.get_userlist(): username = ensure_unicode(user.name) user_info = user.get(user) for index, index_info in user_info.get('indexes', {}).items(): index = ensure_unicode(index) stage = xom.model.getstage(username, index) if stage is None: # this is async, so the stage may be gone continue names = stage.list_projects_perstage() for name in names: name = ensure_unicode(name) yield ProjectIndexingInfo(stage=stage, name=name)
def preprocess_project(project): stage = project.stage pm = get_pluginmanager(stage.xom.config) name = normalize_name(project.name) try: user = stage.user.name index = stage.index except AttributeError: user, index = stage.name.split('/') user = ensure_unicode(user) index = ensure_unicode(index) if not is_project_cached(stage, name): result = dict(name=name, user=user, index=index) pm.hook.devpiweb_modify_preprocess_project_result(project=project, result=result) return result stage.offline = True if not stage.has_project_perstage(name): # project doesn't exist anymore return setuptools_metadata = frozenset(getattr(stage, 'metadata_keys', ())) versions = get_sorted_versions(stage.list_versions_perstage(name)) result = dict(name=name) for i, version in enumerate(versions): if i == 0: verdata = stage.get_versiondata_perstage(name, version) result.update(verdata) links = stage.get_linkstore_perstage(name, version).get_links(rel="doczip") if links: docs = Docs(stage, name, version) if docs.exists(): result['doc_version'] = version result['+doczip'] = docs break else: assert '+doczip' not in result result[u'user'] = user result[u'index'] = index for key in setuptools_metadata: if key in result: value = result[key] if value == 'UNKNOWN' or not value: del result[key] pm.hook.devpiweb_modify_preprocess_project_result(project=project, result=result) return result
def submit(self, user, index): if user == "root" and index == "pypi": abort(404, "cannot submit to pypi mirror") stage = self.getstage(user, index) self.require_user(user, stage=stage) try: action = request.forms[":action"] except KeyError: abort(400, ":action field not found") if action == "submit": return self._register_metadata_form(stage, request.forms) elif action in ("doc_upload", "file_upload"): try: content = request.files["content"] except KeyError: abort(400, "content file field not found") name = ensure_unicode(request.forms.get("name")) version = ensure_unicode(request.forms.get("version")) info = stage.get_project_info(name) if not info: abort(400, "no project named %r was ever registered" % (name)) if action == "file_upload": log.debug("metadata in form: %s", list(request.forms.items())) abort_if_invalid_filename(name, content.filename) if not stage.get_metadata(name, version): self._register_metadata_form(stage, request.forms) res = stage.store_releasefile(content.filename, content.value) if res == 409: abort( 409, "%s already exists in non-volatile index" % (content.filename, )) jenkinurl = stage.ixconfig["uploadtrigger_jenkins"] if jenkinurl: jenkinurl = jenkinurl.format(pkgname=name) if trigger_jenkins(stage, jenkinurl, name) == -1: abort_custom( 200, "OK, but couldn't trigger jenkins at %s" % (jenkinurl, )) else: # docs have no version (XXX but they are tied to the latest) if len(content.value) > MAXDOCZIPSIZE: abort_custom( 413, "zipfile size %d too large, max=%s" % (len(content.value), MAXDOCZIPSIZE)) stage.store_doczip(name, version, py.io.BytesIO(content.value)) else: abort(400, "action %r not supported" % action) return ""
def project_version_delete(self, user, index, name, version): stage = self.getstage(user, index) name = ensure_unicode(name) version = ensure_unicode(version) if stage.name == "root/pypi": abort(405, "cannot delete on root/pypi index") if not stage.ixconfig["volatile"]: abort(403, "cannot delete version on non-volatile index") metadata = stage.get_projectconfig(name) if not metadata: abort(404, "project %r does not exist" % name) verdata = metadata.get(version, None) if not verdata: abort(404, "version %r does not exist" % version) stage.project_version_delete(name, version) apireturn(200, "project %r version %r deleted" % (name, version))
def simple_list_project(self, user, index, projectname): # we only serve absolute links so we don't care about the route's slash abort_if_invalid_projectname(projectname) stage = self.getstage(user, index) projectname = ensure_unicode(projectname) info = stage.get_project_info(projectname) if info and info.name != projectname: redirect("/%s/+simple/%s/" % (stage.name, info.name)) result = stage.getreleaselinks(projectname) if isinstance(result, int): if result == 404: # we don't want pip/easy_install to try the whole simple # page -- we know for sure there is no fitting project # because all devpi indexes perform package name normalization abort(200, "no such project %r" % projectname) if result >= 500: abort(502, "upstream server has internal error") if result < 0: abort(502, "upstream server not reachable") links = [] for entry in result: relpath = entry.relpath href = "/" + relpath href = URL(request.path).relpath(href) if entry.eggfragment: href += "#egg=%s" % entry.eggfragment elif entry.md5: href += "#md5=%s" % entry.md5 links.extend([ "/".join(relpath.split("/", 2)[:2]) + " ", html.a(entry.basename, href=href), html.br(), "\n", ]) return simple_html_body("%s: links for %s" % (stage.name, projectname), links).unicode(indent=2)
def store_releasefile(self, filename, content, last_modified=None): filename = ensure_unicode(filename) bmeta = BasenameMeta(filename) name, version = bmeta.name, bmeta.version info = self.get_project_info(name) name = getattr(info, "name", name) if not self.get_metadata(name, version): raise self.MissesRegistration(name, version) log.debug("project name of %r is %r", filename, name) key = self.keyfs.PROJCONFIG(user=self.user, index=self.index, name=name) with key.locked_update() as projectconfig: verdata = projectconfig.setdefault(version, {}) files = verdata.setdefault("+files", {}) if not self.ixconfig.get("volatile") and filename in files: return 409 entry = self.xom.filestore.store(self.user, self.index, filename, content, last_modified=last_modified) files[filename] = entry.relpath self.log_info("store_releasefile %s", entry.relpath) return entry
def store_releasefile(self, project, version, filename, content, last_modified=None): project = normalize_name(project) filename = ensure_unicode(filename) if not self.get_versiondata_perstage(project, version): # There's a chance the version was guessed from the # filename, which might have swapped dashes to underscores if '_' in version: version = version.replace('_', '-') if not self.get_versiondata_perstage(project, version): raise MissesRegistration("%s-%s", project, version) else: raise MissesRegistration("%s-%s", project, version) linkstore = self.get_linkstore_perstage(project, version, readonly=False) link = linkstore.create_linked_entry(rel="releasefile", basename=filename, file_content=content, last_modified=last_modified) self._regen_simplelinks(project) return link
def submit(self, user, index): if user == "root" and index == "pypi": abort(404, "cannot submit to pypi mirror") stage = self.getstage(user, index) self.require_user(user, stage=stage) try: action = request.forms[":action"] except KeyError: abort(400, ":action field not found") if action == "submit": return self._register_metadata_form(stage, request.forms) elif action in ("doc_upload", "file_upload"): try: content = request.files["content"] except KeyError: abort(400, "content file field not found") name = ensure_unicode(request.forms.get("name")) version = ensure_unicode(request.forms.get("version")) info = stage.get_project_info(name) if not info: abort(400, "no project named %r was ever registered" %(name)) if action == "file_upload": log.debug("metadata in form: %s", list(request.forms.items())) abort_if_invalid_filename(name, content.filename) if not stage.get_metadata(name, version): self._register_metadata_form(stage, request.forms) res = stage.store_releasefile(content.filename, content.value) if res == 409: abort(409, "%s already exists in non-volatile index" %( content.filename,)) jenkinurl = stage.ixconfig["uploadtrigger_jenkins"] if jenkinurl: jenkinurl = jenkinurl.format(pkgname=name) if trigger_jenkins(stage, jenkinurl, name) == -1: abort_custom(200, "OK, but couldn't trigger jenkins at %s" % (jenkinurl,)) else: # docs have no version (XXX but they are tied to the latest) if len(content.value) > MAXDOCZIPSIZE: abort_custom(413, "zipfile size %d too large, max=%s" % (len(content.value), MAXDOCZIPSIZE)) stage.store_doczip(name, version, py.io.BytesIO(content.value)) else: abort(400, "action %r not supported" % action) return ""
def __init__(self, url="", *args, **kwargs): if isinstance(url, URL): url = url.url if args: url = _joinpath(url, args, **kwargs) if not url: url = "" self.url = ensure_unicode(url)
def has_pypi_base(self, name): name = ensure_unicode(name) private_hit = whitelisted = False for stage in self._sro(): if stage.ixconfig["type"] == "mirror": return stage.get_projectname_perstage(name) and \ (not private_hit or whitelisted) private_hit = private_hit or bool(self.get_projectname_perstage(name)) whitelisted = whitelisted or name in stage.ixconfig["pypi_whitelist"]
def iter_projects(xom): timestamp = time.time() for user in xom.model.get_userlist(): username = ensure_unicode(user.name) user_info = user.get(user) for index, index_info in user_info.get('indexes', {}).items(): index = ensure_unicode(index) stage = xom.model.getstage(username, index) if stage is None: # this is async, so the stage may be gone continue log.info("Search-Indexing %s:", stage.name) names = stage.list_projects_perstage() for count, name in enumerate(names, start=1): name = ensure_unicode(name) current_time = time.time() if current_time - timestamp > 3: log.debug("currently search-indexed %s", count) timestamp = current_time yield preprocess_project(stage, name)
def has_pypi_base(self, name): name = ensure_unicode(name) private_hit = whitelisted = False for stage in self._sro(): if stage.ixconfig["type"] == "mirror": return stage.get_projectname_perstage(name) and \ (not private_hit or whitelisted) private_hit = private_hit or bool( self.get_projectname_perstage(name)) whitelisted = whitelisted or name in stage.ixconfig[ "pypi_whitelist"]
def store_releasefile(self, name, version, filename, content, last_modified=None): filename = ensure_unicode(filename) if not self.get_versiondata(name, version): raise MissesRegistration("%s-%s", name, version) threadlog.debug("project name of %r is %r", filename, name) linkstore = self.get_linkstore_perstage(name, version) entry = linkstore.create_linked_entry( rel="releasefile", basename=filename, file_content=content, last_modified=last_modified) return entry
def preprocess_project(stage, name_input): name = normalize_name(name_input) try: user = stage.user.name index = stage.index except AttributeError: user, index = stage.name.split('/') user = ensure_unicode(user) index = ensure_unicode(index) if not is_project_cached(stage, name): return dict(name=name, user=user, index=index) setuptools_metadata = frozenset( ('author', 'author_email', 'classifiers', 'description', 'download_url', 'home_page', 'keywords', 'license', 'platform', 'summary')) versions = get_sorted_versions(stage.list_versions_perstage(name)) result = dict(name=name) for i, version in enumerate(versions): if i == 0: verdata = stage.get_versiondata_perstage(name, version) result.update(verdata) links = stage.get_linkstore_perstage(name, version).get_links(rel="doczip") if links: result['doc_version'] = version result['+doczip'] = Docs(stage, name, version) break else: assert '+doczip' not in result result[u'user'] = user result[u'index'] = index for key in setuptools_metadata: if key in result: value = result[key] if value == 'UNKNOWN' or not value: del result[key] return result
def _set_versiondata_form(self, stage, form): metadata = {} for key in stage.metadata_keys: if key.lower() in stage.metadata_list_fields: val = [ensure_unicode(item) for item in form.getall(key) if item] else: val = form.get(key, "") if val == "UNKNOWN": val = "" assert py.builtin._istext(val), val metadata[key] = val self._set_versiondata_dict(stage, metadata)
def _register_metadata_form(self, stage, form): metadata = {} for key in stage.metadata_keys: if key.lower() in stage.metadata_list_fields: val = [ensure_unicode(item) for item in form.getall(key) if item] else: val = getattr(form, key) # returns unicode in bottle if val == "UNKNOWN": val = "" assert py.builtin._istext(val), val metadata[key] = val self._register_metadata_dict(stage, metadata)
def _register_metadata_form(self, stage, form): metadata = {} for key in stage.metadata_keys: if key.lower() in stage.metadata_list_fields: val = [ ensure_unicode(item) for item in form.getall(key) if item ] else: val = getattr(form, key) # returns unicode in bottle if val == "UNKNOWN": val = "" assert py.builtin._istext(val), val metadata[key] = val self._register_metadata_dict(stage, metadata)
def get_mirror_whitelist_info(self, project): project = ensure_unicode(project) private_hit = whitelisted = False for stage in self.sro(): in_index = stage.has_project_perstage(project) if stage.ixconfig["type"] == "mirror": has_mirror_base = in_index and (not private_hit or whitelisted) blocked_by_mirror_whitelist = in_index and private_hit and not whitelisted return dict(has_mirror_base=has_mirror_base, blocked_by_mirror_whitelist=stage.name if blocked_by_mirror_whitelist else None) private_hit = private_hit or in_index whitelist = set(stage.ixconfig["mirror_whitelist"]) whitelisted = whitelisted or '*' in whitelist or project in whitelist return dict(has_mirror_base=False, blocked_by_mirror_whitelist=None)
def store_releasefile(self, name, version, filename, content, last_modified=None): filename = ensure_unicode(filename) if not self.get_versiondata(name, version): raise MissesRegistration("%s-%s", name, version) threadlog.debug("project name of %r is %r", filename, name) linkstore = self.get_linkstore_perstage(name, version) entry = linkstore.create_linked_entry(rel="releasefile", basename=filename, file_content=content, last_modified=last_modified) return entry
def modify(self, password=None, **kwargs): with self.key.update() as userconfig: modified = [] if password is not None: self._setpassword(userconfig, password) modified.append("password=*******") kwargs['pwsalt'] = None for key, value in kwargs.items(): key = ensure_unicode(key) if key == 'username': continue if value: userconfig[key] = value elif key in userconfig: del userconfig[key] if key in ('pwsalt', 'pwhash') and value: value = "*******" modified.append("%s=%s" % (key, value)) threadlog.info("modified user %r: %s", self.name, ", ".join(modified))
def store_releasefile(self, name, version, filename, content, last_modified=None): filename = ensure_unicode(filename) if not self.get_versiondata(name, version): # There's a chance the version was guessed from the # filename, which might have swapped dashes to underscores if '_' in version: version = version.replace('_', '-') if not self.get_versiondata(name, version): raise MissesRegistration("%s-%s", name, version) else: raise MissesRegistration("%s-%s", name, version) threadlog.debug("project name of %r is %r", filename, name) linkstore = self.get_linkstore_perstage(name, version) link = linkstore.create_linked_entry( rel="releasefile", basename=filename, file_content=content, last_modified=last_modified) return link
def project_get(self, user, index, name): #log.debug("HEADERS: %s", request.headers.items()) stage = self.getstage(user, index) name = ensure_unicode(name) info = stage.get_project_info(name) real_name = info.name if info else name if html_preferred(): # we need to redirect because the simple pages # may return status codes != 200, causing # pip to look at the full simple list at the parent url # but we don't serve this list on /user/index/ redirect("/%s/+simple/%s/" % (stage.name, real_name)) if not json_preferred(): apireturn(415, "unsupported media type %s" % request.headers.items()) if not info: apireturn(404, "project %r does not exist" % name) if real_name != name: redirect("/%s/%s/" % (stage.name, real_name)) metadata = stage.get_projectconfig(name) apireturn(200, type="projectconfig", result=metadata)
def submit(self): request = self.request context = self.context if context.username == "root" and context.index == "pypi": abort_submit(request, 404, "cannot submit to pypi mirror") stage = self.context.stage if not request.has_permission("pypi_submit"): # if there is no authenticated user, then issue a basic auth challenge if not request.authenticated_userid: response = HTTPUnauthorized() response.headers.update(forget(request)) return response abort_submit(request, 403, "no permission to submit") try: action = request.POST[":action"] except KeyError: abort_submit(request, 400, ":action field not found") if action == "submit": self._set_versiondata_form(stage, request.POST) return Response("") elif action in ("doc_upload", "file_upload"): try: content = request.POST["content"] except KeyError: abort_submit(request, 400, "content file field not found") name = ensure_unicode(request.POST.get("name")) # version may be empty on plain doczip uploads version = ensure_unicode(request.POST.get("version") or "") project = normalize_name(name) if action == "file_upload": if not stage.has_project(name): abort_submit( request, 400, "no project named %r was ever registered" % (name)) self.log.debug("metadata in form: %s", list(request.POST.items())) # we only check for release files if version is # contained in the filename because for doczip files # we construct the filename ourselves anyway. if version and version not in content.filename: abort_submit( request, 400, "filename %r does not contain version %r" % ( content.filename, version)) abort_if_invalid_filename(request, name, content.filename) metadata = stage.get_versiondata_perstage(project, version) if not metadata: self._set_versiondata_form(stage, request.POST) metadata = stage.get_versiondata(project, version) if not metadata: abort_submit( request, 400, "could not process form metadata") file_content = content.file.read() try: link = stage.store_releasefile( project, version, content.filename, file_content) except stage.NonVolatile as e: if e.link.matches_checksum(file_content): abort_submit( request, 200, "Upload of identical file to non volatile index.", level="info") abort_submit( request, 409, "%s already exists in non-volatile index" % ( content.filename,)) link.add_log( 'upload', request.authenticated_userid, dst=stage.name) try: self.xom.config.hook.devpiserver_on_upload_sync( log=request.log, application_url=request.application_url, stage=stage, project=project, version=version) except Exception as e: abort_submit( request, 200, "OK, but a trigger plugin failed: %s" % e, level="warn") else: doczip = content.file.read() try: link = stage.store_doczip(project, version, doczip) except stage.MissesVersion as e: abort_submit( request, 400, "%s" % e) except stage.MissesRegistration: abort_submit( request, 400, "%s-%s is not registered" % (name, version)) except stage.NonVolatile as e: if e.link.matches_checksum(doczip): abort_submit( request, 200, "Upload of identical file to non volatile index.", level="info") abort_submit( request, 409, "%s already exists in non-volatile index" % ( content.filename,)) link.add_log( 'upload', request.authenticated_userid, dst=stage.name) else: abort_submit(request, 400, "action %r not supported" % action) return Response("")
def submit(self): request = self.request context = self.context if context.username == "root" and context.index == "pypi": abort_submit(404, "cannot submit to pypi mirror") stage = self.context.stage if not request.has_permission("pypi_submit"): # if there is no authenticated user, then issue a basic auth challenge if not request.authenticated_userid: response = HTTPUnauthorized() response.headers.update(forget(request)) return response abort_submit(403, "no permission to submit") try: action = request.POST[":action"] except KeyError: abort_submit(400, ":action field not found") if action == "submit": self._set_versiondata_form(stage, request.POST) return Response("") elif action in ("doc_upload", "file_upload"): try: content = request.POST["content"] except KeyError: abort_submit(400, "content file field not found") name = ensure_unicode(request.POST.get("name")) # version may be empty on plain uploads version = ensure_unicode(request.POST.get("version") or "") projectname = stage.get_projectname(name) if projectname is None: abort_submit(400, "no project named %r was ever registered" % (name)) if action == "file_upload": self.log.debug("metadata in form: %s", list(request.POST.items())) abort_if_invalid_filename(name, content.filename) metadata = stage.get_versiondata_perstage(projectname, version) if not metadata: self._set_versiondata_form(stage, request.POST) metadata = stage.get_versiondata(projectname, version) if not metadata: abort_submit(400, "could not process form metadata") file_content = content.file.read() try: link = stage.store_releasefile( projectname, version, content.filename, file_content) except stage.NonVolatile as e: if e.link.matches_checksum(file_content): abort_submit(200, "Upload of identical file to non volatile index.") abort_submit(409, "%s already exists in non-volatile index" % ( content.filename,)) link.add_log( 'upload', request.authenticated_userid, dst=stage.name) try: self.xom.config.hook.devpiserver_on_upload_sync( log=request.log, application_url=request.application_url, stage=stage, projectname=projectname, version=version) except Exception as e: abort_submit(200, "OK, but a trigger plugin failed: %s" % e) else: doczip = content.file.read() try: link = stage.store_doczip(projectname, version, doczip) except stage.MissesRegistration: apireturn(400, "%s-%s is not registered" %(name, version)) except stage.NonVolatile as e: if e.link.matches_checksum(doczip): abort_submit(200, "Upload of identical file to non volatile index.") abort_submit(409, "%s already exists in non-volatile index" % ( content.filename,)) link.add_log( 'upload', request.authenticated_userid, dst=stage.name) else: abort_submit(400, "action %r not supported" % action) return Response("")
def name(self): return ensure_unicode(self.matchdict.get('name'))
def md5(self): val = self._parsed.fragment if val.startswith("md5="): return ensure_unicode(val[4:])
def version(self): version = self.matchdict.get('version') if version is None: return return ensure_unicode(version)
def submit(self): request = self.request context = self.context if context.username == "root" and context.index == "pypi": abort_submit(404, "cannot submit to pypi mirror") stage = self.context.stage if not request.has_permission("pypi_submit"): # if there is no authenticated user, then issue a basic auth challenge if not request.authenticated_userid: response = HTTPUnauthorized() response.headers.update(forget(request)) return response abort_submit(403, "no permission to submit") try: action = request.POST[":action"] except KeyError: abort_submit(400, ":action field not found") if action == "submit": self._set_versiondata_form(stage, request.POST) return Response("") elif action in ("doc_upload", "file_upload"): try: content = request.POST["content"] except KeyError: abort_submit(400, "content file field not found") name = ensure_unicode(request.POST.get("name")) # version may be empty on plain uploads version = ensure_unicode(request.POST.get("version") or "") projectname = stage.get_projectname(name) if projectname is None: abort_submit( 400, "no project named %r was ever registered" % (name)) if action == "file_upload": self.log.debug("metadata in form: %s", list(request.POST.items())) abort_if_invalid_filename(name, content.filename) metadata = stage.get_versiondata_perstage(projectname, version) if not metadata: self._set_versiondata_form(stage, request.POST) metadata = stage.get_versiondata(projectname, version) if not metadata: abort_submit(400, "could not process form metadata") res = stage.store_releasefile(projectname, version, content.filename, content.file.read()) if res == 409: abort_submit( 409, "%s already exists in non-volatile index" % (content.filename, )) jenkinurl = stage.ixconfig["uploadtrigger_jenkins"] if jenkinurl: jenkinurl = jenkinurl.format(pkgname=name) if trigger_jenkins(request, stage, jenkinurl, name) == -1: abort_submit( 200, "OK, but couldn't trigger jenkins at %s" % (jenkinurl, )) else: doczip = content.file.read() if len(doczip) > MAXDOCZIPSIZE: abort_submit( 413, "zipfile size %d too large, max=%s" % (len(doczip), MAXDOCZIPSIZE)) stage.store_doczip(name, version, doczip) else: abort_submit(400, "action %r not supported" % action) return Response("")
def version(self): version = self.matchdict.get("version") if version is None: return return ensure_unicode(version)
def sha256(self): val = self._parsed.fragment if val.startswith("sha256="): return ensure_unicode(val[4:])
def version(self): return ensure_unicode(self.matchdict.get('version'))
def _setpassword(self, userconfig, password, pwhash=None): if pwhash: userconfig["pwhash"] = ensure_unicode(pwhash) else: userconfig["pwhash"] = hash_password(password) threadlog.info("setting password for user %r", self.name)
def submit(self): request = self.request context = self.context if context.username == "root" and context.index == "pypi": abort_submit(404, "cannot submit to pypi mirror") stage = self.context.stage if not request.has_permission("pypi_submit"): # if there is no authenticated user, then issue a basic auth challenge if not request.authenticated_userid: response = HTTPUnauthorized() response.headers.update(forget(request)) return response abort_submit(403, "no permission to submit") try: action = request.POST[":action"] except KeyError: abort_submit(400, ":action field not found") if action == "submit": self._set_versiondata_form(stage, request.POST) return Response("") elif action in ("doc_upload", "file_upload"): try: content = request.POST["content"] except KeyError: abort_submit(400, "content file field not found") name = ensure_unicode(request.POST.get("name")) # version may be empty on plain uploads version = ensure_unicode(request.POST.get("version") or "") projectname = stage.get_projectname(name) if projectname is None: abort_submit(400, "no project named %r was ever registered" % (name)) if action == "file_upload": self.log.debug("metadata in form: %s", list(request.POST.items())) abort_if_invalid_filename(name, content.filename) metadata = stage.get_versiondata_perstage(projectname, version) if not metadata: self._set_versiondata_form(stage, request.POST) metadata = stage.get_versiondata(projectname, version) if not metadata: abort_submit(400, "could not process form metadata") res = stage.store_releasefile(projectname, version, content.filename, content.file.read()) if res == 409: abort_submit(409, "%s already exists in non-volatile index" % ( content.filename,)) jenkinurl = stage.ixconfig["uploadtrigger_jenkins"] if jenkinurl: jenkinurl = jenkinurl.format(pkgname=name) if trigger_jenkins(request, stage, jenkinurl, name) == -1: abort_submit(200, "OK, but couldn't trigger jenkins at %s" % (jenkinurl,)) else: doczip = content.file.read() if len(doczip) > MAXDOCZIPSIZE: abort_submit(413, "zipfile size %d too large, max=%s" % (len(doczip), MAXDOCZIPSIZE)) stage.store_doczip(name, version, doczip) else: abort_submit(400, "action %r not supported" % action) return Response("")
def name(self): name = self.matchdict.get("name") if name is None: return return ensure_unicode(name)