]> kaliko git repositories - sid.git/blob - sid/bts.py
doc: Improve and update
[sid.git] / sid / bts.py
1 # -*- coding: utf-8 -*-
2 # SPDX-FileCopyrightText: 2015, 2021 kaliko <kaliko@azylum.org>
3 # SPDX-FileCopyrightText: 2010, 2011 Anaël Verrier <elghinn@free.fr>
4 # SPDX-License-Identifier: GPL-3.0-or-later
5 """Intercepts bugs numbers in MUC messages and send info about it
6
7 >>> from sid.bts import Bugs
8 """
9
10 from re import compile as re_compile
11
12 import debianbts
13
14 from .plugin import Plugin, botcmd
15
16
17 class Bugs(Plugin):
18     """Gets bugs info from the BTS
19
20     .. note::
21       This plugin depends on external module: **python-debianbts**
22     """
23     #: Bug id regexp, intercepts bug id in strings : "#629234", "bugs.debian.org/629234" and "bugreport.cgi?bug=629234"
24     re_bugs = re_compile(r'(?:(?<=#)|(?<=bugreport\.cgi\?bug=)|(?<=bugs\.debian\.org/))(\d{6,7})')
25     #: Package name regexp
26     re_pkg = re_compile(r'(?P<package>[0-9a-z.+-]+)$')
27
28     def __init__(self, bot):
29         Plugin.__init__(self, bot)
30         bot.add_event_handler("muc::%s::message" %
31                               self.bot.room, self.muc_message)
32
33     def muc_message(self, msg):
34         """Handler method dealing with MUC incoming messages.
35
36         Intercepts bugs number in MUC messages (as #629234), replies a bug
37         summary."""
38         # Does not reply to myself
39         if msg['mucnick'] == self.bot.nick:
40             return
41         bugs = list()
42         for bug_id in set(Bugs.re_bugs.findall(msg['body'].strip())):
43             self.log.debug('got bug id: %s', bug_id)
44             query = debianbts.get_status(bug_id)
45             if len(query) == 1:
46                 bug = query[0]
47                 url = debianbts.BTS_URL + bug_id
48                 bugs.append({'id': bug_id,
49                              'package': bug.package,
50                              'summary': bug.subject,
51                              'url': url})
52             else:
53                 self.log.warning('Wrong bug number "%s"?', bug_id)
54                 bugs.append({'id': bug_id})
55         for bug in bugs:
56             if len(bug) == 1:
57                 message = 'Invalid bug id: {id}'.format(**bug)
58                 self.reply(msg, message)
59             else:
60                 message = {'mhtml': '<a href="%(url)s">#%(id)s</a>: %(package)s “ %(summary)s ”' % bug,
61                            'mbody': '#%(id)s: %(package)s “ %(summary)s ” %(url)s' % bug}
62                 self.reply(msg, message)
63
64     @botcmd
65     def bugs(self, rcv, args):
66         """Gets bugs info from the BTS
67
68         ``!bugs pkg-name`` : Returns latest bug reports if any
69         """
70         if not args:
71             return
72         if len(args) > 1:
73             self.log.info('more than one packages provided')
74         pkg = Bugs.re_pkg.match(args[0])
75         if not pkg:
76             msg = 'Wrong package name format re: "{}"'.format(Bugs.re_pkg.pattern)
77             self.reply(rcv, msg)
78             return
79         reports_ids = debianbts.get_bugs(status='open', **pkg.groupdict())
80         if not reports_ids:
81             self.reply(rcv, 'No open bugs for "{}"'.format(pkg.string))
82             return
83         reports = debianbts.get_status(reports_ids)
84         reports = sorted(reports, key=lambda r: r.date)
85         msg = ['Latest reports for {1} (total {0})'.format(len(reports), pkg.string)]
86         # Reverse and take last reports
87         for rep in reports[::-1][:4]:
88             msg.append('{r.bug_num}: {r.date:%Y-%m-%d} {r.subject}'.format(r=rep))
89         message = {'mbody': '\n'.join(msg)}
90         self.reply(rcv, message)