11235.5.4
by Curtis Hovey
hush lint. |
1 |
Questions Expiration |
2 |
==================== |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
3 |
|
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
4 |
It is not productive to have questions lying around forever in |
5 |
the Answer Tracker. That's why we have a script which runs daily to |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
6 |
expire old questions on which there was no activity for the past two |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
7 |
weeks. |
8 |
||
3691.197.52
by Francis J. Lacoste
Typos, grammar and other cleanup |
9 |
The expiration period is set using the |
3691.398.24
by Francis J. Lacoste
Rename config section. |
10 |
config.answertracker.days_before_expiration configuration variable. It |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
11 |
defaults to 15 days. |
12 |
||
13 |
>>> from canonical.config import config |
|
3691.398.24
by Francis J. Lacoste
Rename config section. |
14 |
>>> config.answertracker.days_before_expiration |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
15 |
15 |
16 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
17 |
Only questions in the OPEN or NEEDSINFO state which aren't assigned to |
3691.264.1
by Francis J. Lacoste
Do not expire old assigned tickets. |
18 |
somebody are subject to expiration. |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
19 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
20 |
# Sanity check in case somebody modifies the question sampledata and |
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
21 |
# forget to update this script. |
12915.5.1
by Curtis Hovey
Rename questionenums.py to the new standard or enums.py |
22 |
>>> from lp.answers.enums import QuestionStatus |
8971.22.2
by Guilherme Salgado
Fix a bunch of tests to import registry model classes from lp.registry.model instead of from canonical.launchpad.database |
23 |
>>> from lp.answers.model.question import Question |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
24 |
>>> Question.select('status IN (%i,%i)' % ( |
11235.5.4
by Curtis Hovey
hush lint. |
25 |
... QuestionStatus.OPEN.value, |
26 |
... QuestionStatus.NEEDSINFO.value)).count() |
|
4443.1.6
by Curtis Hovey
Added an arabic question and a test that it displays right-to-left. |
27 |
9 |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
28 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
29 |
# By default, all open and needs info question should expire. Make |
30 |
# sure that no new questions were recently added and will make this |
|
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
31 |
# test fails in the future. |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
32 |
>>> Question.select( |
3691.197.72
by Francis J. Lacoste
Make sure future sample data changes do not make expiration test fails with a delay |
33 |
... "datelastresponse >= current_timestamp - interval '15 days' OR " |
34 |
... "datelastquery >= current_timestamp - interval '15 days'").count() |
|
35 |
0 |
|
36 |
||
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
37 |
# We need to massage sample data a little. Since all expiration |
38 |
# candidates in sample data would expire, do a little activity on |
|
39 |
# some of these. |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
40 |
>>> from datetime import datetime, timedelta |
41 |
>>> from pytz import UTC |
|
42 |
>>> now = datetime.now(UTC) |
|
43 |
>>> two_weeks_ago = now - timedelta(days=14) |
|
44 |
>>> a_month_ago = now - timedelta(days=31) |
|
10409.5.38
by Curtis Hovey
Removed glob imports for answers. |
45 |
>>> from canonical.launchpad.webapp.interfaces import ILaunchBag |
11716.1.12
by Curtis Hovey
Sorted imports in doctests. |
46 |
>>> from lp.answers.interfaces.questioncollection import IQuestionSet |
10409.5.38
by Curtis Hovey
Removed glob imports for answers. |
47 |
>>> from lp.registry.interfaces.person import IPersonSet |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
48 |
>>> login('no-priv@canonical.com') |
49 |
>>> no_priv = getUtility(ILaunchBag).user |
|
50 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
51 |
>>> questionset = getUtility(IQuestionSet) |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
52 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
53 |
# An old question in NEEDSINFO the state. |
54 |
>>> old_needs_info_question = questionset.get(7) |
|
55 |
>>> print old_needs_info_question.status.title |
|
3691.264.1
by Francis J. Lacoste
Do not expire old assigned tickets. |
56 |
Needs information |
57 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
58 |
# An open question assigned to somebody. |
3691.264.1
by Francis J. Lacoste
Do not expire old assigned tickets. |
59 |
>>> login('foo.bar@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
60 |
>>> old_assigned_open_question = questionset.get(1) |
61 |
>>> old_assigned_open_question.assignee = getUtility(ILaunchBag).user |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
62 |
|
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
63 |
# This one got an update from its owner recently. |
3691.197.109
by Francis J. Lacoste
- Add launchpad.Owner permission. |
64 |
>>> login('test@canonical.com') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
65 |
>>> recent_open_question = questionset.get(2) |
66 |
>>> recent_open_question.giveInfo( |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
67 |
... 'SVG works better now, but is still broken') |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
68 |
<QuestionMessage...> |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
69 |
|
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
70 |
# This one was put in the NEEDSINFO state recently. |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
71 |
>>> recent_needsinfo_question = questionset.get(4) |
3881.1.2
by Francis J. Lacoste
Fix spurious replace. |
72 |
>>> recent_needsinfo_question.requestInfo( |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
73 |
... no_priv, 'What URL were you visiting?') |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
74 |
<QuestionMessage...> |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
75 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
76 |
# Old open questions. |
77 |
>>> old_open_question = questionset.get(5) |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
78 |
|
3881.1.1
by Francis J. Lacoste
Renamed reference to support tracker in doctests. |
79 |
# Subscribe a team to that question, and a answer contact, |
3691.261.1
by Francis J. Lacoste
Fix bug 74941 (Database permission exception in ticket expiration) by granting permission to personlanguage to the script. |
80 |
# to make sure that DB permissions are correct. |
3691.69.12
by Francis J. Lacoste
Grant permission to teammembership for tickettracker user. |
81 |
>>> admin_team = getUtility(IPersonSet).getByName('admins') |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
82 |
>>> old_open_question.subscribe(admin_team) |
3691.398.19
by Francis J. Lacoste
Rename most remaining classes (views, database, authorizations, notifications, scripts.) |
83 |
<QuestionSubscription...> |
3691.261.1
by Francis J. Lacoste
Fix bug 74941 (Database permission exception in ticket expiration) by granting permission to personlanguage to the script. |
84 |
>>> salgado = getUtility(IPersonSet).getByName('salgado') |
12959.4.21
by Curtis Hovey
Alway pass the subscribed_by argument to addAnswerContact. |
85 |
>>> old_open_question.target.addAnswerContact(salgado, salgado) |
3691.261.1
by Francis J. Lacoste
Fix bug 74941 (Database permission exception in ticket expiration) by granting permission to personlanguage to the script. |
86 |
True |
3691.69.12
by Francis J. Lacoste
Grant permission to teammembership for tickettracker user. |
87 |
|
5686.1.1
by Francis J. Lacoste
Fix missing security declaration for FAQ. |
88 |
# Link it to a FAQ item for the same reason. We are setting the |
89 |
# attribute directly, because using the linkFAQ API would update |
|
90 |
# the last updates date of the question and remove it from the expiration |
|
91 |
# set. |
|
92 |
>>> from zope.security.proxy import removeSecurityProxy |
|
93 |
>>> login('foo.bar@canonical.com') |
|
94 |
>>> faq = old_open_question.target.newFAQ( |
|
95 |
... salgado, 'Why everyone think this is weird.', |
|
96 |
... "That's an easy one. It's because it is!") |
|
97 |
>>> removeSecurityProxy(old_open_question).faq = faq |
|
98 |
||
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
99 |
# A question linked to an non-Invalid bug is not expirable. |
10409.5.38
by Curtis Hovey
Removed glob imports for answers. |
100 |
>>> from lp.bugs.interfaces.bug import IBugSet |
101 |
>>> from lp.bugs.interfaces.bugtask import BugTaskStatus |
|
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
102 |
>>> fixed_bug = getUtility(IBugSet).get(9) |
103 |
>>> bugtasks = fixed_bug.bugtasks |
|
104 |
>>> bugtasks[1].transitionToStatus(BugTaskStatus.INVALID, no_priv) |
|
105 |
>>> [bugtask.status.title for bugtask in bugtasks] |
|
106 |
['Unknown', 'Invalid'] |
|
107 |
>>> bug_link_question = questionset.get(11) |
|
4813.9.2
by Curtis Hovey
Changes pre review. |
108 |
>>> bug_link_question.linkBug(fixed_bug) |
109 |
<QuestionBug at ...> |
|
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
110 |
|
111 |
# A question linked to an Invalid bug; it is expirable. |
|
112 |
>>> invalid_bug = getUtility(IBugSet).get(10) |
|
113 |
>>> bugtask = invalid_bug.bugtasks[0] |
|
114 |
>>> bugtask.transitionToStatus(BugTaskStatus.INVALID, no_priv) |
|
115 |
>>> bugtask.status.title |
|
116 |
'Invalid' |
|
117 |
>>> invalid_bug_question = questionset.get(12) |
|
4813.9.2
by Curtis Hovey
Changes pre review. |
118 |
>>> invalid_bug_question.linkBug(invalid_bug) |
119 |
<QuestionBug at ...> |
|
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
120 |
|
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
121 |
# Commit the current transaction because the script will run in |
122 |
# another transaction and thus it won't see the changes done on this |
|
123 |
# test unless we commit. |
|
4664.1.1
by Curtis Hovey
Normalized comments for bug 3732. |
124 |
# XXX flacoste 2006-10-03 bug=3989: Unecessary flush_database_updates |
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
125 |
# required. |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
126 |
>>> from canonical.database.sqlbase import flush_database_updates |
127 |
>>> flush_database_updates() |
|
128 |
>>> import transaction |
|
129 |
>>> transaction.commit() |
|
130 |
||
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
131 |
# Run the script. |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
132 |
>>> import subprocess |
133 |
>>> process = subprocess.Popen( |
|
3691.398.13
by Francis J. Lacoste
Rename answer tracker py and ZCML files. |
134 |
... 'cronscripts/expire-questions.py', shell=True, |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
135 |
... stdin=subprocess.PIPE, stdout=subprocess.PIPE, |
136 |
... stderr=subprocess.PIPE) |
|
137 |
>>> (out, err) = process.communicate() |
|
138 |
>>> print err |
|
7675.624.73
by Tim Penhey
Some lock files, some job runs. |
139 |
INFO Creating lockfile: /var/lock/launchpad-expire-questions.lock |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
140 |
INFO Expiring OPEN and NEEDSINFO questions without activity for the |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
141 |
last 15 days. |
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
142 |
INFO Found 5 questions to expire. |
143 |
INFO Expired 5 questions. |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
144 |
INFO Finished expiration run. |
145 |
<BLANKLINE> |
|
146 |
>>> print out |
|
147 |
<BLANKLINE> |
|
148 |
>>> process.returncode |
|
149 |
0 |
|
150 |
||
3691.69.11
by Francis J. Lacoste
Convert () comments to regular python code comments. |
151 |
# Now we flush the caches, so that the above defined objects gets |
152 |
# their content from the modified DB. |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
153 |
>>> from canonical.database.sqlbase import flush_database_caches |
154 |
>>> flush_database_caches() |
|
155 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
156 |
The status of the OPEN and NEEDSINFO questions that had recent activity |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
157 |
wasn't modified by the script: |
158 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
159 |
>>> print recent_open_question.status.title |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
160 |
Open |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
161 |
>>> print recent_needsinfo_question.status.title |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
162 |
Needs information |
163 |
||
3691.264.1
by Francis J. Lacoste
Do not expire old assigned tickets. |
164 |
Neither the old one which was assigned to Foo Bar: |
165 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
166 |
>>> print old_assigned_open_question.status.title |
3691.264.1
by Francis J. Lacoste
Do not expire old assigned tickets. |
167 |
Open |
168 |
||
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
169 |
The old question with non-Invalid bug link is still Open status: |
170 |
||
171 |
>>> print bug_link_question.status.title |
|
172 |
Open |
|
173 |
||
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
174 |
But the other ones status was changed to 'Expired': |
175 |
||
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
176 |
>>> print old_needs_info_question.status.title |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
177 |
Expired |
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
178 |
>>> print old_open_question.status.title |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
179 |
Expired |
4813.9.1
by Curtis Hovey
Added rule to never expire questions that are linked to valid bugs |
180 |
>>> print invalid_bug_question.status.title |
181 |
Expired |
|
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
182 |
|
183 |
The message explaining the reason for the expiration was posted by the |
|
4813.9.5
by Curtis Hovey
Reverted expiredQuestions query to use BugTask.status IS NULL because |
184 |
Launchpad Janitor celebrity: |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
185 |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
186 |
>>> expiration_message = old_needs_info_question.messages[-1] |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
187 |
>>> print expiration_message.action.name |
188 |
EXPIRE |
|
3691.197.55
by Francis J. Lacoste
Rename newstatus to new_status as per new naming convention. Renamed foreign key to ticket__answer__fk as requested by stub. |
189 |
>>> print expiration_message.new_status.title |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
190 |
Expired |
191 |
>>> print expiration_message.owner.name |
|
4621.5.26
by Curtis Hovey
Renamed launchpad-janitor to janitor per review. |
192 |
janitor |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
193 |
|
194 |
>>> print expiration_message.text_contents |
|
3691.398.21
by Francis J. Lacoste
Rename all attributes and variables. |
195 |
This question was expired because it remained in the |
3691.197.96
by Francis J. Lacoste
- Comment after every expiration to workaround bug #29744. |
196 |
'Needs information' state without activity for the last 15 days. |
3691.197.49
by Francis J. Lacoste
Add expire-tickets.py script |
197 |
|
198 |