~deryck/+junk/lpjunk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/python -S
#
# Copyright 2010 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

"""
This script should be run from the top-level of the LP tree.

It notifies bug supervisors or owners (if no bug supervisor is
defined) for projects with bug expiry enabled that we are
re-enabling auto expiration.  It then disables the feature on these
projects.  The notification is also meant to notify users they will
have to re-enable this option.  No surprises FTW!

Run with no options, this script is largely harmless.  It will
merely do the queries.
"""

import _pythonpath

from storm.expr import Not

from lp.services.scripts.base import LaunchpadScript
from lp.services.mail.sendmail import simple_sendmail
from canonical.launchpad.interfaces.lpstorm import IMasterStore
from canonical.launchpad.interfaces.emailaddress import EmailAddressStatus

REGISTRY_ADMINS = 6213

MAIL_MSG = """
Bug expiry in Launchpad is changing
------------------------------------

The way Launchpad handles inactive bugs is changing. This affects your project
%(name)s at https://launchpad.net/%(project)s


What's going to change
-----------------------

Right now, the bug expiry option is enabled for %(name)s but is inactive
across all of Launchpad.

We weren't happy with the way bug expiry worked, so we turned it off. However,
now we're ready to switch it back on.

In two weeks, we will re-enable automatic bug expiry in Launchpad. However,
at the same time we will deselect the bug expiry option on each project,
including %(name)s.


What this means for your project
--------------------------------

If you want Launchpad to automatically expire bugs that appear to be inactive,
you need to select the 'Expire "Incomplete" bug reports when they become
inactive' option on this page:

https://bugs.launchpad.net/%(project)s/+configure-bugtracker

For more detail on how Launchpad determines if a bug is inactive, visit our
help page:

https://help.launchpad.net/Bugs/Expiry

If you enable automatic bug expiry, Launchpad will start to automatically
apply the new 'Expired' status to inactive bugs from around the 13th of
September 2010.

If you do not want Launchpad to automatically expire inactive bugs, you should
do nothing.

Why we're doing this
---------------------

Most projects have some bugs that languish with no activity. They clutter bug
listings and, let's face it, are unlikely to ever come back to life.

Automatic bug expiry lets you hand Launchpad the burden of dealing with these.

We're disabling the feature on your project, and others, so that Launchpad
continues to work for you in the way it does now -- i.e. without automatic bug
expiry. If you do want to re-enable bug expiry, it'll take just a few seconds.


Deryck Hodge
Launchpad Bugs Team Lead
"""


class ExpiryNotifyScript(LaunchpadScript):

    description = 'Notify users about bug expiry and disable the feature.'

    def add_my_options(self):
        self.parser.add_option('-D', '--debug', action='store_true',
                               dest='debug', default=False,
                               help='Drop into PDB and figure this out.')
        self.parser.add_option('-u', '--update', action='store_true',
                               dest='update', default=False,
                               help='Update DB to disable bug expiry.')
        self.parser.add_option('-r', '--report', action='store_true',
                               dest='report', default=False,
                               help='Report stats on the data and exit.')
        self.parser.add_option('-s', '--sendmail', action='store_true',
                               dest='sendmail', default=False,
                               help='Actually send the mail out.')

    def main(self):
        # Anyone else hate circular imports?
        from lp.registry.model.product import Product
        from lp.registry.model.person import Person
        from canonical.launchpad.database import EmailAddress

        # Get the supervisors, owners, and projects.
        store = IMasterStore(Product)
        supervisors = list(store.find(
            (Product, Person, EmailAddress),
            Product.enable_bug_expiration == True,
            Not(Product.bug_supervisor == None),
            Product.bug_supervisor == Person.id,
            Product.bug_supervisor != REGISTRY_ADMINS,
            EmailAddress.person == Person.id,
            EmailAddress.status == EmailAddressStatus.PREFERRED,
        ))
        owners = list(store.find(
            (Product, Person, EmailAddress),
            Product.enable_bug_expiration == True,
            Product.bug_supervisor == None,
            Product._owner == Person.id,
            Product._owner != REGISTRY_ADMINS,
            EmailAddress.person == Person.id,
            EmailAddress.status == EmailAddressStatus.PREFERRED,
        ))
        contacts = supervisors + owners
        projects = store.find(
            Product,
            Product.enable_bug_expiration == True,
            Product._owner != REGISTRY_ADMINS,
        )

        # Optionally, show a bit of info about this data.
        if self.options.report:
            print '%d projects with bug expiry enabled' % projects.count()
            print '%d projects with no bug supervisor' % len(owners)
            print '%d projects with a contactable bug supervisor' % (
                len(supervisors))
            if self.options.debug:
                for project, person, email in contacts:
                    self.logger.debug(
                        'Data: (%s, %s, %s)' % (
                            project.name, person.displayname, email.email))

        # Handle the emails.
        for project, person, email in contacts:
            msg = MAIL_MSG % {
                'project': project.name,
                'name': project.displayname}
            if self.options.report:
                print msg
            if self.options.sendmail:
                simple_sendmail(
                    'deryck.hodge@canonical.com', email.email,
                    'Launchpad Bugs Re-enabling Auto Expiring Bugs', msg)

        # Actually update the settings here.
        if self.options.update:
            projects.set(enable_bug_expiration=False)
            self.txn.commit()

        self.logger.debug('ExpiryNotifyScript is done.')

if __name__ == '__main__':
    script = ExpiryNotifyScript()
    script.run()