New Tool: who-can-upload (LP: #876554)

This commit is contained in:
Stefano Rivera 2011-12-02 18:59:46 +02:00
parent 9c20cc13a3
commit e556fdae00
3 changed files with 170 additions and 5 deletions

1
debian/changelog vendored
View File

@ -18,6 +18,7 @@ ubuntu-dev-tools (0.137) UNRELEASED; urgency=low
* mk-sbuild, pbuilder-dist, ubuntu-build: Add armhf.
* pull-debian-source, pull-lp-source: Resolve the source package (via DDE),
if a binary package was requested (LP: #617349)
* New Tool: who-can-upload (LP: #876554)
[ Andreas Moog ]
* sponsor-patch: Check permission to unsubscribe sponsors-team (LP: #896884)

View File

@ -278,11 +278,11 @@ class Archive(BaseWrapper):
resource_type = 'archive'
def __init__(self, *args):
# Don't share between different Archives
if '_binpkgs' not in self.__dict__:
self._binpkgs = dict()
if '_srcpkgs' not in self.__dict__:
self._srcpkgs = dict()
self._binpkgs = {}
self._srcpkgs = {}
self._pkg_uploaders = {}
self._pkgset_uploaders = {}
self._component_uploaders = {}
def getSourcePackage(self, name, series=None, pocket=None):
'''
@ -400,6 +400,40 @@ class Archive(BaseWrapper):
include_binaries=include_binaries
)
def getUploadersForComponent(self, component_name):
'''Get the list of PersonTeams who can upload packages in the
specified component.
'''
if component_name not in self._component_uploaders:
self._component_uploaders[component_name] = sorted(set(
PersonTeam(permission.person_link)
for permission in self._lpobject.getUploadersForComponent(
component_name=component_name
)))
return self._component_uploaders[component_name]
def getUploadersForPackage(self, source_package_name):
'''Get the list of PersonTeams who can upload source_package_name)'''
if source_package_name not in self._pkg_uploaders:
self._pkg_uploaders[source_package_name] = sorted(set(
PersonTeam(permission.person_link)
for permission in self._lpobject.getUploadersForPackage(
source_package_name=source_package_name
)))
return self._pkg_uploaders[source_package_name]
def getUploadersForPackageset(self, packageset, direct_permissions=False):
'''Get the list of PersonTeams who can upload packages in packageset'''
key = (packageset, direct_permissions)
if key not in self._pkgset_uploaders:
self._pkgset_uploaders[key] = sorted(set(
PersonTeam(permission.person_link)
for permission in self._lpobject.getUploadersForPackageset(
packageset=packageset._lpobject,
direct_permissions=direct_permissions,
)))
return self._pkgset_uploaders[key]
class SourcePackagePublishingHistory(BaseWrapper):
'''
@ -703,3 +737,36 @@ class DistributionSourcePackage(BaseWrapper):
Caching class for distribution_source_package objects.
'''
resource_type = 'distribution_source_package'
class Packageset(BaseWrapper):
'''
Caching class for packageset objects.
'''
resource_type = 'packageset'
_lp_packagesets = None
_source_sets = {}
@classmethod
def setsIncludingSource(cls, sourcepackagename, distroseries=None,
direct_inclusion=False):
'''Get the package sets including sourcepackagename'''
if cls._lp_packagesets is None:
cls._lp_packagesets = Launchpad.packagesets
key = (sourcepackagename, distroseries, direct_inclusion)
if key not in cls._source_sets:
params = {
'sourcepackagename': sourcepackagename,
'direct_inclusion': direct_inclusion,
}
if distroseries is not None:
params['distroseries'] = distroseries._lpobject
cls._source_sets[key] = [
Packageset(packageset) for packageset
in cls._lp_packagesets.setsIncludingSource(**params)
]
return cls._source_sets[key]

97
who-can-upload Executable file
View File

@ -0,0 +1,97 @@
#!/usr/bin/python
#
# Copyright (C) 2011, Stefano Rivera <stefanor@ubuntu.com>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import optparse
from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam,
Packageset,
SeriesNotFoundException)
def main():
parser = optparse.OptionParser('%prog [options] package')
parser.add_option('-r', '--release', default=None, metavar='RELEASE',
help='Use RELEASE, rather than the current development '
'release')
parser.add_option('-t', '--list-team-members',
default=False, action='store_true',
help='List all team members of teams with upload rights')
options, args = parser.parse_args()
if len(args) != 1:
parser.error("One (and only one) package must be specified")
package = args[0]
# Need to be logged in to see uploaders:
Launchpad.login()
ubuntu = Distribution('ubuntu')
archive = ubuntu.getArchive()
if options.release is None:
series = ubuntu.getDevelopmentSeries()
else:
try:
series = ubuntu.getSeries(options.release)
except SeriesNotFoundException, e:
parser.error(str(e))
spph = archive.getSourcePackage(package)
component = spph.getComponent()
component_uploader = archive.getUploadersForComponent(
component_name=component)[0]
print "Component (%s)" % component
print "============" + ("=" * len(component))
print_uploaders([component_uploader], options.list_team_members)
packagesets = sorted(Packageset.setsIncludingSource(distroseries=series,
sourcepackagename=package))
if packagesets:
print
print "Packagesets"
print "==========="
for packageset in packagesets:
print
print "%s:" % packageset.name
print_uploaders(archive.getUploadersForPackageset(
packageset=packageset), options.list_team_members)
ppu_uploaders = archive.getUploadersForPackage(source_package_name=package)
if ppu_uploaders:
print
print "Per-Package-Uploaders"
print "====================="
print
print_uploaders(ppu_uploaders, options.list_team_members)
print
if PersonTeam.me.canUploadPackage(archive, series, package, component):
print "You can upload this package"
else:
print "You can not upload this package, yourself."
print ("But you can still contribute to it via the sponsorship "
"process: https://wiki.ubuntu.com/SponsorshipProcess")
def print_uploaders(uploaders, expand_teams=False, prefix=''):
for uploader in sorted(uploaders, key=lambda p: p.display_name):
print ("%s* %s (%s)%s"
% (prefix, uploader.display_name, uploader.name,
' [team]' if uploader.is_team else ''))
if expand_teams and uploader.is_team:
print_uploaders(uploader.participants, True, prefix=prefix + ' ')
if __name__ == '__main__':
main()