geez, university doesn't care about us either
[jelmer/bts-link.git] / btsfwd
1 #! /usr/bin/env python
2 # vim:set encoding=utf-8:
3 ###############################################################################
4 # Copyright:
5 #   © 2006 Pierre Habouzit <madcoder@debian.org>
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 # 3. The names of its contributors may not be used to endorse or promote
16 #    products derived from this software without specific prior written
17 #    permission.
18
19 # THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
20 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
22 # EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 ###############################################################################
30
31 """
32 Usage: %s [-n] nnn [remoteUri] [, nnn2 [remoteUri2]]
33
34     -n  --dry-run
35                dry run
36     -s  --short
37                short run, don't deal with 'Done' bugs.
38
39     nnn        the debian bug number
40     remoteUri  the url of the remote bug
41
42 """
43
44 import sys, os, getopt, threading, time, signal
45 import bts, utils
46 from remote import RemoteBts
47 from utils import BTSLConfig as Cnf
48
49 def warn(s):
50     print >> sys.stderr, s
51
52 def die(s):
53     print >> sys.stderr, s
54     os.kill(os.getpid(), signal.SIGKILL)
55     sys.exit(1)
56
57 def usage(exitCode = 1):
58     die(__doc__.lstrip() % (sys.argv[0].split('/')[-1]))
59
60 class Task(threading.Thread):
61     def __init__(self, rbts, res):
62         self.rbts = rbts
63         self.res  = res
64         threading.Thread.__init__(self)
65
66     def run(self):
67         self.res += self.rbts.processQueue()
68         return
69
70 if __name__ == "__main__":
71     debug = False
72     short = False
73
74     opts, args = getopt.getopt(sys.argv[1:], 'ns', ['dry-run', 'short'])
75     if len(args) < 1: usage(1)
76     for o, v in opts:
77         if o in ('-n', '--dry-run'):
78             debug = True
79         if o in ('-s', '--short'):
80             short = True
81
82     RemoteBts.setup(Cnf.resources())
83     btsi = bts.BtsInterface(Cnf)
84
85     queues  = {}
86
87     cmds = [x.split('\007') for x in '\007'.join(args).split('\007,\007')]
88     for c in cmds:
89         if len(c) not in (1, 2): usage(1)
90         if len(c) is 1:
91             btsbug = btsi.getReport(c[0])
92
93             if btsbug is None:
94                 warn("#%s does not exist" % (c[0]))
95                 continue
96             if not btsbug.forward:
97                 if not btsbug.fwdTo:
98                     warn("#%s has no forwards" % (c[0]))
99                 if len(btsbug.fwdTo) is not 1:
100                     warn("#%s has more than one forward" % (c[0]))
101                 continue
102
103             fwd = btsbug.forward
104         else:
105             btsbug = btsi.getReport(c[0])
106             if btsbug is None:
107                 warn("#%s does not exist" % (c[0]))
108                 continue
109
110             fwd = c[1]
111
112         if short and btsbug.done:
113             continue
114
115         rbts = RemoteBts.find(fwd)
116         if not rbts:
117             warn("#%s: not understood: %s" % (btsbug.id, fwd))
118             continue
119         rbts.enqueue(btsbug, fwd)
120
121     try:
122         res = []
123         for _, v in RemoteBts.resources.iteritems():
124             Task(v['bts'], res).start()
125
126         while threading.activeCount() > 1:
127             time.sleep(1)
128
129         per_src = {}
130         for btsbug, cmds in res:
131             if btsbug.srcpackage in per_src:
132                 per_src[btsbug.srcpackage] += cmds
133             else:
134                 per_src[btsbug.srcpackage] = cmds
135
136         mailer = bts.BtsMailer(debug)
137
138         for spkg, cmds in per_src.iteritems():
139             precmds = []
140             precmds.append("#")
141             precmds.append("# bts-link upstream status pull for source package %s" % (spkg))
142             precmds.append("# see http://lists.debian.org/debian-devel-announce/2006/05/msg00001.html")
143             precmds.append("#")
144             precmds.append("")
145             precmds.append("user %s" % (Cnf.get('general', 'user')))
146             precmds.append("")
147
148             cmds.append('thanks')
149
150             msg = mailer.BtsMail('\n'.join(precmds + cmds))
151             msg['From']    = Cnf.sender()
152             msg['To']      = 'control@bugs.debian.org'
153             msg['Cc']      = "%s, %s@packages.debian.org" % (Cnf.sender(), spkg)
154             msg['Subject'] = '[bts-link] source package %s' % (spkg)
155
156             mailer.sendmail(msg['From'], [msg['To'], msg['From'], "%s@packages.debian.org" % (spkg)], msg)
157
158         mailer.unlink()
159     except KeyboardInterrupt:
160         die("*** ^C...")
161
162 # vim:set foldmethod=indent foldnestmax=1: