Package dak :: Module bts_categorize
[hide private]
[frames] | no frames]

Source Code for Module dak.bts_categorize

  1  #! /usr/bin/env python3 
  2   
  3  """ 
  4  bts -- manage bugs filed against ftp.debian.org 
  5   
  6  @contact: Debian FTP Master <ftpmaster@debian.org> 
  7  @copyright: 2009 Mike O'Connor <stew@vireo.org> 
  8  @copyright: 2010 Alexander Reichle-Schmehl <tolimar@debian.org> 
  9  @license: GNU General Public License version 2 or later 
 10  """ 
 11   
 12  #  This program is free software; you can redistribute it and/or modify it 
 13  #  under the terms of the GNU General Public License as published by the 
 14  #  Free Software Foundation; either version 2, or (at your option) any 
 15  #  later version. 
 16  # 
 17  #  This program is distributed in the hope that it will be useful, 
 18  #  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 19  #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 20  #  GNU General Public License for more details. 
 21  # 
 22  #  You should have received a copy of the GNU General Public License 
 23  #  along with this program; if not, write to the Free Software 
 24  #  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
 25  #  USA. 
 26   
 27  ################################################################################ 
 28  ################################################################################ 
 29   
 30  import sys 
 31  import re 
 32  import logging 
 33  log = logging.getLogger() 
 34   
 35  import apt_pkg 
 36  from daklib import utils 
 37  import debianbts as bts 
 38   
 39   
40 -def usage():
41 print(""" 42 SYNOPSIS 43 dak bts-categorize [options] 44 45 OPTIONS 46 -s 47 --simulate 48 Don't send email, instead output the lines that would be sent to 49 control@b.d.o. 50 51 -v 52 --verbose 53 Print more informational log messages 54 55 -q 56 --quiet 57 Suppress informational messages 58 59 -h 60 --help 61 Print this documentation. 62 """)
63 64 65 arguments = [('s', 'simulate', 'BtsCategorize::Options::Simulate'), 66 ('v', 'verbose', 'BtsCategorize::Options::Verbose'), 67 ('q', 'quiet', 'BtsCategorize::Options::Quiet'), 68 ('h', 'help', 'BtsCategorize::Options::Help'), 69 ('o', 'option', '', 'ArbItem')] 70 71
72 -class BugClassifier:
73 """ 74 classify bugs using usertags based on the bug subject lines 75 76 >>> BugClassifier.rm_re.match( "RM: asdf" ) != None 77 True 78 >>> BugClassifier.rm_re.match( "[dak] Packages.diff/Index broken" ) != None 79 False 80 >>> BugClassifier.dak_re.match( "[dak] Packages.diff/Index broken" ) != None 81 True 82 """ 83 rm_re = re.compile("^RM") 84 dak_re = re.compile(r"^\[dak\]") 85 arch_re = re.compile(r"^\[Architectures\]") 86 override_re = re.compile("^override") 87 88 classifiers = {rm_re: 'remove', 89 dak_re: 'dak', 90 arch_re: 'archs', 91 override_re: 'override'} 92
93 - def unclassified_bugs(self):
94 """ 95 Returns a list of open bugs which have not yet been classified 96 by one of our usertags. 97 """ 98 99 tagged_bugs = bts.get_usertag('ftp.debian.org@packages.debian.org') 100 tagged_bugs_ftp = [] 101 for tags in tagged_bugs.keys(): 102 tagged_bugs_ftp += tagged_bugs[tags] 103 104 return [bug for bug in bts.get_status(bts.get_bugs("package", "ftp.debian.org")) 105 if bug.pending == 'pending' and bug.bug_num not in tagged_bugs_ftp]
106
107 - def classify_bug(self, bug):
108 """ 109 if any of our classifiers match, return a newline terminated 110 command to set an appropriate usertag, otherwise return an 111 empty string 112 """ 113 retval = "" 114 115 for classifier in self.classifiers.keys(): 116 if classifier.match(bug.subject): 117 retval = "usertag %s %s\n" % (bug.bug_num, 118 self.classifiers[classifier]) 119 break 120 121 if retval: 122 log.info(retval) 123 else: 124 log.debug("Unmatched: [%s] %s" % (bug.bug_num, bug.subject)) 125 126 return retval
127
128 - def email_text(self):
129 controls = "" 130 131 bc = BugClassifier() 132 try: 133 for bug in bc.unclassified_bugs(): 134 controls += bc.classify_bug(bug) 135 136 return controls 137 except: 138 log.error("couldn't retrieve bugs from soap interface: %s" % sys.exc_info()[0]) 139 return None
140 141
142 -def send_email(commands, simulate=False):
143 global Cnf 144 145 Subst = {'__COMMANDS__': commands, 146 "__DAK_ADDRESS__": Cnf["Dinstall::MyAdminAddress"]} 147 148 bts_mail_message = utils.TemplateSubst( 149 Subst, Cnf["Dir::Templates"] + "/bts-categorize") 150 151 if simulate: 152 print(bts_mail_message) 153 else: 154 utils.send_mail(bts_mail_message)
155 156
157 -def main():
158 """ 159 for now, we just dump a list of commands that could be sent for 160 control@b.d.o 161 """ 162 global Cnf 163 Cnf = utils.get_conf() 164 165 for arg in arguments: 166 opt = "BtsCategorize::Options::%s" % arg[1] 167 if opt not in Cnf: 168 Cnf[opt] = "" 169 170 packages = apt_pkg.parse_commandline(Cnf, arguments, sys.argv) 171 Options = Cnf.subtree('BtsCategorize::Options') 172 173 if Options["Help"]: 174 usage() 175 sys.exit(0) 176 177 if Options["Quiet"]: 178 level = logging.ERROR 179 180 elif Options["Verbose"]: 181 level = logging.DEBUG 182 183 else: 184 level = logging.INFO 185 186 logging.basicConfig(level=level, 187 format='%(asctime)s %(levelname)s %(message)s', 188 stream=sys.stderr) 189 190 body = BugClassifier().email_text() 191 192 if body: 193 send_email(body, Options["Simulate"]) 194 195 else: 196 log.info("nothing to do")
197 198 199 if __name__ == '__main__': 200 # import doctest 201 # doctest.testmod() 202 main() 203