mirror of
https://git.launchpad.net/ubuntu-dev-tools
synced 2025-05-13 18:01:28 +00:00
Merge
This commit is contained in:
commit
0e291144a4
3
buildd
3
buildd
@ -31,8 +31,7 @@ from optparse import OptionParser
|
|||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
|
|
||||||
# ubuntu-dev-tools modules.
|
# ubuntu-dev-tools modules.
|
||||||
sys.path.append("/usr/share/ubuntu-dev-tools/")
|
from ubuntutools import common
|
||||||
import common
|
|
||||||
|
|
||||||
# Usage.
|
# Usage.
|
||||||
usage = "%prog <srcpackage> <release> <operation>\n\n"
|
usage = "%prog <srcpackage> <release> <operation>\n\n"
|
||||||
|
79
debian/changelog
vendored
79
debian/changelog
vendored
@ -1,4 +1,64 @@
|
|||||||
ubuntu-dev-tools (0.52) UNRELEASED; urgency=low
|
ubuntu-dev-tools (0.58) UNRELEASED; urgency=low
|
||||||
|
|
||||||
|
* Changes go here.
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Sat, 17 Jan 2009 21:04:55 +0000
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.57) jaunty; urgency=low
|
||||||
|
|
||||||
|
* requestsync: Skip existing bug check if no credentials are
|
||||||
|
found (LP: #318120).
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Sat, 17 Jan 2009 22:02:39 +0000
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.56) jaunty; urgency=low
|
||||||
|
|
||||||
|
* manage-credentials: Tighted security by making credentials files and
|
||||||
|
folder world unreadable.
|
||||||
|
* common.py: Improved no credentials found error message to show which
|
||||||
|
consumer token is needed.
|
||||||
|
* requestsync: Catch credentials error to hide traceback.
|
||||||
|
* Moved common.py to ubuntutools/ subdirectory to avoid possible conflicts
|
||||||
|
in Python packaging and fixed all imports as necessary.
|
||||||
|
* debian/ubuntu-dev-tools.install: Removed common.py entry.
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Sat, 17 Jan 2009 11:32:33 +0000
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.55) jaunty; urgency=low
|
||||||
|
|
||||||
|
* manage-credentials: Use common.py's mkdir function to create as many
|
||||||
|
subdirectories as necessary for the credentials directory (LP: #317317).
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Thu, 15 Jan 2009 12:33:31 +0000
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.54) jaunty; urgency=low
|
||||||
|
|
||||||
|
* manage-credentials:
|
||||||
|
- Save credentials to ~/.cache/lp_credentials/ by
|
||||||
|
default.
|
||||||
|
- Set service option default to edge.
|
||||||
|
* doc/manage-credentials.1: Update as necessary for the above.
|
||||||
|
* common.py:
|
||||||
|
- When credentials are not found, ask user to see
|
||||||
|
manage-credentials manpage.
|
||||||
|
- Load all token files for the consumer specified in the above
|
||||||
|
directory as necessary.
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Wed, 14 Jan 2009 19:39:35 +0000
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.53) jaunty; urgency=low
|
||||||
|
|
||||||
|
[ Siegfried-Angel Gevatter Pujals ]
|
||||||
|
* debian/copyright:
|
||||||
|
- Add information about manage-credentials.
|
||||||
|
|
||||||
|
[ Daniel Holbach ]
|
||||||
|
* debian/control: replace 'sb-release' with lsb-release, make package
|
||||||
|
installable again.
|
||||||
|
|
||||||
|
-- Daniel Holbach <daniel.holbach@ubuntu.com> Wed, 14 Jan 2009 16:27:34 +0100
|
||||||
|
|
||||||
|
ubuntu-dev-tools (0.52) jaunty; urgency=low
|
||||||
|
|
||||||
[ Siegfried-Angel Gevatter Pujals ]
|
[ Siegfried-Angel Gevatter Pujals ]
|
||||||
* pbuilder-dist.new:
|
* pbuilder-dist.new:
|
||||||
@ -32,8 +92,23 @@ ubuntu-dev-tools (0.52) UNRELEASED; urgency=low
|
|||||||
'status'.
|
'status'.
|
||||||
* requestsync: If package is new, check the Ubuntu Archive team's bug list
|
* requestsync: If package is new, check the Ubuntu Archive team's bug list
|
||||||
for possible duplicate requests.
|
for possible duplicate requests.
|
||||||
|
* doc/manage-credentials.1: Written up.
|
||||||
|
* doc/requestsync.1: Changed documentation to launchpadlib related-stuff.
|
||||||
|
|
||||||
-- Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com> Sat, 10 Jan 2009 14:35:14 +0100
|
[ Luca Falavigna ]
|
||||||
|
* requestsync:
|
||||||
|
- Catch AssertionError exception if rmadison returns with an error.
|
||||||
|
|
||||||
|
[ Markus Korn ]
|
||||||
|
* Added manage-credentials, a tool to create (and manage) credentials
|
||||||
|
which are used to access launchpad via the API.
|
||||||
|
* Ported: hugdaylist, massfile, grab-attachment and requestsync to
|
||||||
|
launchpadlib.
|
||||||
|
* Other misc. fixes and tweaks.
|
||||||
|
* Install common.py to correct location with py_modules and remove
|
||||||
|
hardcoded path from files.
|
||||||
|
|
||||||
|
-- Jonathan Davies <jpds@ubuntu.com> Wed, 14 Jan 2009 13:21:35 +0000
|
||||||
|
|
||||||
ubuntu-dev-tools (0.51) jaunty; urgency=low
|
ubuntu-dev-tools (0.51) jaunty; urgency=low
|
||||||
|
|
||||||
|
4
debian/control
vendored
4
debian/control
vendored
@ -14,8 +14,8 @@ Package: ubuntu-dev-tools
|
|||||||
Architecture: all
|
Architecture: all
|
||||||
Section: devel
|
Section: devel
|
||||||
Depends: ${python:Depends}, binutils, devscripts, sudo, python-debian,
|
Depends: ${python:Depends}, binutils, devscripts, sudo, python-debian,
|
||||||
python-launchpad-bugs (>= 0.2.25), dctrl-tools, lsb-release, diffstat,
|
python-launchpad-bugs (>= 0.2.25), python-launchpadlib, dctrl-tools,
|
||||||
dpkg-dev, ${misc:Depends}
|
lsb-release, diffstat, dpkg-dev, ${misc:Depends}
|
||||||
Recommends: bzr, pbuilder | cowdancer | sbuild, reportbug (>= 3.39ubuntu1),
|
Recommends: bzr, pbuilder | cowdancer | sbuild, reportbug (>= 3.39ubuntu1),
|
||||||
ca-certificates, genisoimage, perl-modules, libwww-perl
|
ca-certificates, genisoimage, perl-modules, libwww-perl
|
||||||
Conflicts: devscripts (<< 2.10.7ubuntu5)
|
Conflicts: devscripts (<< 2.10.7ubuntu5)
|
||||||
|
18
debian/copyright
vendored
18
debian/copyright
vendored
@ -13,6 +13,7 @@ Upstream Authors:
|
|||||||
Jordan Mantha <mantha@ubuntu.com>
|
Jordan Mantha <mantha@ubuntu.com>
|
||||||
Kees Cook <kees@ubuntu.com>
|
Kees Cook <kees@ubuntu.com>
|
||||||
Luke Yelavich <themuso@ubuntu.com>
|
Luke Yelavich <themuso@ubuntu.com>
|
||||||
|
Markus Korn <thekorn@gmx.de>
|
||||||
Martin Pitt <martin.pitt@ubuntu.com>
|
Martin Pitt <martin.pitt@ubuntu.com>
|
||||||
Matt Zimmerman <mdz@ubuntu.com>
|
Matt Zimmerman <mdz@ubuntu.com>
|
||||||
Michael Bienia <geser@ubuntu.com>
|
Michael Bienia <geser@ubuntu.com>
|
||||||
@ -30,14 +31,15 @@ Copyright:
|
|||||||
(C) 2006-2007, Albin Tonnerre <lut1n.tne@gmail.com>
|
(C) 2006-2007, Albin Tonnerre <lut1n.tne@gmail.com>
|
||||||
(C) 2006-2007, Daniel Holbach <daniel.holbach@ubuntu.com>
|
(C) 2006-2007, Daniel Holbach <daniel.holbach@ubuntu.com>
|
||||||
(C) 2006-2007, Luke Yelavich <themuso@ubuntu.com>
|
(C) 2006-2007, Luke Yelavich <themuso@ubuntu.com>
|
||||||
|
(C) 2009, Markus Korn <thekorn@gmx.de>
|
||||||
(C) 2007, Martin Pitt <martin.pitt@ubuntu.com>
|
(C) 2007, Martin Pitt <martin.pitt@ubuntu.com>
|
||||||
(C) 2006-2007, Michael Bienia <geser@ubuntu.com>
|
(C) 2006-2007, Michael Bienia <geser@ubuntu.com>
|
||||||
(C) 2006-2008, Kees Cook <kees@ubuntu.com>
|
(C) 2006-2008, Kees Cook <kees@ubuntu.com>
|
||||||
(C) 2006-2007, Pete Savage <petesavage@ubuntu.com>
|
(C) 2006-2007, Pete Savage <petesavage@ubuntu.com>
|
||||||
(C) 2007-2008, Siegfried-A. Gevatter <rainct@ubuntu.com>
|
(C) 2007-2009, Siegfried-A. Gevatter <rainct@ubuntu.com>
|
||||||
(C) 2007, Terence Simpson <stdin@stdin.me.uk>
|
(C) 2007, Terence Simpson <stdin@stdin.me.uk>
|
||||||
(C) 2008, Iain Lane <iain@orangesquash.org.uk>
|
(C) 2008, Iain Lane <iain@orangesquash.org.uk>
|
||||||
(C) 2008, Jonathan Davies <jpds@ubuntu.com>
|
(C) 2008-2009, Jonathan Davies <jpds@ubuntu.com>
|
||||||
(C) 2008, Nathan handler <nhandler@ubuntu.com>
|
(C) 2008, Nathan handler <nhandler@ubuntu.com>
|
||||||
|
|
||||||
Licenses:
|
Licenses:
|
||||||
@ -58,9 +60,10 @@ licensed under the GNU General Public License, version 2:
|
|||||||
On Debian and Ubuntu systems, the complete text of the GNU General Public
|
On Debian and Ubuntu systems, the complete text of the GNU General Public
|
||||||
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||||
|
|
||||||
dch-repeat, get-branches, get-build-deps, massfile, mk-sbuild-lv, ppaput,
|
dch-repeat, get-branches, get-build-deps, manage-credentials, massfile,
|
||||||
pull-debian-debdiff, pull-debian-source, pull-lp-source, suspicious-source and what-patch are
|
mk-sbuild-lv, ppaput, pull-debian-debdiff, pull-debian-source, pull-lp-source,
|
||||||
licensed under the GNU General Public License, version 3:
|
suspicious-source and what-patch are licensed under the GNU General Public
|
||||||
|
License, version 3:
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -76,5 +79,6 @@ License v3 can be found in `/usr/share/common-licenses/GPL-3'.
|
|||||||
|
|
||||||
The following of the scripts can be used, at your option, regarding any
|
The following of the scripts can be used, at your option, regarding any
|
||||||
later version of the previously specified license: 404main, dch-repeat, dgetlp,
|
later version of the previously specified license: 404main, dch-repeat, dgetlp,
|
||||||
get-build-deps, mk-sbuild-lv, pull-debian-debdiff, pull-debian-source, pull-lp-source,
|
get-build-deps, manage-credentials, mk-sbuild-lv, pull-debian-debdiff,
|
||||||
reverse-build-depends, suspicious-source, what-patch.
|
pull-debian-source, pull-lp-source, reverse-build-depends, suspicious-source,
|
||||||
|
what-patch.
|
||||||
|
1
debian/ubuntu-dev-tools.install
vendored
1
debian/ubuntu-dev-tools.install
vendored
@ -1,2 +1 @@
|
|||||||
bash_completion/* etc/bash_completion.d/
|
bash_completion/* etc/bash_completion.d/
|
||||||
common.py usr/share/ubuntu-dev-tools/
|
|
||||||
|
76
doc/manage-credentials.1
Normal file
76
doc/manage-credentials.1
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
.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
|
||||||
|
There are currently two ways of using \fBmanage-credentials\fR to get
|
||||||
|
Launchpad tokens.
|
||||||
|
.TP
|
||||||
|
1) manage-credentials create -c CONSUMER --level 2
|
||||||
|
|
||||||
|
.TP
|
||||||
|
This way shall open your webbrowser with a Launchpad login page.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
2) manage-credentials create -c CONSUMER --level 2 --password BOO --email me@example.com
|
||||||
|
|
||||||
|
.TP
|
||||||
|
This is a hack, but it works and does not require a webbrowser .
|
||||||
|
|
||||||
|
.TP
|
||||||
|
If you intend to use manage-credentials for Ubuntu development (such as
|
||||||
|
the ubuntu-dev-tools package). Please by 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.
|
@ -15,10 +15,10 @@ The changelog entry is then downloaded from packages.debian.org.
|
|||||||
If the sync request is being filed per email (default), a prompt for your
|
If the sync request is being filed per email (default), a prompt for your
|
||||||
GPG passphrase follows so that it can sign the mail and send it off to
|
GPG passphrase follows so that it can sign the mail and send it off to
|
||||||
Launchpad.
|
Launchpad.
|
||||||
Alternatively a sync request can be filed directly using the launchpadbugs
|
Alternatively a sync request can be filed directly using the launchpadlib
|
||||||
python module (option \fB\-\-lp\fR).
|
Python module (option \fB\-\-lp\fR).
|
||||||
\fBrequestsync\fR falls back to mail the sync request if submitting using
|
\fBrequestsync\fR falls back to mail the sync request if submitting using
|
||||||
the launchpadbugs module fails.
|
the launchpadlib module fails.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fBrequestsync\fR checks if you have the permissions to request the sync from
|
\fBrequestsync\fR checks if you have the permissions to request the sync from
|
||||||
@ -29,10 +29,8 @@ If you are not a member of the appropriate team, the script will subscribe
|
|||||||
the necessary team with approval rights to the bug report for you.
|
the necessary team with approval rights to the bug report for you.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fBrequestsync\fR uses a cookie file stored at \fI~/.lpcookie.txt\fR to
|
\fBrequestsync\fR uses launchpadlib authentication to file its requests. Please
|
||||||
authenticate with Launchpad.
|
see manage-credentials(1) for more information.
|
||||||
This cookie is created on run from the Mozilla Firefox cookie file at
|
|
||||||
\fI~/.mozilla/*/*/cookies.sqlite\fR.
|
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
Listed below are the command line options for requestsync:
|
Listed below are the command line options for requestsync:
|
||||||
@ -55,7 +53,7 @@ configuration (for example: \fI$HOME/.bashrc\fR).
|
|||||||
This is only used if the sync request is mailed to Launchpad.
|
This is only used if the sync request is mailed to Launchpad.
|
||||||
.TP
|
.TP
|
||||||
.B \-\-lp
|
.B \-\-lp
|
||||||
Use the launchpadbugs python module (packaged as python\-launchpad\-bugs) to
|
Use the launchpadlib Python module (packaged as python\-launchpadlib) to
|
||||||
file the sync request in Launchpad.
|
file the sync request in Launchpad.
|
||||||
.TP
|
.TP
|
||||||
.B \-s
|
.B \-s
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib
|
from ubuntutools.common import get_launchpad
|
||||||
import launchpadbugs.connector as Connector
|
|
||||||
|
|
||||||
USAGE = "grab-attachments <bug numbers>"
|
USAGE = "grab-attachments <bug numbers>"
|
||||||
|
|
||||||
@ -33,17 +32,21 @@ def main():
|
|||||||
if sys.argv[1] in ["--help", "-h"]:
|
if sys.argv[1] in ["--help", "-h"]:
|
||||||
print USAGE
|
print USAGE
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
Bug = Connector.ConnectBug(method="Text")
|
launchpad = get_launchpad("ubuntu-dev-tools")
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
try:
|
try:
|
||||||
number = int(arg)
|
number = int(arg)
|
||||||
except:
|
except:
|
||||||
print >> sys.stderr, "'%s' is not a valid bug number." % arg
|
print >> sys.stderr, "'%s' is not a valid bug number." % arg
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
b = Bug(number)
|
b = launchpad.bugs[number]
|
||||||
for a in b.attachments:
|
for a in b.attachments:
|
||||||
filename = os.path.join(os.getcwd(), a.url.split("/")[-1])
|
f = a.data.open()
|
||||||
urllib.urlretrieve(a.url, filename)
|
filename = os.path.join(os.getcwd(), f.filename)
|
||||||
|
local_file = open(filename, "w")
|
||||||
|
local_file.write(f.read())
|
||||||
|
f.close()
|
||||||
|
local_file.close()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
56
hugdaylist
56
hugdaylist
@ -35,14 +35,7 @@ import string
|
|||||||
import sys
|
import sys
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
try:
|
from ubuntutools.common import get_launchpad, translate_web_api, translate_api_web
|
||||||
import launchpadbugs.connector as Connector
|
|
||||||
BugList = Connector.ConnectBugList()
|
|
||||||
Bug = Connector.ConnectBug(method="Text")
|
|
||||||
except ImportError:
|
|
||||||
print >> sys.stderr, \
|
|
||||||
"python-launchpad-bugs (>= 0.2.25) needs to be installed to use hugdaylist."
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def check_args():
|
def check_args():
|
||||||
howmany = -1
|
howmany = -1
|
||||||
@ -74,27 +67,41 @@ def check_args():
|
|||||||
|
|
||||||
return (howmany, url)
|
return (howmany, url)
|
||||||
|
|
||||||
def filter_unsolved(b):
|
def filter_unsolved(task):
|
||||||
bug = Bug(int(b))
|
# TODO: don't use this filter here, only check status and assignee of
|
||||||
|
# the given task
|
||||||
# Filter out special types of bugs:
|
# Filter out special types of bugs:
|
||||||
# - https://wiki.ubuntu.com/Bugs/HowToTriage#Special%20types%20of%20bugs
|
# - https://wiki.ubuntu.com/Bugs/HowToTriage#Special%20types%20of%20bugs
|
||||||
return filter(lambda a: a.status != 'Fix Committed' and \
|
subscriptions = set(s.person.name for s in task.bug.subscriptions) #this is expensive, parse name out of self_link instead?
|
||||||
(a.assignee in ['motu','desktop-bugs'] or \
|
if (task.status != "Fix Committed" and
|
||||||
not a.assignee), bug.infotable) and \
|
(not task.assignee or task.assignee.name in ['motu','desktop-bugs']) and
|
||||||
'ubuntu-main-sponsors' not in [str(s) for s in bug.subscribers] and \
|
'ubuntu-main-sponsors' not in subscriptions and
|
||||||
'ubuntu-universe-sponsors' not in [str(s) for s in bug.subscribers] and \
|
'ubuntu-universe-sponsors' not in subscriptions and
|
||||||
'ubuntu-archive' not in [str(s) for s in bug.subscribers]
|
'ubuntu-archive' not in subscriptions):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
(howmany, url) = check_args()
|
(howmany, url) = check_args()
|
||||||
|
if len(url.split("?", 1)) == 2:
|
||||||
try:
|
# search options not supported, because there is no mapping web ui options <-> API options
|
||||||
bl = BugList(url)
|
print >> sys.stderr, "Options in url are not supported, url: %s" %url
|
||||||
except:
|
|
||||||
print >> sys.stderr, "The URL at '%s' does not appear to have a bug " \
|
|
||||||
"list." % url
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
launchpad = get_launchpad("ubuntu-dev-tools")
|
||||||
|
api_url = translate_web_api(url, launchpad)
|
||||||
|
try:
|
||||||
|
product = launchpad.load(api_url)
|
||||||
|
except Exception, e:
|
||||||
|
x = getattr(e, "response", {})
|
||||||
|
if response.get("status", None) == "404":
|
||||||
|
print >> sys.stderr, "The URL at '%s' does not appear to be a valid url to a product" %url
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
bl = product.searchTasks()
|
||||||
|
|
||||||
l = filter(filter_unsolved, bl)
|
l = filter(filter_unsolved, bl)
|
||||||
|
|
||||||
if not l:
|
if not l:
|
||||||
@ -112,13 +119,14 @@ def main():
|
|||||||
|| Bug || Subject || Triager ||"""
|
|| Bug || Subject || Triager ||"""
|
||||||
|
|
||||||
for i in list(l)[:howmany]:
|
for i in list(l)[:howmany]:
|
||||||
|
bug = i.bug
|
||||||
print '||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||' % \
|
print '||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||' % \
|
||||||
(i.url, i.bugnumber, i.summary)
|
(translate_api_web(bug.self_link), bug.id, bug.title)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
main()
|
main()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print >> sys.stderr, "Aborted."
|
print >> sys.stderr, "Aborted."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
137
manage-credentials
Executable file
137
manage-credentials
Executable file
@ -0,0 +1,137 @@
|
|||||||
|
#!/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 ubuntutools.common import Credentials, Launchpad, translate_service
|
||||||
|
from ubuntutools.common import LEVEL, translate_api_web, approve_application
|
||||||
|
from ubuntutools.common import mkdir
|
||||||
|
|
||||||
|
class CmdOptions(OptionParser):
|
||||||
|
|
||||||
|
USAGE = (
|
||||||
|
"\t%prog create -c <consumer> [--email <email> --password <password>] [--service <staging|edge>]\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
OPTIONS = (
|
||||||
|
make_option("-c", "--consumer", action="store", type="string",
|
||||||
|
dest="consumer", default=None),
|
||||||
|
make_option("-e", "--email", action="store", type="string",
|
||||||
|
dest="email", default=None),
|
||||||
|
make_option("-p", "--password", action="store", type="string",
|
||||||
|
dest="password", default=None),
|
||||||
|
make_option("-s", "--service", action="store", type="string",
|
||||||
|
dest="service", default="edge"),
|
||||||
|
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",),
|
||||||
|
("email", "password", "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 = translate_service(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, self.LEVEL))
|
||||||
|
return tool, options
|
||||||
|
|
||||||
|
def create_credentials(options):
|
||||||
|
if options.password and options.email:
|
||||||
|
# use hack
|
||||||
|
credentials = Credentials(options.consumer)
|
||||||
|
credentials = approve_application(credentials, options.email,
|
||||||
|
options.password, options.level,
|
||||||
|
translate_api_web(options.service), None)
|
||||||
|
else:
|
||||||
|
launchpad = Launchpad.get_token_and_login(options.consumer,
|
||||||
|
options.service, options.cache)
|
||||||
|
credentials = launchpad.credentials
|
||||||
|
|
||||||
|
if options.output:
|
||||||
|
filepath = options.output
|
||||||
|
else:
|
||||||
|
credentialsDir = os.path.expanduser("~/.cache/lp_credentials")
|
||||||
|
if not os.path.isdir(credentialsDir):
|
||||||
|
mkdir(credentialsDir)
|
||||||
|
os.chmod(credentialsDir, 0700)
|
||||||
|
filepath = os.path.expanduser("%s/%s-%s.txt" % \
|
||||||
|
(credentialsDir, 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 sucessfully 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())
|
78
massfile
78
massfile
@ -27,12 +27,7 @@ import email
|
|||||||
import subprocess
|
import subprocess
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
import launchpadbugs.connector as Connector
|
from ubuntutools.common import get_launchpad, translate_api_web, translate_web_api
|
||||||
|
|
||||||
sys.path.append('/usr/share/ubuntu-dev-tools/')
|
|
||||||
import common
|
|
||||||
|
|
||||||
cookie = common.prepareLaunchpadCookie()
|
|
||||||
|
|
||||||
def read_config():
|
def read_config():
|
||||||
instructions_file = open("instructions")
|
instructions_file = open("instructions")
|
||||||
@ -57,10 +52,6 @@ def read_list():
|
|||||||
listfile.close()
|
listfile.close()
|
||||||
return pack_list
|
return pack_list
|
||||||
|
|
||||||
def file_bug():
|
|
||||||
Bug = Connector.ConnectBug()
|
|
||||||
Bug.authentication = cookie
|
|
||||||
|
|
||||||
def check_configfiles():
|
def check_configfiles():
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
@ -87,43 +78,62 @@ def check_configfiles():
|
|||||||
|
|
||||||
|
|
||||||
def file_bug(config):
|
def file_bug(config):
|
||||||
Bug = Connector.ConnectBug()
|
launchpad = get_launchpad("ubuntu-dev-tools")
|
||||||
|
|
||||||
Bug.authentication = cookie
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
summary = config["subject"].replace("$pack", config["sourcepackage"])
|
summary = config["subject"].replace("$pack", config["sourcepackage"])
|
||||||
description = config["text"].replace("$pack", config["sourcepackage"])
|
description = config["text"].replace("$pack", config["sourcepackage"])
|
||||||
|
|
||||||
bug = Bug.New(product={"name": config["sourcepackage"],
|
|
||||||
"target": "ubuntu"},
|
product_url = "%subuntu/+source/%s" %(launchpad._root_uri, config["sourcepackage"])
|
||||||
summary=summary,
|
tags = filter(None, map(lambda t: t.strip("\n").strip(), config["tags"].split(",")))
|
||||||
description=description)
|
bug = launchpad.bugs.createBug(description=description, title=summary,
|
||||||
print "Successfully filed bug %s: https://launchpad.net/bugs/%s" % \
|
target=product_url, tags=tags)
|
||||||
(bug.bugnumber, bug.bugnumber)
|
|
||||||
for sub in config["subscribers"].split(","):
|
print "Successfully filed bug %i: %s" %(bug.id, translate_api_web(bug.self_link))
|
||||||
if sub.strip("\n").strip():
|
|
||||||
bug.subscribers.add(sub.strip("\n").strip())
|
subscribers = filter(None, map(lambda t: t.strip("\n").strip(), config["subscribers"].split(",")))
|
||||||
for tag in config["tags"].split(","):
|
for sub in subscribers:
|
||||||
if tag.strip("\n").strip():
|
subscribe_url = "%s~%s" %(launchpad._root_uri, sub)
|
||||||
bug.tags.append(tag.strip("\n").strip())
|
bug.subscribe(person=subscribe_url)
|
||||||
bug.assignee = config["assignee"]
|
|
||||||
|
#newly created bugreports have one task
|
||||||
|
task = bug.bug_tasks[0]
|
||||||
|
|
||||||
if config["status"]:
|
if config["status"]:
|
||||||
bug.status = config["status"].capitalize()
|
status = config["status"].capitalize()
|
||||||
else:
|
else:
|
||||||
bug.status = "Confirmed"
|
status = "Confirmed"
|
||||||
bug.commit()
|
task.transitionToStatus(status=status)
|
||||||
|
|
||||||
|
assignee = config["assignee"]
|
||||||
|
if assignee:
|
||||||
|
assignee_url = "%s~%s" %(launchpad._root_uri, assignee)
|
||||||
|
bug.transitionToAssignee(assignee=assignee_url)
|
||||||
except:
|
except:
|
||||||
"Bug for '%s' was not filed." % config["sourcepackage"]
|
"Bug for '%s' was not filed." % config["sourcepackage"]
|
||||||
|
|
||||||
def read_buglist(url):
|
def read_buglist(url):
|
||||||
BugList = Connector.ConnectBugList()
|
if not url:
|
||||||
|
return set()
|
||||||
|
|
||||||
|
if len(url.split("?", 1)) == 2:
|
||||||
|
# search options not supported, because there is no mapping web ui options <-> API options
|
||||||
|
print >> sys.stderr, "Options in url are not supported, url: %s" %url
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
launchpad = get_launchpad("ubuntu-dev-tools")
|
||||||
packages = set()
|
packages = set()
|
||||||
|
|
||||||
if url:
|
api_url = translate_web_api(url, launchpad)
|
||||||
buglist = BugList(url)
|
# workaround LP #303414
|
||||||
for bug in buglist.bugs:
|
# if this is fixed it should simply be: buglist = launchpad.load(api_url)
|
||||||
packages.add(bug.sourcepackage)
|
api_url = api_url.split("?", 1)[0]
|
||||||
|
project = launchpad.load(api_url)
|
||||||
|
buglist = project.searchTasks()
|
||||||
|
|
||||||
|
for bug in buglist:
|
||||||
|
packages.add(bug.bug_target_name)
|
||||||
|
|
||||||
return packages
|
return packages
|
||||||
|
|
||||||
|
@ -33,8 +33,7 @@ import urllib2
|
|||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
# Ubuntu-dev-tools modules.
|
# Ubuntu-dev-tools modules.
|
||||||
sys.path.append("/usr/share/ubuntu-dev-tools")
|
from ubuntutools import common
|
||||||
import common
|
|
||||||
|
|
||||||
class BackportFromLP:
|
class BackportFromLP:
|
||||||
|
|
||||||
|
117
requestsync
117
requestsync
@ -9,6 +9,7 @@
|
|||||||
# Daniel Hahler <ubuntu@thequod.de>
|
# Daniel Hahler <ubuntu@thequod.de>
|
||||||
# Iain Lane <iain@orangesquash.org.uk>
|
# Iain Lane <iain@orangesquash.org.uk>
|
||||||
# Jonathan Davies <jpds@ubuntu.com>
|
# Jonathan Davies <jpds@ubuntu.com>
|
||||||
|
# Markus Korn <thekorn@gmx.de> (python-launchpadlib support)
|
||||||
#
|
#
|
||||||
# ##################################################################
|
# ##################################################################
|
||||||
#
|
#
|
||||||
@ -34,9 +35,7 @@ from debian_bundle.changelog import Version
|
|||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
# Use functions from ubuntu-dev-tools to create Launchpad cookie file.
|
from ubuntutools import common
|
||||||
sys.path.append('/usr/share/ubuntu-dev-tools/')
|
|
||||||
import common
|
|
||||||
|
|
||||||
launchpad_cookiefile = common.prepareLaunchpadCookie()
|
launchpad_cookiefile = common.prepareLaunchpadCookie()
|
||||||
|
|
||||||
@ -54,6 +53,11 @@ def checkNeedsSponsorship(component):
|
|||||||
The prepareLaunchpadCookie function above shall ensure that a cookie
|
The prepareLaunchpadCookie function above shall ensure that a cookie
|
||||||
file exists first.
|
file exists first.
|
||||||
"""
|
"""
|
||||||
|
# TODO: use launchpadlib here
|
||||||
|
# Once LP: #313233 has been fixed this can be implemented by either:
|
||||||
|
# >>> me = launchpad.me
|
||||||
|
# >>> me.inTeam(<TEAM>) #or
|
||||||
|
# >>> me in <TEAM>
|
||||||
urlopener = common.setupLaunchpadUrlOpener(launchpad_cookiefile)
|
urlopener = common.setupLaunchpadUrlOpener(launchpad_cookiefile)
|
||||||
|
|
||||||
# Check where the package is and assign the appropriate variables.
|
# Check where the package is and assign the appropriate variables.
|
||||||
@ -85,52 +89,47 @@ def checkNeedsSponsorship(component):
|
|||||||
# Is a team member, no sponsorship required.
|
# Is a team member, no sponsorship required.
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def checkExistingReports(package, isNewPackage):
|
def checkExistingReports(package):
|
||||||
""" Check existing bug reports on Launchpad for a possible sync request.
|
""" Check existing bug reports on Launchpad for a possible sync request.
|
||||||
|
|
||||||
If found ask for confirmation on filing a request.
|
If found ask for confirmation on filing a request.
|
||||||
"""
|
"""
|
||||||
# Determine if the package is new or not.
|
|
||||||
if isNewPackage:
|
launchpad = None
|
||||||
# Package not in Ubuntu, check Ubuntu Archive Team's bug page for
|
|
||||||
# possible duplicate reports.
|
|
||||||
bugListUrl = "https://bugs.launchpad.net/~ubuntu-archive"
|
|
||||||
else:
|
|
||||||
# Package in Ubuntu, check the package's bug list for duplicate reports.
|
|
||||||
bugListUrl = "https://bugs.launchpad.net/ubuntu/+source/%s" % package
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import launchpadbugs.connector as Connector
|
launchpad = common.get_launchpad("ubuntu-dev-tools")
|
||||||
except:
|
except ImportError:
|
||||||
# Failed to import launchpadbugs - skip check.
|
print >> sys.stderr, 'Importing launchpadlib failed. Is ' \
|
||||||
print >> sys.stderr, "Unable to import launchpadbugs. Is " \
|
'python-launchpadlib installed?'
|
||||||
"python-launchpad-bugs installed?"
|
except IOError, msg:
|
||||||
|
# No credentials found.
|
||||||
|
print msg
|
||||||
|
|
||||||
|
# Failed to get Launchpad credentials.
|
||||||
|
if launchpad is None:
|
||||||
print >> sys.stderr, "Skipping existing report check, you should "\
|
print >> sys.stderr, "Skipping existing report check, you should "\
|
||||||
"manually check at:"
|
"manually see if there are any at:"
|
||||||
print "-", bugListUrl
|
print "- https://bugs.launchpad.net/ubuntu/+source/%s" % package
|
||||||
return
|
print ""
|
||||||
|
return False
|
||||||
|
|
||||||
# Connect to the bug list.
|
# Fetch the package's bug list from Launchpad.
|
||||||
bugList = Connector.ConnectBugList()
|
pkg = launchpad.distributions["ubuntu"].getSourcePackage(name=package)
|
||||||
|
pkgBugList = pkg.searchTasks()
|
||||||
# Fetch data from Launchpad.
|
|
||||||
pkgBugList = bugList(bugListUrl)
|
|
||||||
|
|
||||||
if len(pkgBugList) == 0:
|
|
||||||
return # No bugs found.
|
|
||||||
|
|
||||||
# Search bug list for other sync requests.
|
# Search bug list for other sync requests.
|
||||||
matchingBugs = [bug for bug in pkgBugList if "Please sync %s" %
|
matchingBugs = [bug for bug in pkgBugList if "Please sync %s" %
|
||||||
package in bug.summary]
|
package in bug.title]
|
||||||
|
|
||||||
if len(matchingBugs) == 0:
|
if len(matchingBugs) == 0:
|
||||||
return # No sync bugs found.
|
return # No sync bugs found.
|
||||||
|
|
||||||
print "The following bugs could possibly be duplicate sync request(s) on Launchpad:"
|
print "The following bugs could be possible duplicate sync bug(s) on Launchpad:"
|
||||||
|
|
||||||
for bug in matchingBugs:
|
for bug in matchingBugs:
|
||||||
print " *", bug.summary
|
print " *", bug.title
|
||||||
print " -", bug.url
|
print " -", common.translate_api_web(bug.self_link)
|
||||||
|
|
||||||
print "Please check the above URLs to verify this before filing a " \
|
print "Please check the above URLs to verify this before filing a " \
|
||||||
"possible duplicate report."
|
"possible duplicate report."
|
||||||
@ -317,7 +316,7 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
|
|||||||
(mailserver, mailserver_port, s[1], s[0])
|
(mailserver, mailserver_port, s[1], s[0])
|
||||||
print "The port %s may be firewalled. Please try using requestsync with" \
|
print "The port %s may be firewalled. Please try using requestsync with" \
|
||||||
% mailserver_port
|
% mailserver_port
|
||||||
print "the '--lp' flag to file a sync request with the launchpadbugs " \
|
print "the '--lp' flag to file a sync request with the launchpadlib " \
|
||||||
"module."
|
"module."
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -343,23 +342,26 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def post_bug(source_package, subscribe, status, bugtitle, bugtext):
|
def post_bug(source_package, subscribe, status, bugtitle, bugtext):
|
||||||
'''Use python-launchpad-bugs to submit the sync request.
|
'''Use python-launchpadlib to submit the sync request.
|
||||||
Return True if successfully posted, otherwise False.'''
|
Return True if successfully posted, otherwise False.'''
|
||||||
|
|
||||||
import glob, os.path
|
import glob, os.path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import launchpadbugs.connector
|
launchpad = common.get_launchpad("ubuntu-dev-tools")
|
||||||
from launchpadbugs.lpconstants import HTTPCONNECTION
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print >> sys.stderr, 'Importing launchpadbugs failed. Is python-launchpad-bugs installed?'
|
print >> sys.stderr, 'Importing launchpadlib failed. Is python-launchpadlib installed?'
|
||||||
return False
|
return False
|
||||||
|
except IOError, msg:
|
||||||
|
# No credentials found.
|
||||||
|
print msg
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if source_package:
|
if source_package:
|
||||||
product = {'name': source_package, 'target': 'ubuntu'}
|
product_url = "%subuntu/+source/%s" %(launchpad._root_uri, source_package)
|
||||||
else:
|
else:
|
||||||
# new source package
|
# new source package
|
||||||
product = {'name': 'ubuntu'}
|
product_url = "%subuntu" %launchpad._root_uri
|
||||||
|
|
||||||
in_confirm_loop = True
|
in_confirm_loop = True
|
||||||
while in_confirm_loop:
|
while in_confirm_loop:
|
||||||
@ -379,32 +381,17 @@ def post_bug(source_package, subscribe, status, bugtitle, bugtext):
|
|||||||
print "Invalid answer."
|
print "Invalid answer."
|
||||||
|
|
||||||
# Create bug
|
# Create bug
|
||||||
Bug = launchpadbugs.connector.ConnectBug()
|
bug = launchpad.bugs.createBug(description=bugtext, title=bugtitle, target=product_url)
|
||||||
# Force the usage of stable Launchpad.
|
|
||||||
Bug.set_connection_mode(HTTPCONNECTION.MODE.STABLE)
|
|
||||||
|
|
||||||
# Use our cookie file for authentication.
|
#newly created bugreports have one task
|
||||||
Bug.authentication = launchpad_cookiefile
|
task = bug.bug_tasks[0]
|
||||||
print "Using LP cookie at: %s for authentication." % launchpad_cookiefile
|
task.transitionToImportance(importance='Wishlist')
|
||||||
|
task.transitionToStatus(status=status)
|
||||||
|
|
||||||
# Submit bug report.
|
subscribe_url = "%s~%s" %(launchpad._root_uri, subscribe)
|
||||||
bug = Bug.New(product = product, summary = bugtitle, description = bugtext)
|
bug.subscribe(person=subscribe_url)
|
||||||
sleep(2) # Wait in case of slow Launchpad.
|
|
||||||
|
|
||||||
try:
|
|
||||||
bug.importance = 'Wishlist'
|
|
||||||
except IOError, s:
|
|
||||||
print "Warning: setting importance failed: %s" % s
|
|
||||||
|
|
||||||
bug.status = status
|
|
||||||
bug.subscriptions.add(subscribe)
|
|
||||||
sleep(1) # Wait.
|
|
||||||
|
|
||||||
bug.commit()
|
|
||||||
sleep(1) # Wait.
|
|
||||||
|
|
||||||
print 'Sync request filed as bug #%i: https://launchpad.net/bugs/%i' % (bug.bugnumber, bug.bugnumber)
|
|
||||||
|
|
||||||
|
print 'Sync request filed as bug #%i: %s' % (bug.id, common.translate_api_web(bug.self_link))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def edit_report(subject, body, changes_required=False):
|
def edit_report(subject, body, changes_required=False):
|
||||||
@ -477,7 +464,7 @@ if __name__ == '__main__':
|
|||||||
help = "Whether package to sync is a new package in Ubuntu.")
|
help = "Whether package to sync is a new package in Ubuntu.")
|
||||||
optParser.add_option("--lp", action = "store_true",
|
optParser.add_option("--lp", action = "store_true",
|
||||||
dest = "lpbugs", default = False,
|
dest = "lpbugs", default = False,
|
||||||
help = "Specify whether to use the launchpadbugs module for filing " \
|
help = "Specify whether to use the launchpadlib module for filing " \
|
||||||
"report.")
|
"report.")
|
||||||
optParser.add_option("-s", action = "store_true",
|
optParser.add_option("-s", action = "store_true",
|
||||||
dest = "sponsor", default = False,
|
dest = "sponsor", default = False,
|
||||||
@ -524,8 +511,8 @@ if __name__ == '__main__':
|
|||||||
# -s flag not specified - check if we do need sponsorship.
|
# -s flag not specified - check if we do need sponsorship.
|
||||||
if not sponsorship: sponsorship = checkNeedsSponsorship(component)
|
if not sponsorship: sponsorship = checkNeedsSponsorship(component)
|
||||||
|
|
||||||
# Check for existing sync requests.
|
# Check for existing package reports.
|
||||||
checkExistingReports(srcpkg, newsource)
|
if not newsource: checkExistingReports(srcpkg)
|
||||||
|
|
||||||
# Generate bug report.
|
# Generate bug report.
|
||||||
subscribe = 'ubuntu-archive'
|
subscribe = 'ubuntu-archive'
|
||||||
|
1
setup.py
1
setup.py
@ -24,6 +24,7 @@ setup(name='ubuntu-dev-tools',
|
|||||||
'get-build-deps',
|
'get-build-deps',
|
||||||
'grab-attachments',
|
'grab-attachments',
|
||||||
'hugdaylist',
|
'hugdaylist',
|
||||||
|
'manage-credentials',
|
||||||
'massfile',
|
'massfile',
|
||||||
'mk-sbuild-lv',
|
'mk-sbuild-lv',
|
||||||
'pbuilder-dist',
|
'pbuilder-dist',
|
||||||
|
@ -31,6 +31,16 @@ import re
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import urlparse
|
||||||
|
import urllib
|
||||||
|
try:
|
||||||
|
import httplib2
|
||||||
|
from launchpadlib.credentials import Credentials
|
||||||
|
from launchpadlib.launchpad import Launchpad, STAGING_SERVICE_ROOT, EDGE_SERVICE_ROOT
|
||||||
|
from launchpadlib.errors import HTTPError
|
||||||
|
except ImportError:
|
||||||
|
Credentials = None
|
||||||
|
Launchpad = None
|
||||||
|
|
||||||
# Clear https_proxy env var as it's not supported in urllib/urllib2; see
|
# Clear https_proxy env var as it's not supported in urllib/urllib2; see
|
||||||
# LP #122551
|
# LP #122551
|
||||||
@ -265,3 +275,120 @@ def packageComponent(package, release):
|
|||||||
component = rel.split('/')[1]
|
component = rel.split('/')[1]
|
||||||
|
|
||||||
return component.strip()
|
return component.strip()
|
||||||
|
|
||||||
|
|
||||||
|
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=EDGE_SERVICE_ROOT, 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)
|
||||||
|
|
||||||
|
def query_to_dict(query_string):
|
||||||
|
result = dict()
|
||||||
|
options = filter(None, query_string.split("&"))
|
||||||
|
for opt in options:
|
||||||
|
key, value = opt.split("=")
|
||||||
|
result.setdefault(key, set()).add(value)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def translate_web_api(url, launchpad):
|
||||||
|
scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
|
||||||
|
query = query_to_dict(query)
|
||||||
|
if not (("edge" in netloc and "edge" in str(launchpad._root_uri))
|
||||||
|
or ("staging" in netloc and "staging" in str(launchpad._root_uri))):
|
||||||
|
raise ValueError("url conflict (url: %s, root: %s" %(url, launchpad._root_uri))
|
||||||
|
if path.endswith("/+bugs"):
|
||||||
|
path = path[:-6]
|
||||||
|
if "ws.op" in query:
|
||||||
|
raise ValueError("Invalid web url, url: %s" %url)
|
||||||
|
query["ws.op"] = "searchTasks"
|
||||||
|
scheme, netloc, api_path, _, _ = urlparse.urlsplit(str(launchpad._root_uri))
|
||||||
|
query = urllib.urlencode(query)
|
||||||
|
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("beta/", "")
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def translate_service(service):
|
||||||
|
_service = service.lower()
|
||||||
|
if _service in (STAGING_SERVICE_ROOT, EDGE_SERVICE_ROOT):
|
||||||
|
return _service
|
||||||
|
elif _service == "edge":
|
||||||
|
return EDGE_SERVICE_ROOT
|
||||||
|
elif _service == "staging":
|
||||||
|
return STAGING_SERVICE_ROOT
|
||||||
|
else:
|
||||||
|
raise ValueError("unknown service '%s'" %service)
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user