* Support Launchpadlib 1.9. (LP: #725231, #725092)

- Document Launchpadlib 1.9 issues in NEWS.
* Remove manage-credentials, and credential handling code from
  ubuntutools.lp.libsupport. Launchpadlib 1.9 handles this via
  python-keyring. (LP: #387297, #645629, #689100)
* Use Launchpadlib.login_with() directly in scripts.
* Remove ubuntutools.lp.libsupport.approve_application, no longer used.
* Remove ubuntutools.lp.libsupport.get_launchpad, no longer used.
* Remove ubuntutools.lp.libsupport.translate_api_web, no longer used.
* Skip pylint test if it crashes.
This commit is contained in:
Stefano Rivera 2011-03-01 15:04:16 +02:00
commit c409ef2e4d
19 changed files with 63 additions and 336 deletions

View File

@ -28,8 +28,9 @@ import logging
import glob
import fnmatch
from launchpadlib.launchpad import Launchpad
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad
COMMAND_LINE_SYNTAX_ERROR = 1
VERSION_DETECTION_FAILED = 2
@ -148,7 +149,7 @@ def unsubscribe_sponsors(launchpad, bug):
def ack_sync(bug_numbers, all_package, all_version, all_section, update,
all_uploader_email, key, upload, lpinstance, pbuilder, sbuild, lvm,
piuparts, verbose=False, silent=False):
launchpad = get_launchpad("ubuntu-dev-tools", server=lpinstance)
launchpad = Launchpad.login_with("ubuntu-dev-tools", lpinstance)
# TODO: use release-info (once available)
series = launchpad.distributions["ubuntu"].current_series
dist = series.name

17
debian/NEWS vendored Normal file
View File

@ -0,0 +1,17 @@
ubuntu-dev-tools (0.119) unstable; urgency=low
launchpadlib 1.9 will cause some issues, as it uses the GNOME Keyring / KDE
wallet to store credentials.
https://help.launchpad.net/API/ThirdPartyIntegration
Known issues and workarounds:
Seeing keyring.backend.PasswordSetError or gnomekeyring.IOError when
using ubuntu-dev-tools on a remote machine?
Try ssh -X and run export `dbus-launch` in the ssh session.
Otherwise, uninstalling python-gnomekeyring will force the credentials to be
stored in ~/keyring_pass.cfg instead of a keyring, and bypass all these
issues.
-- Stefano Rivera <stefanor@debian.org> Tue, 01 Mar 2011 15:01:01 +0200

15
debian/changelog vendored
View File

@ -1,3 +1,18 @@
ubuntu-dev-tools (0.119) UNRELEASED; urgency=low
* Support Launchpadlib 1.9. (LP: #725231, #725092)
- Document Launchpadlib 1.9 issues in NEWS.
* Remove manage-credentials, and credential handling code from
ubuntutools.lp.libsupport. Launchpadlib 1.9 handles this via
python-keyring. (LP: #387297, #645629, #689100)
* Use Launchpadlib.login_with() directly in scripts.
* Remove ubuntutools.lp.libsupport.approve_application, no longer used.
* Remove ubuntutools.lp.libsupport.get_launchpad, no longer used.
* Remove ubuntutools.lp.libsupport.translate_api_web, no longer used.
* Skip pylint test if it crashes.
-- Stefano Rivera <stefanor@debian.org> Tue, 01 Mar 2011 01:00:44 +0200
ubuntu-dev-tools (0.118) unstable; urgency=low
* requestsync: Use from...import require_utf8() to work around unexpected

1
debian/control vendored
View File

@ -88,7 +88,6 @@ Description: useful tools for Ubuntu developers
- lp-list-bugs - briefly list status of Launchpad bugs.
- lp-project-upload - upload a release tarball to a Launchpad project
- lp-set-dup - sets the "duplicate of" bug of a bug and its dups.
- manage-credentials - manage Launchpad token credentials.
- massfile - fill multiple bugs using a template.
- merge-changelog - manually merges two Debian changelogs with the same base
version.

2
debian/copyright vendored
View File

@ -129,7 +129,6 @@ Files: dch-repeat
doc/get-build-deps.1
doc/grep-merges.1
doc/lp-list-bugs.1
doc/manage-credentials.1
doc/mk-sbuild.1
doc/pull-lp-source.1
doc/pull-revu-source.1
@ -138,7 +137,6 @@ Files: dch-repeat
get-build-deps
grep-merges
lp-list-bugs
manage-credentials
mk-sbuild
pull-lp-source
pull-revu-source

View File

@ -1,69 +0,0 @@
.TH MANAGE-CREDENTIALS "1" "13 January 2009" "ubuntu-dev-tools"
.SH NAME
manage-credentials \- a tool to create (and manage) credentials which
are used to access launchpad via the API.
.SH SYNOPSIS
.B manage-credentials create -c <consumer> [--email <email> --password <password>] [--service <staging|edge>]
.br
.B manage-credentials \-h
.SH DESCRIPTION
\fBmanage-credentials\fR is a tool to create (and manage) credentials which
are used to access Launchpad via the API.
.PP
Currently this tool can be used
to create a token with or without using the web UI. In the future, once
related methods are available through the API, this tool can also be used
to manage tokens in launchpad and on the users local machine.
.SH OPTIONS
Listed below are the command line options for requestsync:
.TP
.B \-h
Display a help message and exit.
.TP
.B \-c \-\-consumer
.TP
.B \-e \-\-email <email>
Your email address as registered on Launchpad.
.TP
.B \-p \-\-password <password>
Your Launchpad password.
.TP
.B \-s \-\-service <edge|staging>
If we should use the edge or staging root of the Launchpad API.
.TP
.B \-\-cache
Where to store the cache.
.TP
.B \-o
Which file we should save the credentials to. By default
\fBmanage-credentials\fR writes the credentials tokens to the
~/.cache/lp_credentials/ directory.
.TP
.B \-l \-\-level <number>
A number representing the access-level you wish to give to the new
Launchpad token. 0 is unauthorized, 1 is read public data, 2; write public data,
3; read private data and 4; write private data.
.SH EXAMPLE USAGE
To get Launchpad tokens using \fBmanage-credentials\fR, run the following command:
.TP
manage-credentials create \-c CONSUMER \-\-level 2
.TP
This will open your web browser with a Launchpad login page.
.TP
If you intend to use manage-credentials for Ubuntu development (such as
the ubuntu-dev-tools package). Please be sure to run the following:
.TP
manage-credentials create \-c ubuntu-dev-tools \-l 2
.SH AUTHOR
.B manage-credentials
was written by Markus Korn <thekorn@gmx.de> and this manual page was written by
Jonathan Davies <jpds@ubuntu.com>.
.PP
Both are released under the GNU General Public License, version 3.

View File

@ -33,8 +33,7 @@ answer the question about upload permissions honestly to determine if a team
with approval rights is to be subscribed to the bug.
.PP
\fBrequestsync\fR uses launchpadlib authentication to file its requests. Please
see manage-credentials(1) for more information.
\fBrequestsync\fR uses launchpadlib authentication to file its requests.
.SH OPTIONS
Listed below are the command line options for requestsync:

View File

@ -23,8 +23,9 @@ from optparse import OptionParser
import os
import sys
from launchpadlib.launchpad import Launchpad
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad
USAGE = "grab-attachments <bug numbers>"
@ -45,7 +46,7 @@ def main():
opts.lpinstance = config.get_value('LPINSTANCE')
try:
launchpad = get_launchpad("ubuntu-dev-tools", server=opts.lpinstance)
launchpad = Launchpad.login_with("ubuntu-dev-tools", opts.lpinstance)
for arg in args:
try:

View File

@ -32,7 +32,9 @@
import sys
from optparse import OptionParser
from ubuntutools.lp.libsupport import (get_launchpad, translate_web_api)
from launchpadlib.launchpad import Launchpad
from ubuntutools.lp.libsupport import translate_web_api
def check_args():
howmany = -1
@ -87,7 +89,7 @@ def main():
launchpad = None
try:
launchpad = get_launchpad("ubuntu-dev-tools")
launchpad = Launchpad.login_with("ubuntu-dev-tools", 'production')
except IOError, error:
print error
sys.exit(1)

View File

@ -34,8 +34,9 @@ except ImportError:
"this utility.")
sys.exit(1)
from launchpadlib.launchpad import Launchpad
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad
def main():
bug_re = re.compile(r"bug=(\d+)")
@ -73,7 +74,7 @@ def main():
options.lpinstance = config.get_value("LPINSTANCE")
try:
launchpad = get_launchpad("ubuntu-dev-tools", options.lpinstance)
launchpad = Launchpad.login_with("ubuntu-dev-tools", options.lpinstance)
except IOError, msg:
print msg
print "No credentials, can't continue"

View File

@ -23,10 +23,9 @@
# Colin Watson <cjwatson@ubuntu.com>
import sys
from optparse import OptionParser
from ubuntutools.lp.libsupport import get_launchpad
from launchpadlib.launchpad import Launchpad
from launchpadlib.errors import HTTPError
def main():
@ -37,7 +36,7 @@ def main():
parser.error("Need at least one bug number")
try:
launchpad = get_launchpad('ubuntu-dev-tools')
launchpad = Launchpad.login_with('ubuntu-dev-tools', 'production')
except Exception, error:
print >> sys.stderr, 'Could not connect to Launchpad:', str(error)
sys.exit(2)

View File

@ -24,7 +24,7 @@ import subprocess
import sys
import tempfile
from ubuntutools.lp.libsupport import get_launchpad
from launchpadlib.launchpad import Launchpad
from launchpadlib.errors import HTTPError
def create_release(project, version):
@ -88,7 +88,7 @@ def main():
(project, version, tarball) = sys.argv[1:]
try:
launchpad = get_launchpad('ubuntu-dev-tools')
launchpad = Launchpad.login_with('ubuntu-dev-tools', 'production')
except Exception, error:
print >> sys.stderr, 'Could not connect to Launchpad:', str(error)
sys.exit(2)

View File

@ -25,9 +25,9 @@
import sys
from optparse import OptionParser
from launchpadlib.launchpad import Launchpad
from launchpadlib.errors import HTTPError
import ubuntutools.lp.libsupport as lp_libsupport
from ubuntutools.config import UDTConfig
def die(message):
@ -60,14 +60,10 @@ def main():
launchpad = None
try:
print "Setting up Launchpad"
launchpad = lp_libsupport.get_launchpad("ubuntu-dev-tools",
server=options.lpinstance)
launchpad = Launchpad.login_with("ubuntu-dev-tools", options.lpinstance)
print "Launchpad setup complete"
except ImportError:
suggestion = "check whether python-launchpadlib is installed"
except IOError:
suggestion = "you might want to \"manage-credentials create " + \
"--consumer ubuntu-dev-tools --level 2\""
if launchpad is None:
die("Couldn't setup Launchpad for the ubuntu-dev-tools consumer; %s" % \
(suggestion, ))

View File

@ -1,132 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Markus Korn <thekorn@gmx.de>
#
# ##################################################################
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# See file /usr/share/common-licenses/GPL for more details.
#
# ##################################################################
import os
import sys
from optparse import OptionParser, make_option
from launchpadlib.uris import lookup_service_root
from ubuntutools.lp.libsupport import Launchpad, translate_api_web, LEVEL
class CmdOptions(OptionParser):
USAGE = (
"\t%prog create -c <consumer> [--service <staging|production>]"
)
OPTIONS = (
make_option("-c", "--consumer", action="store", type="string",
dest="consumer", default=None),
make_option("-s", "--service", action="store", type="string",
dest="service", default="production"),
make_option("--cache", action="store", type="string",
dest="cache", default=None),
make_option("-o", action="store", type="string",
dest="output", default=None),
make_option("-l", "--level", action="store", type="int",
dest="level", default=0,
help="integer representing the access-level (default: 0), "
"mapping: %s" % LEVEL),
)
TOOLS = {
"create": ( ("consumer",),
("service", "cache", "output",
"level")),
"list": (tuple(), ("service", )),
}
def __init__(self):
OptionParser.__init__(self, option_list=self.OPTIONS)
self.set_usage(self.USAGE)
def parse_args(self, args=None, values=None):
options, args = OptionParser.parse_args(self, args, values)
given_options = set(i for i, k in self.defaults.iteritems()
if not getattr(options, i) == k)
if not args:
self.error("Please define a sub-tool you would like to use")
if not len(args) == 1:
self.error("Only one sub-tool allowed")
else:
tool = args.pop()
if not tool in self.TOOLS:
self.error("Unknown tool '%s'" %tool)
needed_options = set(self.TOOLS[tool][0]) - given_options
if needed_options:
self.error("Please define the following options: %s" % \
", ".join(needed_options))
optional_options = given_options - set(sum(self.TOOLS[tool], ()))
if optional_options:
self.error("The following options are not allowed for this tool: "
"%s" % ", ".join(optional_options))
options.service = lookup_service_root(options.service)
if options.level in LEVEL:
options.level = LEVEL[options.level]
elif options.level.upper() in LEVEL.values():
options.level = options.level.upper()
else:
self.error("Unknown access-level '%s', level must be in %s" %
(options.level, LEVEL))
return tool, options
def create_credentials(options):
launchpad = Launchpad.get_token_and_login(options.consumer,
options.service, options.cache)
credentials = launchpad.credentials
if options.output:
filepath = options.output
else:
credentials_dir = os.path.expanduser("~/.cache/lp_credentials")
if not os.path.isdir(credentials_dir):
os.makedirs(credentials_dir)
os.chmod(credentials_dir, 0700)
filepath = os.path.expanduser("%s/%s-%s.txt" %
(credentials_dir, options.consumer,
str(options.level).lower()))
f = open(filepath, "w")
# Make credentials file non-world readable.
os.chmod(filepath, 0600)
credentials.save(f)
f.close()
print "Credentials successfully written to %s." % filepath
return
def list_tokens(options):
print "Not implemented yet."
print ("To get a list of your tokens, please visit "
"%speople/+me/+oauth-tokens") % translate_api_web(options.service)
return 1
def main():
cmdoptions = CmdOptions()
tool, options = cmdoptions.parse_args()
if tool == "create":
return create_credentials(options)
elif tool == "list":
return list_tokens(options)
if __name__ == "__main__":
sys.exit(main())

View File

@ -28,9 +28,10 @@ import os
import sys
import email
from launchpadlib.launchpad import Launchpad
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import (get_launchpad,
translate_web_api)
from ubuntutools.lp.libsupport import translate_web_api
def read_config():
instructions_file = open("instructions")
@ -164,7 +165,7 @@ def main():
if not check_configfiles():
sys.exit(1)
launchpad = get_launchpad('ubuntu-dev-tools', server=options.lpinstance)
launchpad = Launchpad.login_with('ubuntu-dev-tools', options.lpinstance)
config = read_config()
pack_list = read_list()
buglist = read_buglist(config["buglist-url"], launchpad)

View File

@ -32,7 +32,6 @@ scripts = ['404main',
'lp-project-upload',
'lp-set-dup',
'lp-shell',
'manage-credentials',
'massfile',
'merge-changelog',
'mk-sbuild',

View File

@ -19,69 +19,8 @@
#
# Modules.
import glob
import os
import sys
import urllib
import urlparse
import httplib2
try:
from launchpadlib.credentials import Credentials
from launchpadlib.launchpad import Launchpad
from launchpadlib.errors import HTTPError
except ImportError:
print ("Unable to import launchpadlib module, is python-launchpadlib "
"installed?")
sys.exit(1)
except:
Credentials = None
Launchpad = None
from ubuntutools.lp import (service, api_version)
def find_credentials(consumer, files, level=None):
""" search for credentials matching 'consumer' in path for given access
level. """
if Credentials is None:
raise ImportError
for f in files:
cred = Credentials()
try:
cred.load(open(f))
except:
continue
if cred.consumer.key == consumer:
return cred
raise IOError("No credentials found for '%s', please see the "
"manage-credentials manpage for help on how to create "
"one for this consumer." % consumer)
def get_credentials(consumer, cred_file=None, level=None):
files = list()
if cred_file:
files.append(cred_file)
if "LPCREDENTIALS" in os.environ:
files.append(os.environ["LPCREDENTIALS"])
files.append(os.path.join(os.getcwd(), "lp_credentials.txt"))
# Add all files which have our consumer name to file listing.
for x in glob.glob(os.path.expanduser("~/.cache/lp_credentials/%s*.txt" %
consumer)):
files.append(x)
return find_credentials(consumer, files, level)
def get_launchpad(consumer, server=service, cache=None,
cred_file=None, level=None):
credentials = get_credentials(consumer, cred_file, level)
cache = cache or os.environ.get("LPCACHE", None)
return Launchpad(credentials, server, cache, version=api_version)
def query_to_dict(query_string):
result = dict()
@ -110,42 +49,3 @@ def translate_web_api(url, launchpad):
url = urlparse.urlunsplit((scheme, netloc, api_path + path.lstrip("/"),
query, fragment))
return url
def translate_api_web(self_url):
return self_url.replace("api.", "").replace("%s/" % (api_version), "")
LEVEL = {
0: "UNAUTHORIZED",
1: "READ_PUBLIC",
2: "WRITE_PUBLIC",
3: "READ_PRIVATE",
4: "WRITE_PRIVATE"
}
def approve_application(credentials, email, password, level, web_root,
context):
authorization_url = credentials.get_request_token(context, web_root)
if level in LEVEL:
level = 'field.actions.%s' % LEVEL[level]
elif level in LEVEL.values():
level = 'field.actions.%s' % level
elif (str(level).startswith("field.actions") and
str(level).split(".")[-1] in LEVEL):
pass
else:
raise ValueError("Unknown access level '%s'" %level)
params = {level: 1,
"oauth_token": credentials._request_token.key,
"lp.context": context or ""}
lp_creds = ":".join((email, password))
basic_auth = "Basic %s" % (lp_creds.encode('base64'))
headers = {'Authorization': basic_auth}
response, content = httplib2.Http().request(authorization_url,
method="POST", body=urllib.urlencode(params), headers=headers)
if int(response["status"]) != 200:
if not 300 <= int(response["status"]) <= 400: # this means redirection
raise HTTPError(response, content)
credentials.exchange_request_token_for_access_token(web_root)
return credentials

View File

@ -26,11 +26,10 @@
import sys
import launchpadlib.launchpad as launchpad
from launchpadlib.launchpad import Launchpad as LP
from launchpadlib.errors import HTTPError
from lazr.restfulclient.resource import Entry
import ubuntutools.lp.libsupport as libsupport
from ubuntutools.lp import (service, api_version)
from ubuntutools.lp.udtexceptions import (AlreadyLoggedInError,
ArchiveNotFoundException,
@ -58,8 +57,8 @@ class _Launchpad(object):
'''Enforce a non-anonymous login.'''
if not self.logged_in:
try:
self.__lp = libsupport.get_launchpad('ubuntu-dev-tools',
server=service)
self.__lp = LP.login_with('ubuntu-dev-tools', service,
version=api_version)
except IOError, error:
print >> sys.stderr, 'E: %s' % error
raise
@ -69,8 +68,8 @@ class _Launchpad(object):
def login_anonymously(self, service=service, api_version=api_version):
'''Enforce an anonymous login.'''
if not self.logged_in:
self.__lp = launchpad.Launchpad.login_anonymously(
'ubuntu-dev-tools', service_root=service, version=api_version)
self.__lp = LP.login_anonymously('ubuntu-dev-tools', service,
version=api_version)
else:
raise AlreadyLoggedInError('Already logged in to Launchpad.')

View File

@ -45,7 +45,8 @@ class PylintTestCase(unittest.TestCase):
stderr=subprocess.PIPE, close_fds=True)
out, err = process.communicate()
self.assertEqual(err, '')
if err != '':
raise unittest.SkipTest('pylint crashed :/')
filtered_out = []
detected_in = ''