Merge lp:~lifeless/launchpad/mentoring into lp:launchpad

Proposed by Robert Collins on 2010-10-31
Status: Merged
Approved by: Jonathan Lange on 2010-10-31
Approved revision: no longer in the source branch.
Merged at revision: 11840
Proposed branch: lp:~lifeless/launchpad/mentoring
Merge into: lp:launchpad
Diff against target: 1945 lines (+24/-1170)
38 files modified
lib/canonical/launchpad/browser/__init__.py (+0/-1)
lib/canonical/launchpad/browser/launchpad.py (+0/-2)
lib/canonical/launchpad/doc/badges.txt (+1/-2)
lib/canonical/launchpad/doc/sample-data-assertions.txt (+0/-41)
lib/canonical/launchpad/icing/icon-sprites.positioning (+1/-9)
lib/canonical/launchpad/icing/style-3-0.css.in (+0/-8)
lib/canonical/launchpad/interfaces/__init__.py (+0/-1)
lib/canonical/launchpad/templates/launchpad-graphics.pt (+0/-11)
lib/canonical/launchpad/webapp/badge.py (+0/-3)
lib/lp/app/browser/tales.py (+0/-15)
lib/lp/blueprints/interfaces/specification.py (+1/-2)
lib/lp/blueprints/model/specification.py (+0/-42)
lib/lp/bugs/browser/bug.py (+1/-16)
lib/lp/bugs/browser/bugtask.py (+2/-6)
lib/lp/bugs/browser/cvereport.py (+0/-1)
lib/lp/bugs/configure.zcml (+0/-15)
lib/lp/bugs/doc/bugtask.txt (+0/-11)
lib/lp/bugs/interfaces/bug.py (+1/-2)
lib/lp/bugs/interfaces/bugtask.py (+11/-10)
lib/lp/bugs/model/bug.py (+0/-39)
lib/lp/bugs/model/bugtask.py (+0/-36)
lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt (+1/-2)
lib/lp/registry/browser/mentoringoffer.py (+0/-200)
lib/lp/registry/browser/milestone.py (+0/-1)
lib/lp/registry/browser/tests/milestone-views.txt (+0/-1)
lib/lp/registry/configure.zcml (+0/-11)
lib/lp/registry/doc/mentoringoffer.txt (+0/-292)
lib/lp/registry/interfaces/distribution.py (+1/-2)
lib/lp/registry/interfaces/mentoringoffer.py (+0/-95)
lib/lp/registry/interfaces/person.py (+1/-4)
lib/lp/registry/interfaces/product.py (+1/-2)
lib/lp/registry/interfaces/projectgroup.py (+1/-2)
lib/lp/registry/model/distribution.py (+0/-22)
lib/lp/registry/model/mentoringoffer.py (+0/-121)
lib/lp/registry/model/person.py (+1/-83)
lib/lp/registry/model/product.py (+0/-22)
lib/lp/registry/model/projectgroup.py (+0/-24)
utilities/migrater/file-ownership.txt (+0/-13)
To merge this branch: bzr merge lp:~lifeless/launchpad/mentoring
Reviewer Review Type Date Requested Status
Jonathan Lange (community) 2010-10-31 Approve on 2010-10-31
Review via email: mp+39721@code.launchpad.net

Commit Message

Delete the python component of the removed mentoring feature. May cause Persons who had used mentoring to fail to merge until we delete the mentoring content.

Description of the Change

