Merge lp:~james-w/ubuntu-archive-tools/improved-sync-helper into lp:ubuntu-archive-tools

Proposed by James Westby
Status: Merged
Approved by: Steve Kowalik
Approved revision: not available
Merge reported by: Steve Kowalik
Merged at revision: not available
Proposed branch: lp:~james-w/ubuntu-archive-tools/improved-sync-helper
Merge into: lp:ubuntu-archive-tools
Diff against target: 221 lines (+160/-31)
1 file modified
sync-helper.py (+160/-31)
To merge this branch: bzr merge lp:~james-w/ubuntu-archive-tools/improved-sync-helper
Reviewer Review Type Date Requested Status
Steve Kowalik (community) Approve
Review via email: mp+16779@code.launchpad.net
To post a comment you must log in.
Revision history for this message
James Westby (james-w) wrote :

Hi Steven,

Please review my changes to sync-helper.py and see if you like
them. I didn't want to unilaterally make them to your script,
but I think these improvements make it a lot more usable.

Thanks for writing the initial version. Processing syncs is much
quicker with this script now.

Thanks,

James

91. By James Westby

Allow changing suite back to unstable.

92. By James Westby

Mark commenters that can upload the package with (*).

This makes it easier to see if sponsorship is still needed.

93. By James Westby

Get all the info up-front to speed up processing.

94. By James Westby

Add progress output.

Also avoid another call to rmadison by re-using the info that we have.

95. By James Westby

Fix a thinko that caused crashes when looking up the component

96. By James Westby

Also consider package sets when looking for uploaders.

Revision history for this message
Steve Kowalik (stevenk) wrote :

Hi James,

