def _create_release(self, package, data): data = self._to_unicode(data) release = Release( package=package, summary=data.get('summary'), version=data.get('version'), stable_version=data.get('stable_version'), home_page=data.get('home_page'), license=data.get('license'), description=data.get('description'), keywords=data.get('keywords'), platform=data.get('platform'), download_url=data.get('download_url'), bugtrack_url=data.get('bugtrack_url'), docs_url=data.get('docs_url'), ) if data.get('author'): author = User.by_login(self.session, data['author'], local=False) if not author: author = User(login=data['author'], local=False, email=data.get('author_email')) self.session.add(author) release.author = author self.session.flush() if data.get('maintainer'): maintainer = User.by_login(self.session, data['maintainer'], local=False) if not maintainer: maintainer = User(login=data['maintainer'], local=False, email=data.get('maintainer_email')) self.session.add(maintainer) release.maintainer = maintainer self.session.flush() for name in data.get('classifiers', []): classifier = Classifier.by_name(self.session, name.decode('utf-8')) while classifier: release.classifiers.append(classifier) if classifier not in package.classifiers: package.classifiers.append(classifier) classifier = classifier.parent self.session.flush() return release
def test_by_classifiers(self): from pyshop.models import Release releases = Release.by_classifiers(self.session, [u'Intended Audience :: Developers']) self.assertIsInstance(releases, list) releases = [(r.package.name, r.version) for r in releases] self.assertEqual(releases, [(u'local_package1', u'0.1')])
def show_external_release_file(root, request): """ Download a release from a download url from its package information. Must be used with :func:`pyshop.helpers.download.renderer_factory` to download the release file. :return: download informations :rtype: dict """ session = DBSession() settings = request.registry.settings whlify = asbool(settings.get('pyshop.mirror.wheelify', '0')) release = Release.by_id(session, int(request.matchdict['release_id'])) filename = (release.whlify_download_url_file if whlify else release.download_url_file) rv = { 'url': release.download_url, 'filename': filename, 'original': release.download_url_file, 'whlify': whlify } release.downloads += 1 release.package.downloads += 1 session.add(release.package) session.add(release) request.response.date = datetime.datetime.utcnow() return rv
def test_by_version(self): from pyshop.models import Release release = Release.by_version(self.session, u'mirrored_package2', u'1.0') self.assertIsInstance(release, Release) self.assertEqual(release.package.name, u'mirrored_package2') self.assertEqual(release.version, u'1.0')
def show_external_release_file(root, request): """ Download a release from a download url from its package information. Must be used with :func:`pyshop.helpers.download.renderer_factory` to download the release file. :return: download informations :rtype: dict """ session = DBSession() settings = request.registry.settings whlify = asbool(settings.get('pyshop.mirror.wheelify', '0')) release = Release.by_id(session, int(request.matchdict['release_id'])) filename = (release.whlify_download_url_file if whlify else release.download_url_file) rv = {'url': release.download_url, 'filename': filename, 'original': release.download_url_file, 'whlify': whlify } release.downloads += 1 release.package.downloads += 1 session.add(release.package) session.add(release) request.response.date = datetime.datetime.utcnow() return rv
def test_by_version(self): from pyshop.models import Release release = Release.by_version( self.session, u'mirrored_package2', u'1.0') self.assertIsInstance(release, Release) self.assertEqual(release.package.name, u'mirrored_package2') self.assertEqual(release.version, u'1.0')
def _create_release(self, package, data): release = Release(package=package, summary=data.get('summary'), version=data.get('version'), stable_version=data.get('stable_version'), home_page=data.get('home_page'), license=data.get('license'), description=data.get('description'), keywords=data.get('keywords'), platform=data.get('platform'), download_url=data.get('download_url'), bugtrack_url=data.get('bugtrack_url'), docs_url=data.get('docs_url'), ) if data.get('author'): author = User.by_login(self.session, data['author'], local=False) if not author: author = User(login=data['author'], local=False, email=data.get('author_email')) self.session.add(author) release.author = author self.session.flush() if data.get('maintainer'): maintainer = User.by_login(self.session, data['maintainer'], local=False) if not maintainer: maintainer = User(login=data['maintainer'], local=False, email=data.get('maintainer_email')) self.session.add(maintainer) release.maintainer = maintainer self.session.flush() for name in data.get('classifiers', []): classifier = Classifier.by_name(self.session, name) while classifier: release.classifiers.append(classifier) if classifier not in package.classifiers: package.classifiers.append(classifier) classifier = classifier.parent self.session.flush() return release
def package_releases(self, package_name, show_hidden=False): """ Retrieve a list of the releases registered for the given package_name. Returns a list with all version strings if show_hidden is True or only the non-hidden ones otherwise.""" session = DBSession() releases = Release.by_package_name(session, package_name, show_hidden) session.rollback() return releases
def render(self): package = Package.by_name(self.session, self.request.matchdict["package_name"]) if not package: raise HTTPNotFound() if "form.refresh_package" in self.request.params: package.update_at = None self.session.add(package) owners = dict((usr.login, usr) for usr in package.owners) can_edit_role = self.login in owners.keys() and package.local if "form.add_role" in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params["login"]) if user and user.has_permission("upload_releasefile"): if self.request.params["role"] == "owner": if user.login not in owners: package.owners.append(user) else: maintainers = [usr.login for usr in package.owners] if user.login not in maintainers: package.maintainers.append(user) self.session.add(package) if "form.remove_maintainer" in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params["login"]) if user: maintainers = dict((usr.login, usr) for usr in package.maintainers) if user.login in maintainers: package.maintainers.remove(maintainers[user.login]) self.session.add(package) if "form.remove_owner" in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params["login"]) if user: if user.login in owners: package.owners.remove(owners[user.login]) self.session.add(package) if "release_version" in self.request.matchdict: release = Release.by_version(self.session, package.name, self.request.matchdict["release_version"]) else: release = package.sorted_releases[0] return {u"package": package, u"release": release, u"can_edit_role": can_edit_role}
def render(self): package = Package.by_name(self.session, self.request.matchdict["package_name"]) if not package: raise HTTPNotFound() if "release_version" in self.request.matchdict: release = Release.by_version(self.session, package.name, self.request.matchdict["release_version"]) else: release = package.sorted_releases[0] return {u"package": package, u"release": release}
def search(self, spec, operator='and'): """ Search the package database using the indicated search spec. The spec may include any of the keywords described in the above list (except 'stable_version' and 'classifiers'), for example: {'description': 'spam'} will search description fields. Within the spec, a field's value can be a string or a list of strings (the values within the list are combined with an OR), for example: {'name': ['foo', 'bar']}. Valid keys for the spec dict are listed here. Invalid keys are ignored: name version author author_email maintainer maintainer_email home_page license summary description keywords platform download_url Arguments for different fields are combined using either "and" (the default) or "or". Example: search({'name': 'foo', 'description': 'bar'}, 'or'). The results are returned as a list of dicts {'name': package name, 'version': package release version, 'summary': package release summary} """ api = pypi.proxy rv = [] # search in proxy for k, v in spec.items(): rv += api.search({k: v}, True) # search in local session = DBSession() release = Release.search(session, spec, operator) session.rollback() rv += [ { 'name': r.package.name, 'version': r.version, 'summary': r.summary, # hack https://mail.python.org/pipermail/catalog-sig/2012-October/004633.html '_pypi_ordering': '', } for r in release ] return rv
def search(self, spec, operator='and'): """ Search the package database using the indicated search spec. The spec may include any of the keywords described in the above list (except 'stable_version' and 'classifiers'), for example: {'description': 'spam'} will search description fields. Within the spec, a field's value can be a string or a list of strings (the values within the list are combined with an OR), for example: {'name': ['foo', 'bar']}. Valid keys for the spec dict are listed here. Invalid keys are ignored: name version author author_email maintainer maintainer_email home_page license summary description keywords platform download_url Arguments for different fields are combined using either "and" (the default) or "or". Example: search({'name': 'foo', 'description': 'bar'}, 'or'). The results are returned as a list of dicts {'name': package name, 'version': package release version, 'summary': package release summary} """ api = pypi.proxy rv = [] # search in proxy for k, v in spec.items(): rv += api.search({k: v}, True) # search in local session = DBSession() release = Release.search(session, spec, operator) session.rollback() rv += [{'name': r.package.name, 'version': r.version, 'summary': r.summary, # hack https://mail.python.org/pipermail/catalog-sig/2012-October/004633.html '_pypi_ordering':'', } for r in release] return rv
def browse(self, classifiers): """ Retrieve a list of (name, version) pairs of all releases classified with all of the given classifiers. 'classifiers' must be a list of Trove classifier strings. changelog(since) Retrieve a list of four-tuples (name, version, timestamp, action) since the given timestamp. All timestamps are UTC values. The argument is a UTC integer seconds since the epoch. """ session = DBSession() release = Release.by_classifiers(session, classifiers) rv = [(r.package.name, r.version) for r in release] return rv
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() if 'release_version' in self.request.matchdict: release = Release.by_version(self.session, package.name, self.request.matchdict['release_version']) else: release = package.sorted_releases[0] return {u'package': package, u'release': release, }
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() if 'form.refresh_package' in self.request.params: package.update_at = None self.session.add(package) if 'release_version' in self.request.matchdict: release = Release.by_version(self.session, package.name, self.request.matchdict['release_version']) else: release = package.sorted_releases[0] return {u'package': package, u'release': release, }
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() release = Release.by_version(self.session, package.name, self.request.matchdict['release_version']) filename = release.files[0].filename if not filename.endswith('.whl'): raise HTTPBadRequest() whl = WheelFile(os.path.join(os.environ['PYSHOP_DIR'], 'repository', filename[0].lower(), filename)) meta_name = next(n for n in whl.zipfile.namelist() if n.endswith('.dist-info/pydist.json')) return json.loads(whl.zipfile.read(meta_name))['run_requires'][0]['requires']
def search(self, spec, operator='and'): """ Search the package database using the indicated search spec. The spec may include any of the keywords described in the above list (except 'stable_version' and 'classifiers'), for example: {'description': 'spam'} will search description fields. Within the spec, a field's value can be a string or a list of strings (the values within the list are combined with an OR), for example: {'name': ['foo', 'bar']}. Valid keys for the spec dict are listed here. Invalid keys are ignored: name version author author_email maintainer maintainer_email home_page license summary description keywords platform download_url Arguments for different fields are combined using either "and" (the default) or "or". Example: search({'name': 'foo', 'description': 'bar'}, 'or'). The results are returned as a list of dicts {'name': package name, 'version': package release version, 'summary': package release summary} """ session = DBSession() release = Release.search(session, spec, operator) session.rollback() rv = [{'name': r.package.name, 'version': r.version, 'summary': r.summary} for r in release] return rv
def show_external_release_file(root, request): """ Download a release from a download url from its package information. Must be used with :func:`pyshop.helpers.download.renderer_factory` to download the release file. :return: download informations :rtype: dict """ session = DBSession() release = Release.by_id(session, int(request.matchdict['release_id'])) rv = {'url': release.download_url, 'filename': release.download_url_file, } release.downloads += 1 release.package.downloads += 1 session.add(release.package) session.add(release) return rv
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() if 'form.refresh_package' in self.request.params: package.update_at = None self.session.add(package) if 'release_version' in self.request.matchdict: release = Release.by_version( self.session, package.name, self.request.matchdict['release_version']) else: release = package.sorted_releases[0] return { u'package': package, u'release': release, }
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() if 'form.refresh_package' in self.request.params: package.update_at = None self.session.add(package) owners = dict((usr.login, usr) for usr in package.owners) can_edit_role = self.login in owners.keys() and package.local if 'form.add_role' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user and user.has_permission('upload_releasefile'): if self.request.params['role'] == 'owner': if user.login not in owners: package.owners.append(user) else: maintainers = [usr.login for usr in package.owners] if user.login not in maintainers: package.maintainers.append(user) self.session.add(package) if 'form.remove_maintainer' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user: maintainers = dict((usr.login, usr) for usr in package.maintainers) if user.login in maintainers: package.maintainers.remove(maintainers[user.login]) self.session.add(package) if 'form.remove_owner' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user: if user.login in owners: package.owners.remove(owners[user.login]) self.session.add(package) if 'release_version' in self.request.matchdict: release = Release.by_version( self.session, package.name, self.request.matchdict['release_version']) else: release = package.sorted_releases[0] return {u'package': package, u'release': release, u'can_edit_role': can_edit_role, }
def release_data(self, package_name, version): """ Retrieve metadata describing a specific package release. Returns a dict with keys for: name version stable_version author author_email maintainer maintainer_email home_page license summary description keywords platform download_url classifiers (list of classifier strings) requires requires_dist provides provides_dist requires_external requires_python obsoletes obsoletes_dist project_url docs_url (URL of the packages.python.org docs if they've been supplied) If the release does not exist, an empty dictionary is returned. """ session = DBSession() release = Release.by_version(session, package_name, version) if release: release = {'name': release.package.name, 'version': release.version, 'stable_version': '', 'author': release.author, 'author_email': release.author_email, 'maintainer': release.maintainer, 'maintainer_email': release.maintainer_email, 'home_page': release.home_page, 'license': release.license, 'summary': release.summary, 'description': release.description, 'keywords': release.keywords, 'platform': release.platform, 'download_url': release.download_url, 'classifiers': [c.name for c in release.classifiers], #'requires': '', #'requires_dist': '', #'provides': '', #'provides_dist': '', #'requires_external': '', #'requires_python': '', #'obsoletes': '', #'obsoletes_dist': '', 'bugtrack_url': release.bugtrack_url, 'docs_url': release.docs_url, } return release
def render(self): settings = self.request.registry.settings if not self.user: raise exc.HTTPForbidden() params = self.request.params if (asbool(settings['pyshop.upload.sanitize']) and not re.match(settings['pyshop.upload.sanitize.regex'], params['version'] )): raise exc.HTTPForbidden() pkg = Package.by_name(self.session, params['name']) if pkg and pkg.local: auth = [user for user in pkg.owners + pkg.maintainers if user == self.user] if not auth: raise exc.HTTPForbidden() elif not pkg: pkg = Package(name=params['name'], local=True) pkg.owners.append(self.user) content = self.request.POST['content'] input_file = content.file if asbool(settings.get('pyshop.upload.rewrite_filename', '1')): # rewrite the filename, do not use the posted one for security filename = self._guess_filename(params, content.filename) else: filename = content.filename dir_ = os.path.join(settings['pyshop.repository'], filename[0].lower()) if not os.path.exists(dir_): os.makedirs(dir_, 0o750) filepath = os.path.join(dir_, filename) while os.path.exists(filepath): log.warning('File %s exists but new upload self.request, deleting' % filepath) os.unlink(filepath) size = 0 with open(filepath, 'wb') as output_file: input_file.seek(0) while True: data = input_file.read(2 << 16) if not data: break size += len(data) output_file.write(data) release = Release.by_version(self.session, pkg.name, params['version']) if not release: release = Release(package=pkg, version=params['version'], summary=params.get('summary'), author=self.user, home_page=params.get('home_page'), license=params.get('license'), description=params.get('description'), keywords=params.get('keywords'), platform=params.get('platform'), download_url=params.get('download_url'), docs_url=params.get('docs_url'), ) classifiers = params.getall('classifiers') for name in classifiers: classifier = Classifier.by_name(self.session, name) while classifier: if classifier not in release.classifiers: release.classifiers.append(classifier) if classifier not in pkg.classifiers: pkg.classifiers.append(classifier) classifier = classifier.parent rfile = ReleaseFile.by_filename(self.session, release, filename) if not rfile: rfile = ReleaseFile(release=release, filename=filename, size=size, md5_digest=params.get('md5_digest'), package_type=params['filetype'], python_version=params.get('pyversion'), comment_text=params.get('comment'), ) self.session.add(rfile) self.session.add(release) pkg.update_at = func.now() self.session.add(pkg) return {'release_file': rfile}
def release_data(self, package_name, version): """ Retrieve metadata describing a specific package release. Returns a dict with keys for: name version stable_version author author_email maintainer maintainer_email home_page license summary description keywords platform download_url classifiers (list of classifier strings) requires requires_dist provides provides_dist requires_external requires_python obsoletes obsoletes_dist project_url docs_url (URL of the packages.python.org docs if they've been supplied) If the release does not exist, an empty dictionary is returned. """ session = DBSession() release = Release.by_version(session, package_name, version) if release: result = { 'name': release.package.name, 'version': release.version, 'stable_version': '', 'author': release.author.name, 'author_email': release.author.email, 'home_page': release.home_page, 'license': release.license, 'summary': release.summary, 'description': release.description, 'keywords': release.keywords, 'platform': release.platform, 'download_url': release.download_url, 'classifiers': [c.name for c in release.classifiers], #'requires': '', #'requires_dist': '', #'provides': '', #'provides_dist': '', #'requires_external': '', #'requires_python': '', #'obsoletes': '', #'obsoletes_dist': '', 'bugtrack_url': release.bugtrack_url, 'docs_url': release.docs_url, } if release.maintainer: result.update({ 'maintainer': release.maintainer.name, 'maintainer_email': release.maintainer.email, }) return dict([(key, val or '') for key, val in result.items()])
def test_search_by_author(self): from pyshop.models import Release releases = Release.search(self.session, {'author': 'janedoe'}, 'and') self.assertIsInstance(releases, list) releases = [(r.package.name, r.version) for r in releases] self.assertEqual(releases, [(u'mirrored_package1', u'0.1')])
def _create_release(self, package, data, session_users): log.info('Create release {0} for package {1}'.format( data.get('version'), package.name)) data = self._to_unicode(data) release = Release(package=package, summary=data.get('summary'), version=data.get('version'), stable_version=data.get('stable_version'), home_page=data.get('home_page'), license=data.get('license'), description=data.get('description'), keywords=data.get('keywords'), platform=data.get('platform'), download_url=data.get('download_url'), bugtrack_url=data.get('bugtrack_url'), docs_url=data.get('docs_url'), ) if data.get('author'): log.info('Looking for author {0}'.format(data['author'])) if _sanitize(data['author']) in session_users: author = session_users[_sanitize(data['author'])] else: author = User.by_login(self.session, data['author'], local=False) if not author: log.info('Author {0} not found, creating'.format( data['author'])) author = User(login=data['author'], local=False, email=data.get('author_email')) self.session.add(author) session_users[_sanitize(data['author'])] = author release.author = author self.session.flush() if data.get('maintainer'): log.info('Looking for maintainer {0}'.format(data['maintainer'])) if _sanitize(data['maintainer']) in session_users: maintainer = session_users[_sanitize(data['maintainer'])] else: maintainer = User.by_login(self.session, data['maintainer'], local=False) if not maintainer: log.info('Maintainer not found, creating user {0}' ''.format(data['maintainer'])) maintainer = User(login=data['maintainer'], local=False, email=data.get('maintainer_email')) self.session.add(maintainer) session_users[_sanitize(data['maintainer'])] = maintainer release.maintainer = maintainer self.session.flush() for name in data.get('classifiers', []): classifier = Classifier.by_name(self.session, name.decode('utf-8'), create_if_not_exists=True) while classifier: if classifier not in release.classifiers: release.classifiers.append(classifier) if classifier not in package.classifiers: package.classifiers.append(classifier) classifier = classifier.parent self.session.flush() return release
def render(self): package = Package.by_name(self.session, self.request.matchdict['package_name']) if not package: raise HTTPNotFound() if 'form.refresh_package' in self.request.params: package.update_at = None self.session.add(package) owners = dict((usr.login, usr) for usr in package.owners) can_edit_role = self.login in owners.keys() and package.local if 'form.add_role' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user and user.has_permission('upload_releasefile'): if self.request.params['role'] == 'owner': if user.login not in owners: package.owners.append(user) else: maintainers = [usr.login for usr in package.owners] if user.login not in maintainers: package.maintainers.append(user) self.session.add(package) if 'form.remove_maintainer' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user: maintainers = dict((usr.login, usr) for usr in package.maintainers) if user.login in maintainers: package.maintainers.remove(maintainers[user.login]) self.session.add(package) if 'form.remove_owner' in self.request.params: if not can_edit_role: raise HTTPForbidden() user = User.by_login(self.session, self.request.params['login']) if user: if user.login in owners: package.owners.remove(owners[user.login]) self.session.add(package) if 'release_version' in self.request.matchdict: release = Release.by_version(self.session, package.name, self.request.matchdict['release_version']) else: release = package.sorted_releases[0] return {u'package': package, u'release': release, u'can_edit_role': can_edit_role, }
def render(self): settings = self.request.registry.settings username = authenticated_userid(self.request) if not username: raise exc.HTTPForbidden() remote_user = User.by_login(self.session, username) if not remote_user: raise exc.HTTPForbidden() params = self.request.params if (asbool(settings['pyshop.upload.satanize']) and not re.match(settings['pyshop.upload.satanize.regex'], params['version'] )): raise exc.HTTPForbidden() pkg = Package.by_name(self.session, params['name']) if pkg: auth = [user for user in pkg.owners + pkg.maintainers if user == remote_user] if not auth: raise exc.HTTPForbidden() else: pkg = Package(name=params['name'], local=True) pkg.owners.append(remote_user) content = self.request.POST['content'] input_file = content.file # rewrite the filename, do not use the posted one for security filename = u'%s-%s.%s' % (params['name'], params['version'], {u'sdist': u'tar.gz', u'bdist_egg': u'egg', u'bdist_msi': u'msi', u'bdist_dmg': u'zip', # XXX or gztar ? u'bdist_rpm': u'rpm', u'bdist_dumb': u'msi', u'bdist_wininst': u'exe', }[params['filetype']]) dir_ = os.path.join(settings['pyshop.repository'], filename[0].lower()) if not os.path.exists(dir_): os.mkdir(dir_, 0750) filepath = os.path.join(dir_, filename) while os.path.exists(filepath): log.warn('File %s exists but new upload self.request, deleting' % filepath) os.unlink(filepath) size = 0 with open(filepath, 'wb') as output_file: input_file.seek(0) while True: data = input_file.read(2<<16) if not data: break size += len(data) output_file.write(data) release = Release.by_version(self.session, pkg.name, params['version']) if not release: release = Release(package=pkg, version=params['version'], summary=params.get('summary'), author=remote_user, home_page=params.get('home_page'), license=params.get('license'), description=params.get('description'), keywords=params.get('keywords'), platform=params.get('platform'), download_url=params.get('download_url'), docs_url=params.get('docs_url'), ) classifiers = params.getall('classifiers') for name in classifiers: classifier = Classifier.by_name(self.session, name) while classifier: if classifier not in release.classifiers: release.classifiers.append(classifier) if classifier not in pkg.classifiers: pkg.classifiers.append(classifier) classifier = classifier.parent rfile = ReleaseFile.by_filename(self.session, release, filename) if not rfile: rfile = ReleaseFile(release=release, filename=filename, size=size, md5_digest=params.get('md5_digest'), package_type=params['filetype'], python_version=params.get('pyversion'), comment_text=params.get('comment'), ) self.session.add(rfile) self.session.add(release) pkg.update_at = func.now() self.session.add(pkg) return {'release_file': rfile}
def _create_release(self, package, data, session_users): log.info('Create release %s for package %s', data.get('version'), package.name) data = self._to_unicode(data) release = Release(package=package, summary=data.get('summary'), version=data.get('version'), stable_version=data.get('stable_version'), home_page=data.get('home_page'), license=data.get('license'), description=data.get('description'), keywords=data.get('keywords'), platform=data.get('platform'), download_url=data.get('download_url'), bugtrack_url=data.get('bugtrack_url'), docs_url=data.get('docs_url'), ) if data.get('author'): log.info('Looking for author %s', data['author']) if _sanitize(data['author']) in session_users: author = session_users[_sanitize(data['author'])] else: author = User.by_login(self.session, data['author'], local=False) if not author: log.info('Author %s not found, creating', data['author']) author = User(login=data['author'], local=False, email=data.get('author_email')) self.session.add(author) session_users[_sanitize(data['author'])] = author release.author = author self.session.flush() if data.get('maintainer'): log.info('Looking for maintainer {0}'.format(data['maintainer'])) if _sanitize(data['maintainer']) in session_users: maintainer = session_users[_sanitize(data['maintainer'])] else: maintainer = User.by_login(self.session, data['maintainer'], local=False) if not maintainer: log.info('Maintainer not found, creating user {0}' ''.format(data['maintainer'])) maintainer = User(login=data['maintainer'], local=False, email=data.get('maintainer_email')) self.session.add(maintainer) session_users[_sanitize(data['maintainer'])] = maintainer release.maintainer = maintainer self.session.flush() for name in data.get('classifiers', []): classifier = Classifier.by_name(self.session, name.decode('utf-8'), create_if_not_exists=True) while classifier: if classifier not in release.classifiers: release.classifiers.append(classifier) if classifier not in package.classifiers: package.classifiers.append(classifier) classifier = classifier.parent self.session.flush() return release
def render(self): settings = self.request.registry.settings if not self.user: raise exc.HTTPForbidden() params = self.request.params if (asbool(settings['pyshop.upload.sanitize']) and not re.match(settings['pyshop.upload.sanitize.regex'], params['version'] )): raise exc.HTTPForbidden( "Provided version ({}) should match ""regexp {}" .format(params['version'], settings['pyshop.upload.sanitize.regex'])) pkg = Package.by_name(self.session, params['name']) if pkg and pkg.local: auth = [user for user in pkg.owners + pkg.maintainers if user == self.user] if not auth: raise exc.HTTPForbidden() elif not pkg: pkg = Package(name=params['name'], local=True) pkg.owners.append(self.user) content = self.request.POST['content'] input_file = content.file if asbool(settings.get('pyshop.upload.rewrite_filename', '1')): # rewrite the filename, do not use the posted one for security filename = self._guess_filename(params, content.filename) else: filename = content.filename dir_ = os.path.join(settings['pyshop.repository'], filename[0].lower()) if not os.path.exists(dir_): os.makedirs(dir_, 0o750) filepath = os.path.join(dir_, filename) while os.path.exists(filepath): log.warning('File %s exists but new upload self.request, deleting', filepath) os.unlink(filepath) size = 0 with open(filepath, 'wb') as output_file: input_file.seek(0) while True: data = input_file.read(2 << 16) if not data: break size += len(data) output_file.write(data) release = Release.by_version(self.session, pkg.name, params['version']) if not release: release = Release(package=pkg, version=params['version'], summary=params.get('summary'), author=self.user, home_page=params.get('home_page'), license=params.get('license'), description=params.get('description'), keywords=params.get('keywords'), platform=params.get('platform'), download_url=params.get('download_url'), docs_url=params.get('docs_url'), ) classifiers = params.getall('classifiers') for name in classifiers: classifier = Classifier.by_name(self.session, name, create_if_not_exists=True) while classifier: if classifier not in release.classifiers: release.classifiers.append(classifier) if classifier not in pkg.classifiers: pkg.classifiers.append(classifier) classifier = classifier.parent rfile = ReleaseFile.by_filename(self.session, release, filename) if not rfile: rfile = ReleaseFile(release=release, filename=filename, size=size, md5_digest=params.get('md5_digest'), package_type=params['filetype'], python_version=params.get('pyversion'), comment_text=params.get('comment'), ) self.session.add(rfile) self.session.add(release) pkg.update_at = func.now() self.session.add(pkg) return {'release_file': rfile}
def setUpModule(): engine = create_engine(settings) populate(engine, interactive=False) session = DBSession() admin_user = User.by_login(session, u'admin') local_user = User(login=u'local_user', password=u'secret', local=True, firstname=u'Local', lastname=u'User') local_user.groups.append(Group.by_name(session, u'developer')) jdo = User(login=u'johndo', local=False) jdoe = User(login=u'janedoe', local=False) session.add(jdo) session.add(jdoe) session.add(local_user) classifiers_names = [ u'Programming Language :: Python', u'Programming Language :: Python :: 2.6', u'Programming Language :: Python :: 2.7', u'Topic :: Software Development', u'Topic :: System :: Archiving :: Mirroring', u'Topic :: System :: Archiving :: Packaging', u'Intended Audience :: Developers', u'Intended Audience :: System Administrators' ] classifiers = [ Classifier.by_name(session, name=c, create_if_not_exists=True) for c in classifiers_names ] pack1 = Package(name=u'mirrored_package1') pack1.owners.append(jdo) pack1.owners.append(jdoe) pack1.downloads = 7 session.add(pack1) release1 = Release(package=pack1, version=u'0.1', summary=u'Common Usage Library', author=jdoe) for c in classifiers[:3]: release1.classifiers.append(c) session.add(release1) release1.files.append( ReleaseFile(filename=u'mirrored_package1-0.1.tar.gz', package_type=u'sdist')) session.add(release1) release2 = Release(package=pack1, version=u'0.2', summary=u'Common Usage Library') for c in classifiers[:5]: release2.classifiers.append(c) release2.files.append( ReleaseFile(filename=u'mirrored_package1-0.2.tar.gz', package_type=u'sdist')) release2.files.append( ReleaseFile(filename=u'mirrored_package1-0.2.egg', package_type=u'bdist_egg')) session.add(release2) pack2 = Package(name=u'mirrored_package2') pack2.owners.append(jdo) pack2.maintainers.append(jdoe) pack2.downloads = 1 session.add(pack2) release3 = Release(package=pack2, version=u'1.0', summary=u'Web Framework For Everybody') for c in classifiers[:3] + classifiers[-2:-2]: release3.classifiers.append(c) session.add(release3) release3.files.append( ReleaseFile(filename=u'mirrored_package2-1.0.tar.gz', package_type=u'sdist')) session.add(release3) pack3 = Package(name=u'local_package1', local=True) pack3.owners.append(local_user) pack3.owners.append(admin_user) session.add(pack3) release4 = Release(package=pack3, version=u'0.1', summary=u'Pet Shop Application') for c in classifiers: release4.classifiers.append(c) release4.files.append( ReleaseFile(filename=u'local_package1-0.1.tar.gz', package_type=u'sdist')) session.add(release4) session.commit()