Delete unused code (it may have test fallout, but I don't think so). Two possibly unused methods have been retained because they need some careful analysis to see if they are actually unused- but I explained that in their docstrings.

To post a comment you must log in.
Jonathan Lange (jml) wrote :

Rock!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/browser/__init__.py'
2--- lib/canonical/launchpad/browser/__init__.py 2010-10-13 06:00:09 +0000
3+++ lib/canonical/launchpad/browser/__init__.py 2010-11-02 20:17:46 +0000
4@@ -46,7 +46,6 @@
5 from lp.registry.browser.featuredproject import *
6 from lp.registry.browser.karma import *
7 from lp.registry.browser.mailinglists import *
8-from lp.registry.browser.mentoringoffer import *
9 from lp.registry.browser.objectreassignment import *
10 from lp.registry.browser.peoplemerge import *
11 from lp.registry.browser.poll import *
12
13=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
14--- lib/canonical/launchpad/browser/launchpad.py 2010-10-29 03:10:42 +0000
15+++ lib/canonical/launchpad/browser/launchpad.py 2010-11-02 20:17:46 +0000
16@@ -131,7 +131,6 @@
17 from lp.registry.interfaces.codeofconduct import ICodeOfConductSet
18 from lp.registry.interfaces.distribution import IDistributionSet
19 from lp.registry.interfaces.karma import IKarmaActionSet
20-from lp.registry.interfaces.mentoringoffer import IMentoringOfferSet
21 from lp.registry.interfaces.person import IPersonSet
22 from lp.registry.interfaces.pillar import IPillarNameSet
23 from lp.registry.interfaces.product import (
24@@ -584,7 +583,6 @@
25 'karmaaction': IKarmaActionSet,
26 '+imports': ITranslationImportQueue,
27 '+languages': ILanguageSet,
28- '+mentoring': IMentoringOfferSet,
29 'package-sets': IPackagesetSet,
30 'people': IPersonSet,
31 'pillars': IPillarNameSet,
32
33=== modified file 'lib/canonical/launchpad/doc/badges.txt'
34--- lib/canonical/launchpad/doc/badges.txt 2010-10-03 15:30:06 +0000
35+++ lib/canonical/launchpad/doc/badges.txt 2010-11-02 20:17:46 +0000
36@@ -11,7 +11,7 @@
37
38 In the object listing views, badges are used to show links between
39 objects, such as bug-branch links or bug-spec links, and object
40-attribute values such as privacy or mentoring availability.
41+attribute values such as privacy.
42
43 Listings use small icon sized images, and object details pages use
44 larger logo sized images.
45@@ -29,7 +29,6 @@
46 blueprint
47 branch
48 bug
49- mentoring
50 mergeproposal
51 patch
52 private
53
54=== modified file 'lib/canonical/launchpad/doc/sample-data-assertions.txt'
55--- lib/canonical/launchpad/doc/sample-data-assertions.txt 2010-10-10 15:39:28 +0000
56+++ lib/canonical/launchpad/doc/sample-data-assertions.txt 2010-11-02 20:17:46 +0000
57@@ -31,44 +31,3 @@
58 >>> one_membership = personset.getByName('one-membership')
59 >>> for t in one_membership.team_memberships: print t.team.displayname
60 Simple Team
61-
62-
63-== Mentorship Page Tests ==
64-
65-We will use bugs #2 and #8 and a specific blueprint as the test vehicles
66-for the mentoring set of pagetests. Bug #2 should be incomplete, and bug #8
67-complete. The specification should be incomplete too. Finally, Bug #6
68-should be a duplicate, and should be incomplete.
69-
70- >>> from zope.component import getUtility
71- >>> from lp.bugs.interfaces.bug import IBugSet
72- >>> from lp.registry.interfaces.distribution import IDistributionSet
73- >>> bugset = getUtility(IBugSet)
74- >>> distroset = getUtility(IDistributionSet)
75- >>> from canonical.launchpad.ftests import login
76- >>> login('no-priv@canonical.com')
77- >>> b2 = bugset.get(2)
78- >>> b2.is_complete
79- False
80- >>> b8 = bugset.get(8)
81- >>> b8.is_complete
82- True
83- >>> b6 = bugset.get(6)
84- >>> b6.is_complete
85- False
86- >>> b6.duplicateof is not None
87- True
88- >>> kubuntu = distroset.getByName('kubuntu')
89- >>> cluster_blueprint = kubuntu.getSpecification('cluster-installation')
90- >>> cluster_blueprint.is_complete
91- False
92-
93-There should be no mentorships on any of these.
94-
95- >>> b2.mentoring_offers.count()
96- 0
97- >>> b8.mentoring_offers.count()
98- 0
99- >>> cluster_blueprint.mentoring_offers.count()
100- 0
101-
102
103=== modified file 'lib/canonical/launchpad/icing/icon-sprites.positioning'
104--- lib/canonical/launchpad/icing/icon-sprites.positioning 2010-06-11 18:39:35 +0000
105+++ lib/canonical/launchpad/icing/icon-sprites.positioning 2010-11-02 20:17:46 +0000
106@@ -245,10 +245,6 @@
107 0,
108 -6228
109 ],
110- "../images/mentoring.png": [
111- 0,
112- -7048
113- ],
114 "../images/flame-large.png": [
115 0,
116 -16976
117@@ -453,10 +449,6 @@
118 0,
119 -1968
120 ],
121- "../images/mentoring-large.png": [
122- 0,
123- -17704
124- ],
125 "../images/bug.png": [
126 0,
127 -4260
128@@ -477,4 +469,4 @@
129 0,
130 -1148
131 ]
132-}
133\ No newline at end of file
134+}
135
136=== modified file 'lib/canonical/launchpad/icing/style-3-0.css.in'
137--- lib/canonical/launchpad/icing/style-3-0.css.in 2010-10-19 03:26:47 +0000
138+++ lib/canonical/launchpad/icing/style-3-0.css.in 2010-11-02 20:17:46 +0000
139@@ -2062,10 +2062,6 @@
140 background-image: url(/@@/person-inactive-badge.png); /* sprite-ref: icon-sprites */
141 background-repeat: no-repeat;
142 }
143-.mentoring {
144- background-image: url(/@@/mentoring.png); /* sprite-ref: icon-sprites */
145- background-repeat: no-repeat;
146- }
147 .undecided {
148 background-image: url(/@@/maybe.png); /* sprite-ref: icon-sprites */
149 background-repeat: no-repeat;
150@@ -2324,10 +2320,6 @@
151 background-image: url(/@@/launchpad-large.png); /* sprite-ref: icon-sprites */
152 background-repeat: no-repeat;
153 }
154-.large-mentoring {
155- background-image: url(/@@/mentoring-large.png); /* sprite-ref: icon-sprites */
156- background-repeat: no-repeat;
157- }
158 .large-proposal {
159 background-image: url(/@@/merge-proposal-large.png); /* sprite-ref: icon-sprites */
160 background-repeat: no-repeat;
161
162=== removed file 'lib/canonical/launchpad/images/mentoring-large.png'
163Binary files lib/canonical/launchpad/images/mentoring-large.png 2010-02-03 05:16:27 +0000 and lib/canonical/launchpad/images/mentoring-large.png 1970-01-01 00:00:00 +0000 differ
164=== removed file 'lib/canonical/launchpad/images/mentoring.png'
165Binary files lib/canonical/launchpad/images/mentoring.png 2010-02-03 05:16:27 +0000 and lib/canonical/launchpad/images/mentoring.png 1970-01-01 00:00:00 +0000 differ
166=== modified file 'lib/canonical/launchpad/interfaces/__init__.py'
167--- lib/canonical/launchpad/interfaces/__init__.py 2010-10-19 03:26:47 +0000
168+++ lib/canonical/launchpad/interfaces/__init__.py 2010-11-02 20:17:46 +0000
169@@ -90,7 +90,6 @@
170 from canonical.launchpad.interfaces.mailbox import *
171 from lp.registry.interfaces.mailinglist import *
172 from lp.registry.interfaces.mailinglistsubscription import *
173-from lp.registry.interfaces.mentoringoffer import *
174 from canonical.launchpad.interfaces.message import *
175 from lp.registry.interfaces.milestone import *
176 from canonical.launchpad.interfaces.oauth import *
177
178=== modified file 'lib/canonical/launchpad/templates/launchpad-graphics.pt'
179--- lib/canonical/launchpad/templates/launchpad-graphics.pt 2010-05-22 02:59:19 +0000
180+++ lib/canonical/launchpad/templates/launchpad-graphics.pt 2010-11-02 20:17:46 +0000
181@@ -473,17 +473,6 @@
182 <td><img alt="" src="/@@/meeting-mugshot" /></td>
183 </tr>
184 <tr>
185- <td>mentoring</td>
186- <td><img alt="" src="/@@/mentoring" /></td>
187- <td rowspan="2">A bug or blueprint for which mentoring has been
188- offered.
189- </td>
190- </tr>
191- <tr>
192- <td>mentoring-large</td>
193- <td><img alt="" src="/@@/mentoring-large" /></td>
194- </tr>
195- <tr>
196 <td>milestone</td>
197 <td><img alt="" src="/@@/milestone" /></td>
198 <td>A "target". This indicates a development milestone to which a
199
200=== modified file 'lib/canonical/launchpad/webapp/badge.py'
201--- lib/canonical/launchpad/webapp/badge.py 2010-08-20 20:31:18 +0000
202+++ lib/canonical/launchpad/webapp/badge.py 2010-11-02 20:17:46 +0000
203@@ -79,9 +79,6 @@
204 'security': Badge('/@@/security', '/@@/security-large',
205 '(Security vulnerability)', 'Security vulnerability',
206 'securitybadge'),
207- 'mentoring': Badge('/@@/mentoring', '/@@/mentoring-large',
208- '(Mentoring available)', 'Mentoring available',
209- 'mentoringbadge'),
210 'mergeproposal': Badge('/@@/merge-proposal-icon',
211 '/@@/merge-proposal-large',
212 '(Has a merge proposal)', 'Has a merge proposal',
213
214=== modified file 'lib/lp/app/browser/tales.py'
215--- lib/lp/app/browser/tales.py 2010-10-03 15:30:06 +0000
216+++ lib/lp/app/browser/tales.py 2010-11-02 20:17:46 +0000
217@@ -832,10 +832,6 @@
218
219 return self.icon_template % (alt, title, css)
220
221- def _hasMentoringOffer(self):
222- """Return whether the bug has a mentoring offer."""
223- return self._context.bug.mentoring_offers.count() > 0
224-
225 def _hasBugBranch(self):
226 """Return whether the bug has a branch linked to it."""
227 return self._context.bug.linked_branches.count() > 0
228@@ -854,10 +850,6 @@
229 badges.append(self.icon_template % (
230 "private", "Private", "sprite private"))
231
232- if self._hasMentoringOffer():
233- badges.append(self.icon_template % (
234- "mentoring", "Mentoring offered", "sprite mentoring"))
235-
236 if self._hasBugBranch():
237 badges.append(self.icon_template % (
238 "branch", "Branch exists", "sprite branch"))
239@@ -890,10 +882,6 @@
240 accessed.
241 """
242
243- def _hasMentoringOffer(self):
244- """See `BugTaskImageDisplayAPI`"""
245- return self._context.has_mentoring_offer
246-
247 def _hasBugBranch(self):
248 """See `BugTaskImageDisplayAPI`"""
249 return self._context.has_bug_branch
250@@ -936,9 +924,6 @@
251 def badges(self):
252
253 badges = ''
254- if self._context.mentoring_offers.count() > 0:
255- badges += self.icon_template % (
256- "mentoring", "Mentoring offered", "sprite mentoring")
257
258 if self._context.linked_branches.count() > 0:
259 badges += self.icon_template % (
260
261=== modified file 'lib/lp/blueprints/interfaces/specification.py'
262--- lib/lp/blueprints/interfaces/specification.py 2010-11-01 03:26:22 +0000
263+++ lib/lp/blueprints/interfaces/specification.py 2010-11-02 20:17:46 +0000
264@@ -46,7 +46,6 @@
265 from lp.blueprints.interfaces.specificationtarget import IHasSpecifications
266 from lp.blueprints.interfaces.sprint import ISprint
267 from lp.code.interfaces.branchlink import IHasLinkedBranches
268-from lp.registry.interfaces.mentoringoffer import ICanBeMentored
269 from lp.registry.interfaces.projectgroup import IProjectGroup
270 from lp.registry.interfaces.role import IHasOwner
271 from lp.services.fields import (
272@@ -208,7 +207,7 @@
273
274
275 class ISpecification(INewSpecification, INewSpecificationTarget, IHasOwner,
276- ICanBeMentored, IHasLinkedBranches):
277+ IHasLinkedBranches):
278 """A Specification."""
279
280 export_as_webservice_entry()
281
282=== modified file 'lib/lp/blueprints/model/specification.py'
283--- lib/lp/blueprints/model/specification.py 2010-11-01 03:32:29 +0000
284+++ lib/lp/blueprints/model/specification.py 2010-11-02 20:17:46 +0000
285@@ -85,7 +85,6 @@
286 from lp.registry.interfaces.distroseries import IDistroSeries
287 from lp.registry.interfaces.person import validate_public_person
288 from lp.registry.interfaces.productseries import IProductSeries
289-from lp.registry.model.mentoringoffer import MentoringOffer
290
291
292 class Specification(SQLBase, BugLinkTargetMixin):
293@@ -157,8 +156,6 @@
294 date_started = UtcDateTimeCol(notNull=False, default=None)
295
296 # useful joins
297- mentoring_offers = SQLMultipleJoin(
298- 'MentoringOffer', joinColumn='specification', orderBy='id')
299 subscriptions = SQLMultipleJoin('SpecificationSubscription',
300 joinColumn='specification', orderBy='id')
301 subscribers = SQLRelatedJoin('Person',
302@@ -293,45 +290,6 @@
303 specification=self, reviewer=person)
304 return fb.prejoin(['requester'])
305
306- def canMentor(self, user):
307- """See ICanBeMentored."""
308- if user is None:
309- return False
310- if self.is_complete:
311- return False
312- if bool(self.isMentor(user)):
313- return False
314- if not user.teams_participated_in:
315- return False
316- return True
317-
318- def isMentor(self, user):
319- """See ICanBeMentored."""
320- return MentoringOffer.selectOneBy(
321- specification=self, owner=user) is not None
322-
323- def offerMentoring(self, user, team):
324- """See ICanBeMentored."""
325- # if an offer exists, then update the team
326- mentoringoffer = MentoringOffer.selectOneBy(
327- specification=self, owner=user)
328- if mentoringoffer is not None:
329- mentoringoffer.team = team
330- return mentoringoffer
331- # if no offer exists, create one from scratch
332- mentoringoffer = MentoringOffer(owner=user, team=team,
333- specification=self)
334- notify(ObjectCreatedEvent(mentoringoffer, user=user))
335- return mentoringoffer
336-
337- def retractMentoring(self, user):
338- """See ICanBeMentored."""
339- mentoringoffer = MentoringOffer.selectOneBy(
340- specification=self, owner=user)
341- if mentoringoffer is not None:
342- notify(ObjectDeletedEvent(mentoringoffer, user=user))
343- MentoringOffer.delete(mentoringoffer.id)
344-
345 def notificationRecipientAddresses(self):
346 """See ISpecification."""
347 related_people = [
348
349=== modified file 'lib/lp/bugs/browser/bug.py'
350--- lib/lp/bugs/browser/bug.py 2010-10-20 16:30:03 +0000
351+++ lib/lp/bugs/browser/bug.py 2010-11-02 20:17:46 +0000
352@@ -209,8 +209,7 @@
353 links = ['editdescription', 'markduplicate', 'visibility', 'addupstream',
354 'adddistro', 'subscription', 'addsubscriber', 'addcomment',
355 'nominate', 'addbranch', 'linktocve', 'unlinkcve',
356- 'offermentoring', 'retractmentoring', 'createquestion',
357- 'removequestion', 'activitylog', 'affectsmetoo']
358+ 'createquestion', 'removequestion', 'activitylog', 'affectsmetoo']
359
360 def __init__(self, context):
361 # Always force the context to be the current bugtask, so that we don't
362@@ -306,20 +305,6 @@
363 text = 'Remove CVE link'
364 return Link('+unlinkcve', text, icon='remove', enabled=enabled)
365
366- def offermentoring(self):
367- """Return the 'Offer mentorship' Link."""
368- text = 'Offer mentorship'
369- user = getUtility(ILaunchBag).user
370- enabled = False
371- return Link('+mentor', text, icon='add', enabled=enabled)
372-
373- def retractmentoring(self):
374- """Return the 'Retract mentorship' Link."""
375- text = 'Retract mentorship'
376- user = getUtility(ILaunchBag).user
377- enabled = False
378- return Link('+retractmentoring', text, icon='remove', enabled=enabled)
379-
380 @property
381 def _bug_question(self):
382 return self.context.bug.getQuestionCreatedFromBug()
383
384=== modified file 'lib/lp/bugs/browser/bugtask.py'
385--- lib/lp/bugs/browser/bugtask.py 2010-10-18 01:06:18 +0000
386+++ lib/lp/bugs/browser/bugtask.py 2010-11-02 20:17:46 +0000
387@@ -240,7 +240,6 @@
388 from lp.bugs.interfaces.bugwatch import BugWatchActivityStatus
389 from lp.bugs.interfaces.cve import ICveSet
390 from lp.bugs.interfaces.malone import IMaloneApplication
391-from lp.registry.browser.mentoringoffer import CanBeMentoredView
392 from lp.registry.interfaces.distribution import IDistribution
393 from lp.registry.interfaces.distributionsourcepackage import (
394 IDistributionSourcePackage,
395@@ -620,8 +619,7 @@
396 return view.render()
397
398
399-class BugTaskView(LaunchpadView, BugViewMixin, CanBeMentoredView,
400- FeedsMixin):
401+class BugTaskView(LaunchpadView, BugViewMixin, FeedsMixin):
402 """View class for presenting information about an `IBugTask`."""
403
404 override_title_breadcrumbs = True
405@@ -2086,12 +2084,11 @@
406 """
407 delegates(IBugTask, 'bugtask')
408
409- def __init__(self, bugtask, has_mentoring_offer, has_bug_branch,
410+ def __init__(self, bugtask, has_bug_branch,
411 has_specification, has_patch, request=None,
412 target_context=None):
413 self.bugtask = bugtask
414 self.review_action_widget = None
415- self.has_mentoring_offer = has_mentoring_offer
416 self.has_bug_branch = has_bug_branch
417 self.has_specification = has_specification
418 self.has_patch = has_patch
419@@ -2141,7 +2138,6 @@
420 target_context = self.target_context
421 return BugTaskListingItem(
422 bugtask,
423- badge_property['has_mentoring_offer'],
424 badge_property['has_branch'],
425 badge_property['has_specification'],
426 badge_property['has_patch'],
427
428=== modified file 'lib/lp/bugs/browser/cvereport.py'
429--- lib/lp/bugs/browser/cvereport.py 2010-08-24 10:45:57 +0000
430+++ lib/lp/bugs/browser/cvereport.py 2010-11-02 20:17:46 +0000
431@@ -79,7 +79,6 @@
432 # queries being issues when trying to render the badges.
433 bugtask = BugTaskListingItem(
434 bugtask,
435- has_mentoring_offer=badges['has_mentoring_offer'],
436 has_bug_branch=badges['has_branch'],
437 has_specification=badges['has_specification'],
438 has_patch=badges['has_patch'])
439
440=== modified file 'lib/lp/bugs/configure.zcml'
441--- lib/lp/bugs/configure.zcml 2010-10-25 13:02:15 +0000
442+++ lib/lp/bugs/configure.zcml 2010-11-02 20:17:46 +0000
443@@ -196,8 +196,6 @@
444 bug_subscribers
445 is_complete
446 canTransitionToStatus
447- isMentor
448- canMentor
449 isSubscribed
450 getPackageComponent
451 userCanEditImportance
452@@ -257,11 +255,6 @@
453 <require
454 permission="launchpad.Edit"
455 set_attributes="product productseries sourcepackagename distribution distroseries milestone statusexplanation importance bugwatch datecreated age owner targetname title related_tasks statusdisplayhtml statuselsewhere setStatusFromDebbugs setImportanceFromDebbugs"/>
456- <require
457- permission="launchpad.AnyPerson"
458- attributes="
459- offerMentoring
460- retractMentoring"/>
461 </class>
462 <adapter
463 provides="canonical.lazr.interfaces.IObjectPrivacy"
464@@ -646,9 +639,6 @@
465 getDirectSubscribers
466 getDirectSubscriptions
467 getIndirectSubscribers
468- mentoring_offers
469- canMentor
470- isMentor
471 getNullBugTask
472 is_complete
473 official_tags
474@@ -779,11 +769,6 @@
475 title description
476 who_made_private"/>
477 <require
478- permission="launchpad.AnyPerson"
479- attributes="
480- offerMentoring
481- retractMentoring"/>
482- <require
483 permission="launchpad.Admin"
484 attributes="
485 setCommentVisibility
486
487=== modified file 'lib/lp/bugs/doc/bugtask.txt'
488--- lib/lp/bugs/doc/bugtask.txt 2010-10-22 19:23:14 +0000
489+++ lib/lp/bugs/doc/bugtask.txt 2010-11-02 20:17:46 +0000
490@@ -1236,22 +1236,13 @@
491 >>> print_badge_properties(badge_properties)
492 Properties for bug 2:
493 has_branch: False
494- has_mentoring_offer: False
495 has_patch: False
496 has_specification: False
497 Properties for bug 3:
498 has_branch: False
499- has_mentoring_offer: False
500 has_patch: False
501 has_specification: False
502
503-If a mentoring offer gets made...
504-
505- >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
506- >>> ubuntu_team = getUtility(IPersonSet).getByName('ubuntu-team')
507- >>> bug_two.offerMentoring(no_priv, ubuntu_team)
508- <MentoringOffer at ...>
509-
510 ..., a specification gets linked...
511
512 >>> from lp.blueprints.interfaces.specification import ISpecificationSet
513@@ -1272,12 +1263,10 @@
514 >>> print_badge_properties(badge_properties)
515 Properties for bug 2:
516 has_branch: False
517- has_mentoring_offer: True
518 has_patch: False
519 has_specification: True
520 Properties for bug 3:
521 has_branch: True
522- has_mentoring_offer: False
523 has_patch: False
524 has_specification: False
525
526
527=== modified file 'lib/lp/bugs/interfaces/bug.py'
528--- lib/lp/bugs/interfaces/bug.py 2010-10-25 13:46:12 +0000
529+++ lib/lp/bugs/interfaces/bug.py 2010-11-02 20:17:46 +0000
530@@ -81,7 +81,6 @@
531 from lp.bugs.interfaces.bugwatch import IBugWatch
532 from lp.bugs.interfaces.cve import ICve
533 from lp.code.interfaces.branchlink import IHasLinkedBranches
534-from lp.registry.interfaces.mentoringoffer import ICanBeMentored
535 from lp.registry.interfaces.person import IPerson
536 from lp.services.fields import (
537 BugField,
538@@ -191,7 +190,7 @@
539 return subject_field
540
541
542-class IBug(ICanBeMentored, IPrivacy, IHasLinkedBranches):
543+class IBug(IPrivacy, IHasLinkedBranches):
544 """The core bug entry."""
545 export_as_webservice_entry()
546
547
548=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
549--- lib/lp/bugs/interfaces/bugtask.py 2010-10-25 13:03:02 +0000
550+++ lib/lp/bugs/interfaces/bugtask.py 2010-11-02 20:17:46 +0000
551@@ -112,7 +112,6 @@
552 NoBugTrackerFound,
553 UnrecognizedBugTrackerURL,
554 )
555-from lp.registry.interfaces.mentoringoffer import ICanBeMentored
556 from lp.services.fields import (
557 BugField,
558 PersonChoice,
559@@ -443,7 +442,7 @@
560 webservice_error(400) #Bad request.
561
562
563-class IBugTask(IHasDateCreated, IHasBug, ICanBeMentored):
564+class IBugTask(IHasDateCreated, IHasBug):
565 """A bug needing fixing in a particular product or package."""
566 export_as_webservice_entry()
567
568@@ -656,20 +655,22 @@
569 def subscribe(person, subscribed_by):
570 """Subscribe this person to the underlying bug.
571
572- This method is required here so that MentorshipOffers can happen on
573- IBugTask. When we move to context-less bug presentation (where the
574- bug is at /bugs/n?task=ubuntu) then we can eliminate this if it is
575- no longer useful.
576+ This method was documented as being required here so that
577+ MentorshipOffers could happen on IBugTask. If that was the sole reason
578+ this method should be deletable. When we move to context-less bug
579+ presentation (where the bug is at /bugs/n?task=ubuntu) then we can
580+ eliminate this if it is no longer useful.
581 """
582
583 def isSubscribed(person):
584 """Return True if the person is an explicit subscriber to the
585 underlying bug for this bugtask.
586
587- This method is required here so that MentorshipOffers can happen on
588- IBugTask. When we move to context-less bug presentation (where the
589- bug is at /bugs/n?task=ubuntu) then we can eliminate this if it is
590- no longer useful.
591+ This method was documented as being required here so that
592+ MentorshipOffers could happen on IBugTask. If that was the sole reason
593+ then this method should be deletable. When we move to context-less bug
594+ presentation (where the bug is at /bugs/n?task=ubuntu) then we can
595+ eliminate this if it is no longer useful.
596 """
597
598 @mutator_for(milestone)
599
600=== modified file 'lib/lp/bugs/model/bug.py'
601--- lib/lp/bugs/model/bug.py 2010-10-26 02:02:12 +0000
602+++ lib/lp/bugs/model/bug.py 2010-11-02 20:17:46 +0000
603@@ -176,7 +176,6 @@
604 from lp.registry.interfaces.productseries import IProductSeries
605 from lp.registry.interfaces.series import SeriesStatus
606 from lp.registry.interfaces.sourcepackage import ISourcePackage
607-from lp.registry.model.mentoringoffer import MentoringOffer
608 from lp.registry.model.person import (
609 Person,
610 ValidPersonCache,
611@@ -320,8 +319,6 @@
612 cves = SQLRelatedJoin('Cve', intermediateTable='BugCve',
613 orderBy='sequence', joinColumn='bug', otherColumn='cve')
614 cve_links = SQLMultipleJoin('BugCve', joinColumn='bug', orderBy='id')
615- mentoring_offers = SQLMultipleJoin(
616- 'MentoringOffer', joinColumn='bug', orderBy='id')
617 duplicates = SQLMultipleJoin(
618 'Bug', joinColumn='duplicateof', orderBy='id')
619 specifications = SQLRelatedJoin('Specification', joinColumn='bug',
620@@ -1389,42 +1386,6 @@
621 """See `IBug`."""
622 return self._question_from_bug
623
624- def canMentor(self, user):
625- """See `ICanBeMentored`."""
626- if user is None:
627- return False
628- if self.duplicateof is not None or self.is_complete:
629- return False
630- if bool(self.isMentor(user)):
631- return False
632- if not user.teams_participated_in:
633- return False
634- return True
635-
636- def isMentor(self, user):
637- """See `ICanBeMentored`."""
638- return MentoringOffer.selectOneBy(bug=self, owner=user) is not None
639-
640- def offerMentoring(self, user, team):
641- """See `ICanBeMentored`."""
642- # if an offer exists, then update the team
643- mentoringoffer = MentoringOffer.selectOneBy(bug=self, owner=user)
644- if mentoringoffer is not None:
645- mentoringoffer.team = team
646- return mentoringoffer
647- # if no offer exists, create one from scratch
648- mentoringoffer = MentoringOffer(owner=user, team=team,
649- bug=self)
650- notify(ObjectCreatedEvent(mentoringoffer, user=user))
651- return mentoringoffer
652-
653- def retractMentoring(self, user):
654- """See `ICanBeMentored`."""
655- mentoringoffer = MentoringOffer.selectOneBy(bug=self, owner=user)
656- if mentoringoffer is not None:
657- notify(ObjectDeletedEvent(mentoringoffer, user=user))
658- MentoringOffer.delete(mentoringoffer.id)
659-
660 def getMessageChunks(self):
661 """See `IBug`."""
662 query = """
663
664=== modified file 'lib/lp/bugs/model/bugtask.py'
665--- lib/lp/bugs/model/bugtask.py 2010-10-26 02:02:12 +0000
666+++ lib/lp/bugs/model/bugtask.py 2010-11-02 20:17:46 +0000
667@@ -359,37 +359,6 @@
668 result.add(that_pillar)
669 return sorted(result, key=pillar_sort_key)
670
671- @property
672- def mentoring_offers(self):
673- """See `IHasMentoringOffers`."""
674- # mentoring is on IBug as a whole, not on a specific task, so we
675- # pass through to the bug
676- return self.bug.mentoring_offers
677-
678- def canMentor(self, user):
679- """See `ICanBeMentored`."""
680- # mentoring is on IBug as a whole, not on a specific task, so we
681- # pass through to the bug
682- return self.bug.canMentor(user)
683-
684- def isMentor(self, user):
685- """See `ICanBeMentored`."""
686- # mentoring is on IBug as a whole, not on a specific task, so we
687- # pass through to the bug
688- return self.bug.isMentor(user)
689-
690- def offerMentoring(self, user, team):
691- """See `ICanBeMentored`."""
692- # mentoring is on IBug as a whole, not on a specific task, so we
693- # pass through to the bug
694- return self.bug.offerMentoring(user, team)
695-
696- def retractMentoring(self, user):
697- """See `ICanBeMentored`."""
698- # mentoring is on IBug as a whole, not on a specific task, so we
699- # pass through to the bug
700- return self.bug.retractMentoring(user)
701-
702
703 class NullBugTask(BugTaskMixin):
704 """A null object for IBugTask.
705@@ -1520,11 +1489,8 @@
706 from lp.blueprints.model.specificationbug import SpecificationBug
707 from lp.bugs.model.bug import Bug
708 from lp.bugs.model.bugbranch import BugBranch
709- from lp.registry.model.mentoringoffer import MentoringOffer
710
711 bug_ids = list(set(bugtask.bugID for bugtask in bugtasks))
712- bug_ids_with_mentoring_offers = set(IStore(MentoringOffer).find(
713- MentoringOffer.bugID, In(MentoringOffer.bugID, bug_ids)))
714 bug_ids_with_specifications = set(IStore(SpecificationBug).find(
715 SpecificationBug.bugID, In(SpecificationBug.bugID, bug_ids)))
716 bug_ids_with_branches = set(IStore(BugBranch).find(
717@@ -1538,8 +1504,6 @@
718 for bugtask in bugtasks:
719 bug = bugs[bugtask.bugID]
720 badge_properties[bugtask] = {
721- 'has_mentoring_offer':
722- bug.id in bug_ids_with_mentoring_offers,
723 'has_specification':
724 bug.id in bug_ids_with_specifications,
725 'has_branch':
726
727=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt'
728--- lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-10-18 22:24:59 +0000
729+++ lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-11-02 20:17:46 +0000
730@@ -194,8 +194,7 @@
731
732 == Bug Badge Decoration ==
733
734-We display bug badges for associated branches, mentorship,
735-specifications, patches, etc.
736+We display bug badges for associated branches, specifications, patches, etc.
737
738 >>> def names_and_branches(contents):
739 ... table = find_tag_by_id(contents, 'buglisting')
740
741=== removed file 'lib/lp/registry/browser/mentoringoffer.py'
742--- lib/lp/registry/browser/mentoringoffer.py 2010-08-20 20:31:18 +0000
743+++ lib/lp/registry/browser/mentoringoffer.py 1970-01-01 00:00:00 +0000
744@@ -1,200 +0,0 @@
745-# Copyright 2009 Canonical Ltd. This software is licensed under the
746-# GNU Affero General Public License version 3 (see the file LICENSE).
747-
748-"""Mentorship views."""
749-
750-__metaclass__ = type
751-
752-__all__ = [
753- 'CanBeMentoredView',
754- 'HasMentoringOffersView',
755- 'MentoringOfferSetFacets',
756- 'MentoringOfferSetOverviewMenu',
757- 'MentoringOfferSetView',
758- 'MentoringOfferAddView',
759- 'MentoringOfferRetractView',
760- ]
761-
762-from canonical.launchpad import _
763-from canonical.launchpad.webapp import (
764- action,
765- ApplicationMenu,
766- canonical_url,
767- LaunchpadFormView,
768- LaunchpadView,
769- Link,
770- StandardLaunchpadFacets,
771- )
772-from canonical.launchpad.webapp.batching import BatchNavigator
773-from lp.blueprints.interfaces.specification import ISpecification
774-from lp.bugs.interfaces.bugtask import IBugTask
775-from lp.registry.interfaces.distribution import IDistribution
776-from lp.registry.interfaces.mentoringoffer import (
777- IMentoringOffer,
778- IMentoringOfferSet,
779- )
780-from lp.registry.interfaces.person import IPerson
781-from lp.registry.interfaces.product import IProduct
782-from lp.registry.interfaces.projectgroup import IProjectGroup
783-
784-
785-class MentoringOfferSetFacets(StandardLaunchpadFacets):
786-
787- usedfor = IMentoringOfferSet
788-
789- enable_only = ['overview']
790-
791-
792-class MentoringOfferSetOverviewMenu(ApplicationMenu):
793-
794- usedfor = IMentoringOfferSet
795- facet = 'overview'
796- links = ['current', 'successful']
797-
798- def current(self):
799- text = 'Current offers'
800- return Link('+mentoring', text, icon='info')
801-
802- def successful(self):
803- text = 'Recent successes'
804- return Link('+success', text, icon='info')
805-
806-
807-class CanBeMentoredView:
808- """Used as a mixin on any view for something that can be mentored."""
809-
810- def userCanMentor(self):
811- """Is the user able to offer mentorship?"""
812- return self.context.canMentor(self.user)
813-
814- def userIsMentor(self):
815- """Is the user offering mentorship on this bug?"""
816- return self.context.isMentor(self.user)
817-
818-
819-class MentoringOfferAddView(LaunchpadFormView):
820- """This view will be used for objects that can be mentored, that
821- includes IBug, IBugTask and ISpecification
822- """
823-
824- schema = IMentoringOffer
825- label = "Offer to mentor this work"
826- field_names = ['team', 'subscription_request']
827- mentoring_offer = None
828-
829- def validate(self, data):
830- team = data.get('team')
831- if not self.user.inTeam(team):
832- # person must be a participant in team
833- self.setFieldError('team',
834- 'You can only offer mentorship for teams in which you are '
835- 'a member.')
836-
837- @action(_('Offer Mentoring'), name='add')
838- def add_action(self, action, data):
839- user = self.user
840- team = data.get('team')
841- self.mentoring_offer = self.context.offerMentoring(user, team)
842- subscribe = data.get('subscription_request')
843- if subscribe:
844- if not self.context.isSubscribed(user):
845- # XXX Tom Berger 2007-07-15: IBugTask
846- # and ISpecification (and everything
847- # else you can subscribe to) should
848- # implement a common interface and
849- # have the same signature for their
850- # subscribe method.
851- if IBugTask.providedBy(self.context):
852- self.context.subscribe(user, user)
853- elif ISpecification.providedBy(self.context):
854- self.context.subscribe(user, user, False)
855- else:
856- raise AssertionError, (
857- '%s does not provide IBugTask or ISpecification' %
858- self.context)
859- self.request.response.addInfoNotification(
860- 'You have subscribed to this item.')
861- self.request.response.addInfoNotification(
862- 'Thank you for this mentorship offer.')
863-
864- @property
865- def next_url(self):
866- assert self.mentoring_offer is not None, 'No mentorship recorded'
867- return canonical_url(self.context)
868-
869-
870-class MentoringOfferRetractView(LaunchpadFormView, CanBeMentoredView):
871- """This view is used to retract the offer of mentoring."""
872-
873- schema = IMentoringOffer
874- label = "Retract your offer of mentorship"
875- field_names = []
876-
877- @action(_('Retract Mentoring'), name='retract')
878- def add_action(self, action, data):
879- user = self.user
880- if self.context.isMentor(user):
881- self.context.retractMentoring(user)
882- self.request.response.addInfoNotification(
883- 'You are no longer offering mentoring on this work.')
884-
885- @property
886- def next_url(self):
887- return canonical_url(self.context)
888-
889-
890-class HasMentoringOffersView(LaunchpadView):
891-
892- # these flags determine which columns will be displayed. In the
893- # initialise() method, some columns may be disabled based on the type of
894- # context (person, team, project, mentorship manager)
895- show_person = True
896- show_team = True
897- show_date = True
898- show_work = True
899-
900- # these flags govern some of the content of the spec page, which allows
901- # us to vary the text flow slightly without creating large numbers of
902- # template fragments
903- is_person = False
904- is_team = False
905- is_pillar = False
906- is_manager = False
907-
908- def initialize(self):
909- if IPerson.providedBy(self.context):
910- if self.context.teamowner is None:
911- self.is_person = True
912- self.show_person = False
913- else:
914- self.is_team = True
915- self.show_team = False
916- elif (IDistribution.providedBy(self.context) or
917- IProduct.providedBy(self.context) or
918- IProjectGroup.providedBy(self.context)):
919- self.is_pillar = True
920- elif IMentoringOfferSet.providedBy(self.context):
921- self.is_manager = True
922- else:
923- raise AssertionError, 'Unknown mentorship listing site'
924- mapping = {'name': self.context.displayname}
925- if self.is_person:
926- self.title = _('Mentoring offered by $name', mapping=mapping)
927- else:
928- self.title = _('Offers of mentoring for $name', mapping=mapping)
929-
930- def batched_offers(self):
931- if self.is_team:
932- resultset = self.context.team_mentorships
933- else:
934- resultset = self.context.mentoring_offers
935- return BatchNavigator(resultset, self.request)
936-
937-
938-class MentoringOfferSetView(HasMentoringOffersView):
939-
940- def batched_successes(self):
941- return BatchNavigator(self.context.recent_completed_mentorships,
942- self.request)
943-
944-
945
946=== modified file 'lib/lp/registry/browser/milestone.py'
947--- lib/lp/registry/browser/milestone.py 2010-08-24 10:45:57 +0000
948+++ lib/lp/registry/browser/milestone.py 2010-11-02 20:17:46 +0000
949@@ -284,7 +284,6 @@
950 badge_property = self._bug_badge_properties[bugtask]
951 return BugTaskListingItem(
952 bugtask,
953- badge_property['has_mentoring_offer'],
954 badge_property['has_branch'],
955 badge_property['has_specification'],
956 badge_property['has_patch'])
957
958=== modified file 'lib/lp/registry/browser/tests/milestone-views.txt'
959--- lib/lp/registry/browser/tests/milestone-views.txt 2010-11-01 03:46:17 +0000
960+++ lib/lp/registry/browser/tests/milestone-views.txt 2010-11-02 20:17:46 +0000
961@@ -127,7 +127,6 @@
962 ... print '%s: %s' % (key, badge_dict[key])
963 <BugTask ...>
964 has_branch: False
965- has_mentoring_offer: False
966 has_patch: False
967 has_specification: False
968
969
970=== modified file 'lib/lp/registry/configure.zcml'
971--- lib/lp/registry/configure.zcml 2010-10-29 10:01:34 +0000
972+++ lib/lp/registry/configure.zcml 2010-11-02 20:17:46 +0000
973@@ -1802,17 +1802,6 @@
974 permission="launchpad.Edit"
975 set_schema="lp.registry.interfaces.distributionmirror.IMirrorProbeRecord" />
976 </class>
977- <class
978- class="lp.registry.model.mentoringoffer.MentoringOffer">
979- <allow
980- interface="lp.registry.interfaces.mentoringoffer.IMentoringOffer"/>
981- </class>
982- <securedutility
983- class="lp.registry.model.mentoringoffer.MentoringOfferSet"
984- provides="lp.registry.interfaces.mentoringoffer.IMentoringOfferSet">
985- <allow
986- interface="lp.registry.interfaces.mentoringoffer.IMentoringOfferSet"/>
987- </securedutility>
988
989 <!-- Packaging -->
990 <class
991
992=== removed file 'lib/lp/registry/doc/mentoringoffer.txt'
993--- lib/lp/registry/doc/mentoringoffer.txt 2010-11-01 03:46:17 +0000
994+++ lib/lp/registry/doc/mentoringoffer.txt 1970-01-01 00:00:00 +0000
995@@ -1,292 +0,0 @@
996-= The Mentoring System =
997-
998-== Offers of Mentoring ==
999-
1000-Launchpad allows people to make an offer of mentoring for a bug or
1001-specification. Here, Foo Bar will make an offer on a spec and a bug:
1002-
1003- >>> from lp.bugs.interfaces.bug import IBugSet
1004- >>> from lp.registry.interfaces.distribution import IDistributionSet
1005- >>> from lp.registry.interfaces.person import IPersonSet
1006- >>> from canonical.launchpad.ftests import login, syncUpdate
1007- >>> distroset = getUtility(IDistributionSet)
1008- >>> personset = getUtility(IPersonSet)
1009- >>> bugset = getUtility(IBugSet)
1010- >>> foo_bar = personset.getByEmail('foo.bar@canonical.com')
1011- >>> mark = personset.getByName('mark')
1012- >>> lpteam = personset.getByName('launchpad')
1013- >>> kubuntu = distroset.getByName('kubuntu')
1014- >>> bug2 = bugset.get(2)
1015- >>> bug2.is_complete
1016- False
1017- >>> spec1 = kubuntu.getSpecification('cluster-installation')
1018- >>> spec1.is_complete
1019- False
1020- >>> login('foo.bar@canonical.com')
1021- >>> offer1 = bug2.offerMentoring(foo_bar, lpteam)
1022- >>> offer2 = spec1.offerMentoring(foo_bar, lpteam)
1023-
1024-Now, it should be possible to see those offers on a variety of lists.
1025-
1026-First, we look at foo_bar's offers:
1027-
1028- >>> for offer in foo_bar.mentoring_offers:
1029- ... print offer.target.title
1030- Facilitate mass installs of Ubuntu using Netboot configuration
1031- Blackhole Trash folder
1032-
1033-Now, let's look at the list of offers associated with lpteam. For this we
1034-use the team_mentorships attribute, because mentoring_offers would imply
1035-offers made *by* the team, which we don't do. The team_memberships attribute
1036-is for mentorships made by people specifically in support of new members
1037-wanting to join that specific team:
1038-
1039- >>> for offer in lpteam.team_mentorships:
1040- ... print offer.target.title
1041- Facilitate mass installs of Ubuntu using Netboot configuration
1042- Blackhole Trash folder
1043-
1044-And at the offers related to Bug #2:
1045-
1046- >>> for offer in bug2.mentoring_offers:
1047- ... print offer.target.title
1048- Blackhole Trash folder
1049-
1050-And for the specification concerned:
1051-
1052- >>> for offer in spec1.mentoring_offers:
1053- ... print offer.target.title
1054- Facilitate mass installs of Ubuntu using Netboot configuration
1055-
1056-Now, Bug #2 is associated with both Ubuntu and Debian
1057-
1058- >>> ubuntu = distroset.getByName('ubuntu')
1059- >>> for offer in ubuntu.mentoring_offers:
1060- ... print offer.target.title
1061- Blackhole Trash folder
1062- >>> debian = distroset.getByName('debian')
1063- >>> for offer in debian.mentoring_offers:
1064- ... print offer.target.title
1065- Blackhole Trash folder
1066-
1067-It is also associated with the ubuntu *upstream* (this is a weirdness in the
1068-Launchpad sample data, we have an upstream product called Ubuntu).
1069-
1070- >>> from lp.registry.interfaces.product import IProductSet
1071- >>> productset = getUtility(IProductSet)
1072- >>> tomcat = productset.getByName('tomcat')
1073- >>> for offer in tomcat.mentoring_offers:
1074- ... print offer.target.title
1075- Blackhole Trash folder
1076-
1077-Now, it gets more interesting.
1078-
1079-Let us add a INVALID bugtask for Bug #2 on the Firefox product.
1080-So the offer of mentoring is NOT relevant to Firefox, and should not
1081-show up there.
1082-
1083- >>> firefox = productset.getByName('firefox')
1084- >>> from lp.bugs.interfaces.bugtask import (
1085- ... BugTaskImportance,
1086- ... BugTaskStatus,
1087- ... IBugTaskSet,
1088- ... )
1089- >>> bugtaskset = getUtility(IBugTaskSet)
1090- >>> ff_task = bugtaskset.createTask(
1091- ... bug=bug2, product=firefox, owner=mark,
1092- ... status=BugTaskStatus.INVALID,
1093- ... importance=BugTaskImportance.MEDIUM)
1094- >>> syncUpdate(ff_task)
1095- >>> ff_task.product == firefox
1096- True
1097- >>> for task in bug2.bugtasks:
1098- ... if task.product == firefox:
1099- ... print 'Found firefox task with status', task.status.name
1100- Found firefox task with status INVALID
1101-
1102- >>> print firefox.mentoring_offers.count()
1103- 0
1104-
1105-We also can get lists of offers of mentoring associated with ProjectGroups.
1106-Tomcat is part of the Apache project group, so:
1107-
1108- >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
1109- >>> projectset = getUtility(IProjectGroupSet)
1110- >>> apache = projectset.getByName('apache')
1111- >>> for offer in apache.mentoring_offers:
1112- ... print offer.target.title
1113- Blackhole Trash folder
1114-
1115-
1116-== The Mentorship Manager ==
1117-
1118-There is a utility which we can use to see all current mentorship offers
1119-across the whole system.
1120-
1121- >>> from lp.registry.interfaces.mentoringoffer import IMentoringOfferSet
1122- >>> mm = getUtility(IMentoringOfferSet)
1123- >>> print mm.mentoring_offers.count()
1124- 2
1125-
1126-== Mentoring lists do not include private items ==
1127-
1128-When a bug is marked private, it drops off the mentoring lists.
1129-
1130- >>> bug2.private
1131- False
1132- >>> bug2.setPrivate(True, getUtility(ILaunchBag).user)
1133- True
1134- >>> syncUpdate(bug2)
1135- >>> bug2.private
1136- True
1137-
1138-So, now that Bug #2 is private it should no longer appear in the list of
1139-mentorships offered by foo_bar:
1140-
1141- >>> for offer in lpteam.team_mentorships:
1142- ... print offer.target.title
1143- Facilitate mass installs of Ubuntu using Netboot configuration
1144-
1145-Let's make sure it is off all of the lists:
1146-
1147- >>> for offertarget in [foo_bar, apache, tomcat, debian, ubuntu, mm]:
1148- ... for offer in offertarget.mentoring_offers:
1149- ... if offer.target.title == 'Blackhole Trash folder':
1150- ... print 'Failed! Private bug showed in listing.'
1151-
1152-
1153-# NB these comments can be removed when we have private specs, which should
1154-# drop off the lists too.
1155-
1156-#And lets see if we can eliminate the spec by making that complete too.
1157-#
1158-# >>> spec1.private
1159-# False
1160-# >>> spec1.private = True
1161-# >>> syncUpdate(spec1)
1162-# >>> spec1.private
1163-# True
1164-# >>> print foo_bar.mentoring_offers.count()
1165-# 0
1166-
1167-#And both offers should have disappeared from ALL the listings we looked at
1168-#earlier:
1169-#
1170-# >>> print lpteam.team_mentorships.count()
1171-# 0
1172-# >>> print uproj.mentoring_offers.count()
1173-# 0
1174-# >>> print ubuntu_prod.mentoring_offers.count()
1175-# 0
1176-# >>> print debian.mentoring_offers.count()
1177-# 0
1178-# >>> print ubuntu.mentoring_offers.count()
1179-# 0
1180-
1181-#The mentorship manager should also no longer show those items:
1182-#
1183-# >>> print mm.mentoring_offers.count()
1184-# 0
1185-
1186-
1187-OK, let's mark the bug public again:
1188-
1189- >>> bug2.private
1190- True
1191- >>> bug2.setPrivate(False, getUtility(ILaunchBag).user)
1192- True
1193- >>> syncUpdate(bug2)
1194- >>> bug2.private
1195- False
1196-
1197-
1198-== Mentoring lists include only incomplete items ==
1199-
1200-When a spec or a bug is completed, it drops off the mentoring lists.
1201-
1202- >>> from lp.blueprints.enums import SpecificationImplementationStatus
1203- >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
1204- >>> bug2.is_complete
1205- False
1206- >>> from canonical.database.sqlbase import flush_database_updates
1207- >>> for task in bug2.bugtasks:
1208- ... if task.conjoined_master is None:
1209- ... task.transitionToStatus(
1210- ... BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user)
1211- >>> flush_database_updates()
1212- >>> bug2.is_complete
1213- True
1214-
1215-So, now that Bug #2 is "complete" it should no longer appear in the list of
1216-mentorships offered by foo_bar:
1217-
1218- >>> for offer in foo_bar.mentoring_offers:
1219- ... print offer.target.title
1220- Facilitate mass installs of Ubuntu using Netboot configuration
1221-
1222-And lets see if we can eliminate the spec by making that complete too.
1223-
1224- >>> spec1.is_complete
1225- False
1226- >>> spec1.implementation_status = SpecificationImplementationStatus.IMPLEMENTED
1227- >>> newstate = spec1.updateLifecycleStatus(foo_bar)
1228- >>> syncUpdate(spec1)
1229- >>> spec1.is_complete
1230- True
1231- >>> print foo_bar.mentoring_offers.count()
1232- 0
1233-
1234-And both offers should have disappeared from ALL the listings we looked at
1235-earlier:
1236-
1237- >>> print lpteam.team_mentorships.count()
1238- 0
1239- >>> print apache.mentoring_offers.count()
1240- 0
1241- >>> print tomcat.mentoring_offers.count()
1242- 0
1243- >>> print debian.mentoring_offers.count()
1244- 0
1245- >>> print ubuntu.mentoring_offers.count()
1246- 0
1247-
1248-The mentorship manager should also no longer show those items:
1249-
1250- >>> print mm.mentoring_offers.count()
1251- 0
1252-
1253-However, the mentorship manager should show these as recent successful
1254-mentorings:
1255-
1256- >>> for offer in mm.recent_completed_mentorships:
1257- ... print offer.target.title
1258- Blackhole Trash folder
1259- Facilitate mass installs of Ubuntu using Netboot configuration
1260-
1261-
1262-== Checking if the person is a Mentor ==
1263-
1264-Once an offer has been made, you can test to see if a person is a mentor for
1265-a bug or a blueprint.
1266-
1267- >>> stevea = personset.getByName('stevea')
1268- >>> bug2.isMentor(stevea)
1269- False
1270- >>> bug2.isMentor(foo_bar)
1271- True
1272- >>> spec1.isMentor(stevea)
1273- False
1274- >>> bug2.isMentor(foo_bar)
1275- True
1276-
1277-== Retracting mentorship offers ==
1278-
1279-We can also retract offers of mentoring.
1280-
1281- >>> bug2.retractMentoring(foo_bar)
1282- >>> bug2.isMentor(foo_bar)
1283- False
1284- >>> spec1.retractMentoring(foo_bar)
1285- >>> spec1.isMentor(foo_bar)
1286- False
1287-
1288
1289=== modified file 'lib/lp/registry/interfaces/distribution.py'
1290--- lib/lp/registry/interfaces/distribution.py 2010-10-29 10:01:34 +0000
1291+++ lib/lp/registry/interfaces/distribution.py 2010-11-02 20:17:46 +0000
1292@@ -76,7 +76,6 @@
1293 from lp.registry.interfaces.announcement import IMakesAnnouncements
1294 from lp.registry.interfaces.distributionmirror import IDistributionMirror
1295 from lp.registry.interfaces.karma import IKarmaContext
1296-from lp.registry.interfaces.mentoringoffer import IHasMentoringOffers
1297 from lp.registry.interfaces.milestone import (
1298 ICanGetMilestonesDirectly,
1299 IHasMilestones,
1300@@ -130,7 +129,7 @@
1301
1302 class IDistributionPublic(
1303 IBugTarget, ICanGetMilestonesDirectly, IHasAppointedDriver,
1304- IHasBuildRecords, IHasDrivers, IHasMentoringOffers, IHasMilestones,
1305+ IHasBuildRecords, IHasDrivers, IHasMilestones,
1306 IHasOwner, IHasSecurityContact, IHasSprints, IHasTranslationImports,
1307 ITranslationPolicy, IKarmaContext, ILaunchpadUsage, IMakesAnnouncements,
1308 IOfficialBugTagTargetPublic, IPillar, IServiceUsage,
1309
1310=== removed file 'lib/lp/registry/interfaces/mentoringoffer.py'
1311--- lib/lp/registry/interfaces/mentoringoffer.py 2010-08-20 20:31:18 +0000
1312+++ lib/lp/registry/interfaces/mentoringoffer.py 1970-01-01 00:00:00 +0000
1313@@ -1,95 +0,0 @@
1314-# Copyright 2009 Canonical Ltd. This software is licensed under the
1315-# GNU Affero General Public License version 3 (see the file LICENSE).
1316-
1317-# pylint: disable-msg=E0211,E0213
1318-
1319-"""MentoringOffer interfaces."""
1320-
1321-__metaclass__ = type
1322-
1323-__all__ = [
1324- 'ICanBeMentored',
1325- 'IHasMentoringOffers',
1326- 'IMentoringOffer',
1327- 'IMentoringOfferSet',
1328- ]
1329-
1330-
1331-from zope.interface import (
1332- Attribute,
1333- Interface,
1334- )
1335-from zope.schema import (
1336- Bool,
1337- Datetime,
1338- )
1339-
1340-from canonical.launchpad import _
1341-from lp.registry.interfaces.role import IHasOwner
1342-from lp.services.fields import PublicPersonChoice
1343-
1344-
1345-class IMentoringOffer(IHasOwner):
1346- """An offer of mentoring help."""
1347-
1348- owner = PublicPersonChoice(
1349- title=_('Owner'), required=True, readonly=True,
1350- vocabulary='ValidPerson')
1351- team = PublicPersonChoice(
1352- title=_('Team'), required=True, vocabulary='UserTeamsParticipation')
1353- date_created = Datetime(
1354- title=_('Date Created'), required=True, readonly=True)
1355- subscription_request = Bool(title=_('Email me about this'),
1356- required=True, description=_(
1357- "Subscribe me to this item so that I get emailed whenever "
1358- "the status changes or somebody comments. If you are already "
1359- "subscribed, then leaving this box clear will not "
1360- "unsubscribe you."))
1361-
1362-
1363- # other attributes we don't need to set through a form
1364- bug = Attribute('A bug, if that is the target, or None')
1365- specification = Attribute('A blueprint, if that is the target, or None')
1366- # properties
1367- target = Attribute("The bug or specification for which mentoring is"
1368- "offered.")
1369-
1370-
1371-class IHasMentoringOffers(Interface):
1372- """Used for objects which have mentoring offers."""
1373-
1374- mentoring_offers = Attribute(
1375- "The list of mentoring offers related to this object.")
1376-
1377-
1378-class ICanBeMentored(IHasMentoringOffers):
1379- """Used for objects which can have mentoring offered or retracted."""
1380-
1381- def canMentor(user):
1382- """True if this user could now offer mentoring on this piece of
1383- work. Will be negative if the user is already offering mentoring, or
1384- if the work is complete, for example.
1385- """
1386-
1387- def isMentor(user):
1388- """True if the user is offering mentoring for this piece of work."""
1389-
1390- def offerMentoring(user, team):
1391- """Record that the user is willing to mentor anyone who is trying to
1392- do this work.
1393- """
1394-
1395- def retractMentoring(user):
1396- """Remove the offer of mentoring for this work by this user."""
1397-
1398-
1399-class IMentoringOfferSet(IHasMentoringOffers):
1400- """An object which gives us an overview of mentorship in Launchpad."""
1401-
1402- displayname = Attribute('Display name')
1403- title = Attribute('Title')
1404-
1405- recent_completed_mentorships = Attribute(
1406- 'Mentorships offered in the past year for which the task (bug or '
1407- 'blueprint) has since been completed.')
1408-
1409
1410=== modified file 'lib/lp/registry/interfaces/person.py'
1411--- lib/lp/registry/interfaces/person.py 2010-11-02 06:21:58 +0000
1412+++ lib/lp/registry/interfaces/person.py 2010-11-02 20:17:46 +0000
1413@@ -129,7 +129,6 @@
1414 from lp.registry.interfaces.mailinglistsubscription import (
1415 MailingListAutoSubscribePolicy,
1416 )
1417-from lp.registry.interfaces.mentoringoffer import IHasMentoringOffers
1418 from lp.registry.interfaces.ssh import ISSHKey
1419 from lp.registry.interfaces.teammembership import (
1420 ITeamMembership,
1421@@ -509,7 +508,7 @@
1422 description=_("The reason the person's standing is what it is."))
1423
1424
1425-class IPersonPublic(IHasBranches, IHasSpecifications, IHasMentoringOffers,
1426+class IPersonPublic(IHasBranches, IHasSpecifications,
1427 IHasMergeProposals, IHasLogo, IHasMugshot, IHasIcon,
1428 IHasLocation, IHasRequestedReviews, IObjectWithLocation,
1429 IPrivacy, IHasBugs, IHasRecipes, IHasTranslationImports):
1430@@ -723,8 +722,6 @@
1431 assigned_specs_in_progress = Attribute(
1432 "Specifications assigned to this person whose implementation is "
1433 "started but not yet completed, sorted newest first.")
1434- team_mentorships = Attribute(
1435- "All the offers of mentoring which are relevant to this team.")
1436 teamowner = exported(
1437 PublicPersonChoice(
1438 title=_('Team Owner'), required=False, readonly=False,
1439
1440=== modified file 'lib/lp/registry/interfaces/product.py'
1441--- lib/lp/registry/interfaces/product.py 2010-10-29 10:01:34 +0000
1442+++ lib/lp/registry/interfaces/product.py 2010-11-02 20:17:46 +0000
1443@@ -108,7 +108,6 @@
1444 ICommercialSubscription,
1445 )
1446 from lp.registry.interfaces.karma import IKarmaContext
1447-from lp.registry.interfaces.mentoringoffer import IHasMentoringOffers
1448 from lp.registry.interfaces.milestone import (
1449 ICanGetMilestonesDirectly,
1450 IHasMilestones,
1451@@ -408,7 +407,7 @@
1452 class IProductPublic(
1453 IBugTarget, ICanGetMilestonesDirectly, IHasAppointedDriver, IHasBranches,
1454 IHasBranchVisibilityPolicy, IHasDrivers, IHasExternalBugTracker, IHasIcon,
1455- IHasLogo, IHasMentoringOffers, IHasMergeProposals, IHasMilestones,
1456+ IHasLogo, IHasMergeProposals, IHasMilestones,
1457 IHasMugshot, IHasOwner, IHasSecurityContact, IHasSprints,
1458 IHasTranslationImports, ITranslationPolicy, IKarmaContext,
1459 ILaunchpadUsage, IMakesAnnouncements, IOfficialBugTagTargetPublic,
1460
1461=== modified file 'lib/lp/registry/interfaces/projectgroup.py'
1462--- lib/lp/registry/interfaces/projectgroup.py 2010-10-20 14:05:26 +0000
1463+++ lib/lp/registry/interfaces/projectgroup.py 2010-11-02 20:17:46 +0000
1464@@ -68,7 +68,6 @@
1465 )
1466 from lp.registry.interfaces.announcement import IMakesAnnouncements
1467 from lp.registry.interfaces.karma import IKarmaContext
1468-from lp.registry.interfaces.mentoringoffer import IHasMentoringOffers
1469 from lp.registry.interfaces.milestone import (
1470 ICanGetMilestonesDirectly,
1471 IHasMilestones,
1472@@ -110,7 +109,7 @@
1473 class IProjectGroupPublic(
1474 ICanGetMilestonesDirectly, IHasAppointedDriver, IHasBranches, IHasBugs,
1475 IHasDrivers, IHasBranchVisibilityPolicy, IHasIcon, IHasLogo,
1476- IHasMentoringOffers, IHasMergeProposals, IHasMilestones, IHasMugshot,
1477+ IHasMergeProposals, IHasMilestones, IHasMugshot,
1478 IHasOwner, IHasSpecifications, IHasSprints, IMakesAnnouncements,
1479 IKarmaContext, IRootContext, IHasOfficialBugTags, IServiceUsage):
1480 """Public IProjectGroup properties."""
1481
1482=== modified file 'lib/lp/registry/model/distribution.py'
1483--- lib/lp/registry/model/distribution.py 2010-11-02 06:21:58 +0000
1484+++ lib/lp/registry/model/distribution.py 2010-11-02 20:17:46 +0000
1485@@ -139,7 +139,6 @@
1486 )
1487 from lp.registry.model.distroseries import DistroSeries
1488 from lp.registry.model.karma import KarmaContextMixin
1489-from lp.registry.model.mentoringoffer import MentoringOffer
1490 from lp.registry.model.milestone import (
1491 HasMilestonesMixin,
1492 Milestone,
1493@@ -538,27 +537,6 @@
1494 return architectures
1495
1496 @property
1497- def mentoring_offers(self):
1498- """See `IDistribution`"""
1499- via_specs = MentoringOffer.select("""
1500- Specification.distribution = %s AND
1501- Specification.id = MentoringOffer.specification
1502- """ % sqlvalues(self.id) + """ AND NOT (
1503- """ + Specification.completeness_clause + ")",
1504- clauseTables=['Specification'],
1505- distinct=True)
1506- via_bugs = MentoringOffer.select("""
1507- BugTask.distribution = %s AND
1508- BugTask.bug = MentoringOffer.bug AND
1509- BugTask.bug = Bug.id AND
1510- Bug.private IS FALSE
1511- """ % sqlvalues(self.id) + """ AND NOT (
1512- """ + BugTask.completeness_clause +")",
1513- clauseTables=['BugTask', 'Bug'],
1514- distinct=True)
1515- return via_specs.union(via_bugs, orderBy=['-date_created', '-id'])
1516-
1517- @property
1518 def bugtargetdisplayname(self):
1519 """See IBugTarget."""
1520 return self.displayname
1521
1522=== removed file 'lib/lp/registry/model/mentoringoffer.py'
1523--- lib/lp/registry/model/mentoringoffer.py 2010-08-20 20:31:18 +0000
1524+++ lib/lp/registry/model/mentoringoffer.py 1970-01-01 00:00:00 +0000
1525@@ -1,121 +0,0 @@
1526-# Copyright 2009 Canonical Ltd. This software is licensed under the
1527-# GNU Affero General Public License version 3 (see the file LICENSE).
1528-
1529-# pylint: disable-msg=E0611,W0212
1530-
1531-__metaclass__ = type
1532-__all__ = [
1533- 'MentoringOffer',
1534- 'MentoringOfferSet',
1535- ]
1536-
1537-from datetime import (
1538- datetime,
1539- timedelta,
1540- )
1541-
1542-import pytz
1543-from sqlobject import ForeignKey
1544-from zope.interface import implements
1545-
1546-from canonical.database.constants import DEFAULT
1547-from canonical.database.datetimecol import UtcDateTimeCol
1548-from canonical.database.sqlbase import (
1549- SQLBase,
1550- sqlvalues,
1551- )
1552-from lp.registry.interfaces.mentoringoffer import (
1553- IMentoringOffer,
1554- IMentoringOfferSet,
1555- )
1556-from lp.registry.interfaces.person import validate_public_person
1557-
1558-
1559-class MentoringOffer(SQLBase):
1560- """See IMentoringOffer."""
1561-
1562- implements(IMentoringOffer)
1563-
1564- _defaultOrder = ['-date_created', '-id']
1565-
1566- # db field names
1567- owner = ForeignKey(
1568- dbName='owner', foreignKey='Person',
1569- storm_validator=validate_public_person, notNull=True)
1570- date_created = UtcDateTimeCol(notNull=True, default=DEFAULT)
1571- team = ForeignKey(
1572- dbName='team', foreignKey='Person',
1573- storm_validator=validate_public_person, notNull=True)
1574- bug = ForeignKey(dbName='bug', notNull=False,
1575- foreignKey='Bug', default=None)
1576- specification = ForeignKey(dbName='specification', notNull=False,
1577- foreignKey='Specification', default=None)
1578-
1579- # attributes
1580- @property
1581- def target(self):
1582- """See IMentoringOffer."""
1583- if self.bug:
1584- return self.bug
1585- return self.specification
1586-
1587- @property
1588- def subscription_request(self):
1589- """See IMentoringOffer.
1590-
1591- In this case, we return the subscription status of the person on the
1592- underlying target.
1593- """
1594- return self.target.isSubscribed(self.owner)
1595-
1596-
1597-class MentoringOfferSet:
1598- """See IMentoringOfferSet."""
1599-
1600- implements(IMentoringOfferSet)
1601-
1602- displayname = 'the Launchpad Mentorship Manager'
1603- title = 'Launchpad Mentorship Manager'
1604-
1605- @property
1606- def mentoring_offers(self):
1607- """See IHasMentoringOffers."""
1608- # import here to avoid circular imports
1609- from lp.blueprints.model.specification import Specification
1610- from lp.bugs.model.bugtask import BugTask
1611- via_specs = MentoringOffer.select("""
1612- Specification.id = MentoringOffer.specification AND NOT
1613- (""" + Specification.completeness_clause +")",
1614- clauseTables=['Specification'],
1615- distinct=True)
1616- via_bugs = MentoringOffer.select("""
1617- BugTask.bug = Bug.id AND
1618- Bug.private IS FALSE AND
1619- BugTask.bug = MentoringOffer.bug AND NOT (
1620- """ + BugTask.completeness_clause + ")",
1621- clauseTables=['BugTask', 'Bug'],
1622- distinct=True)
1623- return via_specs.union(via_bugs, orderBy=['-date_created'])
1624-
1625- @property
1626- def recent_completed_mentorships(self):
1627- """See IHasMentoringOffers."""
1628- # import here to avoid circular imports
1629- from lp.blueprints.model.specification import Specification
1630- from lp.bugs.model.bugtask import BugTask
1631- now = datetime.now(pytz.timezone('UTC'))
1632- yearago = now - timedelta(365)
1633- via_specs = MentoringOffer.select("""
1634- MentoringOffer.date_created > %s AND
1635- """ % sqlvalues(yearago) + """
1636- Specification.id = MentoringOffer.specification AND
1637- (""" + Specification.completeness_clause +")",
1638- clauseTables=['Specification'])
1639- via_bugs = MentoringOffer.select("""
1640- MentoringOffer.date_created > %s AND
1641- """ % sqlvalues(yearago) + """
1642- BugTask.bug = MentoringOffer.bug AND (
1643- """ + BugTask.completeness_clause + ")",
1644- clauseTables=['BugTask'])
1645- return via_specs.union(via_bugs).orderBy("id")
1646-
1647
1648=== modified file 'lib/lp/registry/model/person.py'
1649--- lib/lp/registry/model/person.py 2010-11-02 06:21:58 +0000
1650+++ lib/lp/registry/model/person.py 2010-11-02 20:17:46 +0000
1651@@ -251,7 +251,6 @@
1652 KarmaCategory,
1653 KarmaTotalCache,
1654 )
1655-from lp.registry.model.mentoringoffer import MentoringOffer
1656 from lp.registry.model.personlocation import PersonLocation
1657 from lp.registry.model.pillar import PillarName
1658 from lp.registry.model.structuralsubscription import StructuralSubscription
1659@@ -666,53 +665,6 @@
1660 """ % replacements
1661 return Specification.select(query, orderBy=['-date_started'], limit=5)
1662
1663- # mentorship
1664- @property
1665- def mentoring_offers(self):
1666- """See `IPerson`"""
1667- return MentoringOffer.select("""MentoringOffer.id IN
1668- (SELECT MentoringOffer.id
1669- FROM MentoringOffer
1670- LEFT OUTER JOIN BugTask ON
1671- MentoringOffer.bug = BugTask.bug
1672- LEFT OUTER JOIN Bug ON
1673- BugTask.bug = Bug.id
1674- LEFT OUTER JOIN Specification ON
1675- MentoringOffer.specification = Specification.id
1676- WHERE
1677- MentoringOffer.owner = %s
1678- """ % sqlvalues(self.id) + """ AND (
1679- BugTask.id IS NULL OR NOT
1680- (Bug.private IS TRUE OR
1681- (""" + BugTask.completeness_clause +"""))) AND (
1682- Specification.id IS NULL OR NOT
1683- (""" + Specification.completeness_clause +")))",
1684- )
1685-
1686- @property
1687- def team_mentorships(self):
1688- """See `IPerson`"""
1689- return MentoringOffer.select("""MentoringOffer.id IN
1690- (SELECT MentoringOffer.id
1691- FROM MentoringOffer
1692- JOIN TeamParticipation ON
1693- MentoringOffer.team = TeamParticipation.person
1694- LEFT OUTER JOIN BugTask ON
1695- MentoringOffer.bug = BugTask.bug
1696- LEFT OUTER JOIN Bug ON
1697- BugTask.bug = Bug.id
1698- LEFT OUTER JOIN Specification ON
1699- MentoringOffer.specification = Specification.id
1700- WHERE
1701- TeamParticipation.team = %s
1702- """ % sqlvalues(self.id) + """ AND (
1703- BugTask.id IS NULL OR NOT
1704- (Bug.private IS TRUE OR
1705- (""" + BugTask.completeness_clause +"""))) AND (
1706- Specification.id IS NULL OR NOT
1707- (""" + Specification.completeness_clause +")))",
1708- )
1709-
1710 @property
1711 def unique_displayname(self):
1712 """See `IPerson`."""
1713@@ -3546,40 +3498,6 @@
1714 DELETE FROM QuestionSubscription WHERE person=%(from_id)d
1715 ''' % vars())
1716
1717- def _mergeMentoringOffer(self, cur, from_id, to_id):
1718- # Update only the MentoringOffers that will not conflict.
1719- cur.execute('''
1720- UPDATE MentoringOffer
1721- SET owner=%(to_id)d
1722- WHERE owner=%(from_id)d
1723- AND bug NOT IN (
1724- SELECT bug
1725- FROM MentoringOffer
1726- WHERE owner = %(to_id)d)
1727- AND specification NOT IN (
1728- SELECT specification
1729- FROM MentoringOffer
1730- WHERE owner = %(to_id)d)
1731- ''' % vars())
1732- cur.execute('''
1733- UPDATE MentoringOffer
1734- SET team=%(to_id)d
1735- WHERE team=%(from_id)d
1736- AND bug NOT IN (
1737- SELECT bug
1738- FROM MentoringOffer
1739- WHERE team = %(to_id)d)
1740- AND specification NOT IN (
1741- SELECT specification
1742- FROM MentoringOffer
1743- WHERE team = %(to_id)d)
1744- ''' % vars())
1745- # and delete those left over.
1746- cur.execute('''
1747- DELETE FROM MentoringOffer
1748- WHERE owner=%(from_id)d OR team=%(from_id)d
1749- ''' % vars())
1750-
1751 def _mergeBugNotificationRecipient(self, cur, from_id, to_id):
1752 # Update BugNotificationRecipient entries that will not conflict.
1753 cur.execute('''
1754@@ -3943,7 +3861,7 @@
1755 self._mergeQuestionSubscription(cur, from_id, to_id)
1756 skip.append(('questionsubscription', 'person'))
1757
1758- self._mergeMentoringOffer(cur, from_id, to_id)
1759+ # DELETE when the mentoring table is deleted.
1760 skip.append(('mentoringoffer', 'owner'))
1761 skip.append(('mentoringoffer', 'team'))
1762
1763
1764=== modified file 'lib/lp/registry/model/product.py'
1765--- lib/lp/registry/model/product.py 2010-11-02 06:21:58 +0000
1766+++ lib/lp/registry/model/product.py 2010-11-02 20:17:46 +0000
1767@@ -142,7 +142,6 @@
1768 from lp.registry.model.distribution import Distribution
1769 from lp.registry.model.distroseries import DistroSeries
1770 from lp.registry.model.karma import KarmaContextMixin
1771-from lp.registry.model.mentoringoffer import MentoringOffer
1772 from lp.registry.model.milestone import (
1773 HasMilestonesMixin,
1774 Milestone,
1775@@ -1020,27 +1019,6 @@
1776 return None
1777
1778 @property
1779- def mentoring_offers(self):
1780- """See `IProduct`"""
1781- via_specs = MentoringOffer.select("""
1782- Specification.product = %s AND
1783- Specification.id = MentoringOffer.specification
1784- """ % sqlvalues(self.id) + """ AND NOT
1785- (""" + Specification.completeness_clause + ")",
1786- clauseTables=['Specification'],
1787- distinct=True)
1788- via_bugs = MentoringOffer.select("""
1789- BugTask.product = %s AND
1790- BugTask.bug = MentoringOffer.bug AND
1791- BugTask.bug = Bug.id AND
1792- Bug.private IS FALSE
1793- """ % sqlvalues(self.id) + """ AND NOT (
1794- """ + BugTask.completeness_clause + ")",
1795- clauseTables=['BugTask', 'Bug'],
1796- distinct=True)
1797- return via_specs.union(via_bugs, orderBy=['-date_created', '-id'])
1798-
1799- @property
1800 def translationgroups(self):
1801 tg = []
1802 if self.translationgroup:
1803
1804=== modified file 'lib/lp/registry/model/projectgroup.py'
1805--- lib/lp/registry/model/projectgroup.py 2010-11-01 03:57:52 +0000
1806+++ lib/lp/registry/model/projectgroup.py 2010-11-02 20:17:46 +0000
1807@@ -92,7 +92,6 @@
1808 )
1809 from lp.registry.model.announcement import MakesAnnouncements
1810 from lp.registry.model.karma import KarmaContextMixin
1811-from lp.registry.model.mentoringoffer import MentoringOffer
1812 from lp.registry.model.milestone import (
1813 HasMilestonesMixin,
1814 Milestone,
1815@@ -184,29 +183,6 @@
1816 return [self.driver]
1817 return []
1818
1819- @property
1820- def mentoring_offers(self):
1821- """See `IProjectGroup`."""
1822- via_specs = MentoringOffer.select("""
1823- Product.project = %s AND
1824- Specification.product = Product.id AND
1825- Specification.id = MentoringOffer.specification
1826- """ % sqlvalues(self.id) + """ AND NOT
1827- (""" + Specification.completeness_clause +")",
1828- clauseTables=['Product', 'Specification'],
1829- distinct=True)
1830- via_bugs = MentoringOffer.select("""
1831- Product.project = %s AND
1832- BugTask.product = Product.id AND
1833- BugTask.bug = MentoringOffer.bug AND
1834- BugTask.bug = Bug.id AND
1835- Bug.private IS FALSE
1836- """ % sqlvalues(self.id) + """ AND NOT (
1837- """ + BugTask.completeness_clause + ")",
1838- clauseTables=['Product', 'BugTask', 'Bug'],
1839- distinct=True)
1840- return via_specs.union(via_bugs, orderBy=['-date_created', '-id'])
1841-
1842 def translatables(self):
1843 """See `IProjectGroup`."""
1844 # XXX j.c.sackett 2010-08-30 bug=627631: Once data migration has
1845
1846=== modified file 'utilities/migrater/file-ownership.txt'
1847--- utilities/migrater/file-ownership.txt 2010-10-27 14:25:19 +0000
1848+++ utilities/migrater/file-ownership.txt 2010-11-02 20:17:46 +0000
1849@@ -66,7 +66,6 @@
1850 ./browser/librarian.py
1851 ./browser/logintoken.py
1852 reg ./browser/mailinglists.py
1853-reg ./browser/mentoringoffer.py
1854 ./browser/message.py
1855 reg ./browser/milestone.py
1856 ./browser/multistep.py
1857@@ -251,7 +250,6 @@
1858 ./database/librarian.py
1859 ./database/logintoken.py
1860 reg ./database/mailinglist.py
1861-reg ./database/mentoringoffer.py
1862 ./database/message.py
1863 reg ./database/milestone.py
1864 ./database/oauth.py
1865@@ -442,7 +440,6 @@
1866 reg ./interfaces/mailinglist.py
1867 reg ./interfaces/mailinglistsubscription.py
1868 bug ./interfaces/malone.py
1869-reg ./interfaces/mentoringoffer.py
1870 fnd ./interfaces/message.py
1871 reg ./interfaces/milestone.py
1872 fnd ./interfaces/oauth.py
1873@@ -937,7 +934,6 @@
1874 ./zcml/packagebugsupervisor.zcml
1875 ./zcml/translationimport.zcml
1876 ./zcml/seriessourcepackagebranch.zcml
1877- ./zcml/mentoringoffer.zcml
1878 ./zcml/bugnotification.zcml
1879 ./zcml/decoratedresultset.zcml
1880 ./zcml/sourcepackagerelease.zcml
1881@@ -1129,7 +1125,6 @@
1882 ./icing/but-sml-helptranslate-down.gif
1883 ./icing/navigation-hierarchy-home-bg
1884 ./icing/navigation-nw-w-selected.png
1885- ./icing/but-sml-mentoring-over.gif
1886 ./icing/app-answers.gif
1887 ./icing/mainarea_bottom.gif
1888 ./icing/navigation-tabs-se-blueprints
1889@@ -1180,7 +1175,6 @@
1890 ./icing/app-register-sml.gif
1891 ./icing/app-register-sml-down.gif
1892 ./icing/app-translations-sml-over.gif
1893- ./icing/but-sml-mentoring.gif
1894 ./icing/navigation-ne-e-normal.png
1895 ./icing/appchoose_tab2_a.gif
1896 ./icing/but-sml-helptranslate-over.gif
1897@@ -1210,7 +1204,6 @@
1898 ./icing/app-code-sml-down.gif
1899 ./icing/navigation-hierarchy-bg
1900 ./icing/help-bottom.gif
1901- ./icing/but-sml-mentoring-off.gif
1902 ./icing/launchpad-tour-screenshot1.png
1903 ./icing/app-answers-wm.gif
1904 ./icing/navigation-hierarchy-chevron-selected
1905@@ -1242,7 +1235,6 @@
1906 ./icing/app-people-sml-over.gif
1907 ./icing/navigation-n.png
1908 ./icing/app-register-wm.gif
1909- ./icing/but-sml-mentoring-down.gif
1910 ./icing/answers-feature-language.png
1911 ./icing/navigation-tabs-se-bugs-active
1912 ./icing/code-tour-screenshot3.png
1913@@ -1373,7 +1365,6 @@
1914 ./images/build-needed.png
1915 ./images/security.png
1916 ./images/security-large.png
1917- ./images/mentoring.png
1918 ./images/bug-remote.png
1919 ./images/launchpad-logo.png
1920 ./images/edit.png
1921@@ -1385,7 +1376,6 @@
1922 ./images/translate.ubuntu.png
1923 ./images/bug.png
1924 ./images/crowd.png
1925- ./images/mentoring-large.png
1926 ./images/rss-large.png
1927 ./images/file_icon.gif
1928 ./images/do-not-disturb.png
1929@@ -2324,7 +2314,6 @@
1930 reg ./doc/mailinglist-subscriptions.txt
1931 reg ./doc/mailinglist-xmlrpc.txt
1932 reg ./doc/mailinglists.txt
1933-reg ./doc/mentoringoffer.txt
1934 reg ./doc/message-holds-xmlrpc.txt
1935 reg ./doc/message-holds.txt
1936 reg ./doc/milestone.txt
1937@@ -2918,8 +2907,6 @@
1938 reg ./pagetests/mailinglists/moderation.txt
1939 reg ./pagetests/mailinglists/subscriptions.txt
1940 reg ./pagetests/mailinglists/welcome-message.txt
1941-reg ./pagetests/mentoring
1942-reg ./pagetests/mentoring/mentoring.txt
1943 reg ./pagetests/milestone
1944 reg ./pagetests/milestone/object-milestones.txt
1945 reg ./pagetests/milestone/xx-create-milestone-on-distribution.txt