This all looks totally awesome! Thanks for the great changes, I'll merge them into trunk soonish.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'sync-helper.py'
--- sync-helper.py 2009-11-20 20:29:12 +0000
+++ sync-helper.py 2010-01-04 19:09:12 +0000
@@ -3,22 +3,108 @@
3# Copyright 2009 Canonical Ltd.3# Copyright 2009 Canonical Ltd.
44
5import os, sys5import os, sys
6from launchpadlib.launchpad import Launchpad, STAGING_SERVICE_ROOT6import subprocess
7from launchpadlib.launchpad import Launchpad, EDGE_SERVICE_ROOT, STAGING_SERVICE_ROOT
8import webbrowser
79
8APP_NAME = 'sync-helper'10APP_NAME = 'sync-helper'
9CACHE_DIR = os.path.expanduser('~/.launchpadlib/cache')11CACHE_DIR = os.path.expanduser('~/.launchpadlib/cache')
10SERVICE_ROOT = STAGING_SERVICE_ROOT12SERVICE_ROOT = EDGE_SERVICE_ROOT
13
14
15class Bug(object):
16
17 def __init__(self, number):
18 self.number = number
19 self.title = None
20 self.package = None
21 self.reporter = None
22 self.content = None
23
1124
12def length(collection):25def length(collection):
13 # XXX: Workaround bug 274074. Thanks wgrant.26 # XXX: Workaround bug 274074. Thanks wgrant.
14 return int(collection._wadl_resource.representation['total_size'])27 return int(collection._wadl_resource.representation['total_size'])
1528
16def prompt(text):29def rmadison(distro, package):
17 print "%s [Show/sKip/sYnc] " % text30 proc = subprocess.Popen(["/usr/bin/rmadison", "-u", distro, package],
18 return sys.stdin.readline().rstrip()31 stdout=subprocess.PIPE)
1932 (output, _) = proc.communicate()
20def sync(bug, syncfile):33 return output.splitlines()
21 syncfile.write("sync %s -f\n" % bug)34
35def get_components(package, debian_details):
36 components = {}
37 for line in debian_details.splitlines():
38 if line.strip() == "":
39 continue
40 series_component = line.split("|")[2].strip()
41 archs = line.split("|")[3].strip().split(", ")
42 if "source" in archs:
43 if "/" in series_component:
44 series, component = series_component.split("/")
45 components[series] = component
46 else:
47 components[series_component] = "main"
48 return components
49
50def ubuntu_details(package, current_series):
51 output = rmadison("ubuntu", package)
52 new_output = []
53 for line in output:
54 parts = line.split("|")
55 if current_series in parts[2]:
56 new_output.append(line)
57 return new_output
58
59def debian_details(package):
60 return rmadison("debian", package)
61
62def canUpload(distribution, person, package_name):
63 if distribution.main_archive.isSourceUploadAllowed(
64 distroseries=distribution.current_series, person=person,
65 sourcepackagename=package_name):
66 return True
67 pubs = distribution.main_archive.getPublishedSources(
68 distro_series=distribution.current_series, exact_match=True,
69 pocket="Release", status="Published", source_name=package_name)
70 pubs = [pub for pub in pubs]
71 if len(pubs) < 1:
72 return False
73 component = pubs[0].component_name
74 for perm in distribution.main_archive.getPermissionsForPerson(person=person):
75 if perm.permission != 'Archive Upload Rights':
76 continue
77 if perm.component_name == component:
78 return True
79 if perm.source_package_name == package_name:
80 return True
81 return False
82
83def prompt(bug, suite, full=True):
84 sys.stdout.write("%s: %s\n" % (bug.number, bug.title))
85 if full:
86 sys.stdout.write(bug.ubuntu_details + "\n")
87 sys.stdout.write(bug.debian_details + "\n")
88 msg = "[Show/sKip/sYnc from %s/" % (suite,)
89 if suite == "unstable" or suite == "experimental":
90 msg += "switch to Testing/"
91 elif suite == "testing":
92 msg += "switch to Unstable/"
93 if suite == "testing" or suite == "unstable":
94 msg += "switch to Experimental/"
95 elif suite == "experimental":
96 msg += "switch to Unstable/"
97 msg += "Open bug]: "
98 sys.stdout.write(msg)
99 sys.stdout.flush()
100 return sys.stdin.readline().rstrip().upper()
101
102def sync(bug, syncfile, suite="unstable", component="main"):
103 params = {"bug": bug.number,
104 "suite": suite,
105 "component": component,
106 }
107 syncfile.write("sync %(bug)s -f -S %(suite)s -C %(component)s\n" % params)
22108
23def main(args):109def main(args):
24 f = None110 f = None
@@ -27,35 +113,78 @@
27 except:113 except:
28 print "%s: Require a filename to write to!" % args[0]114 print "%s: Require a filename to write to!" % args[0]
29 sys.exit(1)115 sys.exit(1)
30 print "Connecting to LP ... "116 sys.stdout.write("Connecting to LP ... ")
117 sys.stdout.flush()
31 launchpad = Launchpad.login_with(APP_NAME, SERVICE_ROOT, CACHE_DIR)118 launchpad = Launchpad.login_with(APP_NAME, SERVICE_ROOT, CACHE_DIR)
32 pillar = launchpad.projects['ubuntu']119 pillar = launchpad.projects['ubuntu']
33 subscriber = launchpad.people['ubuntu-archive']120 subscriber = launchpad.people['ubuntu-archive']
34 print "Done"121 ubuntu_series = pillar.current_series.name
35 print "Loading bugs ... "122 sys.stdout.write("Done\n")
36 bugs = pillar.searchTasks(bug_subscriber = subscriber, search_text = 'sync')123 sys.stdout.write("Loading bugs (this may take some time, go get a "
37 bugs_cache = {}124 "cup of tea) ... \n")
38 bug_numbers = {}125 sync_bugs = []
126 bugs = pillar.searchTasks(bug_subscriber=subscriber, search_text='qcad')
127 num_bugs = length(bugs)
128 bugs_processed = 0
129 prev_line = ""
39 for bugtask in bugs:130 for bugtask in bugs:
40 bugs_cache[bugtask.bug.title] = bugtask.bug.description131 bugs_processed += 1
41 for i in reversed(bugtask.bug.messages_collection):132 sys.stdout.write("\r" + " "*len(prev_line) + "\r")
42 bugs_cache[bugtask.bug.title] += i.content133 prev_line = "%d/%d" % (bugs_processed, num_bugs)
43 bug_numbers[bugtask.bug.title] = bugtask.bug.id134 sys.stdout.write(prev_line)
44 print "Done"135 sys.stdout.flush()
136 if " (Ubuntu)" not in bugtask.bug_target_name:
137 continue
138 bug = Bug(bugtask.bug.id)
139 bug.title = bugtask.bug.title
140 bug.package = bugtask.bug_target_name.rsplit(" ", 1)[0]
141 next_line_part = ": %s" % (bug.package,)
142 sys.stdout.write(next_line_part)
143 prev_line += next_line_part
144 sys.stdout.flush()
145 bug.content = bugtask.bug.description
146 bug.reporter = bugtask.bug.owner
147 for i in reversed(bugtask.bug.messages):
148 bug.content += "\n=============================================\n"
149 star = ""
150 if canUpload(pillar, i.owner, bug.package):
151 star = "(*)"
152 bug.content += "%s%s said %s on %s:\n\n" % (i.owner.name, star,
153 i.subject, str(i.date_created))
154 bug.content += i.content
155 bug.ubuntu_details = "\n".join(ubuntu_details(bug.package, ubuntu_series))
156 bug.debian_details = "\n".join(debian_details(bug.package))
157 bug.components = get_components(bug.package, bug.debian_details)
158 sync_bugs.append(bug)
159 sys.stdout.write("\r" + " "*len(prev_line) + "\r")
160 sys.stdout.write("Done, %d packages to consider.\n" % (len(sync_bugs),))
45161
46 for title in bugs_cache.keys():162 for bug in sync_bugs:
47 ret = prompt(title)163 sys.stdout.write("\n==========================\n")
48 if ret == 'S':164 finished = False
49 print bugs_cache[title]165 suite = "unstable"
50 ret = prompt(title)166 component = "main"
51 if ret == 'Y':167 if suite in bug.components:
52 sync(bug_numbers[title], f)168 component = bug.components[suite]
169 full = True
170 while not finished:
171 ret = prompt(bug, suite, full=full)
172 if ret == 'S':
173 print bug.content
53 elif ret == 'K':174 elif ret == 'K':
54 continue175 finished = True
55 elif ret == 'K':176 elif ret == 'Y':
56 continue177 sync(bug, f, suite=suite, component=component)
57 elif ret == 'Y':178 finished = True
58 sync(bug_numbers[title], f)179 elif ret == 'T':
180 suite = "testing"
181 elif ret == 'U':
182 suite = "unstable"
183 elif ret == 'E':
184 suite = "experimental"
185 elif ret == 'O':
186 webbrowser.open("https://bugs.launchpad.net/bugs/%s" % bug.number)
187 full = False
59 f.close()188 f.close()
60 return 0189 return 0
61190

Subscribers

People subscribed via source and target branches