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 logging 
 31  import re 
 32  import sys 
 33   
 34  log = logging.getLogger() 
 35   
 36  import apt_pkg 
 37  import debianbts as bts 
 38   
 39  from daklib import utils 
 40   
 41   
42 -def usage():
43 print( 44 """ 45 SYNOPSIS 46 dak bts-categorize [options] 47 48 OPTIONS 49 -s 50 --simulate 51 Don't send email, instead output the lines that would be sent to 52 control@b.d.o. 53 54 -v 55 --verbose 56 Print more informational log messages 57 58 -q 59 --quiet 60 Suppress informational messages 61 62 -h 63 --help 64 Print this documentation. 65 """ 66 )
67 68 69 arguments = [ 70 ("s", "simulate", "BtsCategorize::Options::Simulate"), 71 ("v", "verbose", "BtsCategorize::Options::Verbose"), 72 ("q", "quiet", "BtsCategorize::Options::Quiet"), 73 ("h", "help", "BtsCategorize::Options::Help"), 74 ("o", "option", "", "ArbItem"), 75 ] 76 77
78 -class BugClassifier:
79 """ 80 classify bugs using usertags based on the bug subject lines 81 82 >>> BugClassifier.rm_re.match( "RM: asdf" ) != None 83 True 84 >>> BugClassifier.rm_re.match( "[dak] Packages.diff/Index broken" ) != None 85 False 86 >>> BugClassifier.dak_re.match( "[dak] Packages.diff/Index broken" ) != None 87 True 88 """ 89 90 rm_re = re.compile("^RM") 91 dak_re = re.compile(r"^\[dak\]") 92 arch_re = re.compile(r"^\[Architectures\]") 93 override_re = re.compile("^override") 94 95 classifiers = { 96 rm_re: "remove", 97 dak_re: "dak", 98 arch_re: "archs", 99 override_re: "override", 100 } 101
102 - def unclassified_bugs(self):
103 """ 104 Returns a list of open bugs which have not yet been classified 105 by one of our usertags. 106 """ 107 108 tagged_bugs = bts.get_usertag("ftp.debian.org@packages.debian.org") 109 tagged_bugs_ftp = [] 110 for tags in tagged_bugs.keys(): 111 tagged_bugs_ftp += tagged_bugs[tags] 112 113 return [ 114 bug 115 for bug in bts.get_status(bts.get_bugs(package="ftp.debian.org")) 116 if bug.pending == "pending" and bug.bug_num not in tagged_bugs_ftp 117 ]
118
119 - def classify_bug(self, bug):
120 """ 121 if any of our classifiers match, return a newline terminated 122 command to set an appropriate usertag, otherwise return an 123 empty string 124 """ 125 retval = "" 126 127 for classifier in self.classifiers.keys(): 128 if classifier.match(bug.subject): 129 retval = "usertag %s %s\n" % (bug.bug_num, self.classifiers[classifier]) 130 break 131 132 if retval: 133 log.info(retval) 134 else: 135 log.debug("Unmatched: [%s] %s" % (bug.bug_num, bug.subject)) 136 137 return retval
138
139 - def email_text(self):
140 controls = "" 141 142 bc = BugClassifier() 143 try: 144 for bug in bc.unclassified_bugs(): 145 controls += bc.classify_bug(bug) 146 147 return controls 148 except: 149 log.error( 150 "couldn't retrieve bugs from soap interface: %s" % sys.exc_info()[0] 151 ) 152 return None
153 154
155 -def send_email(commands, simulate=False):
156 global Cnf 157 158 Subst = { 159 "__COMMANDS__": commands, 160 "__DAK_ADDRESS__": Cnf["Dinstall::MyAdminAddress"], 161 } 162 163 bts_mail_message = utils.TemplateSubst( 164 Subst, Cnf["Dir::Templates"] + "/bts-categorize" 165 ) 166 167 if simulate: 168 print(bts_mail_message) 169 else: 170 utils.send_mail(bts_mail_message)
171 172
173 -def main():
174 """ 175 for now, we just dump a list of commands that could be sent for 176 control@b.d.o 177 """ 178 global Cnf 179 Cnf = utils.get_conf() 180 181 for arg in arguments: 182 opt = "BtsCategorize::Options::%s" % arg[1] 183 if opt not in Cnf: 184 Cnf[opt] = "" 185 186 apt_pkg.parse_commandline(Cnf, arguments, sys.argv) 187 Options = Cnf.subtree("BtsCategorize::Options") 188 189 if Options["Help"]: 190 usage() 191 sys.exit(0) 192 193 if Options["Quiet"]: 194 level = logging.ERROR 195 196 elif Options["Verbose"]: 197 level = logging.DEBUG 198 199 else: 200 level = logging.INFO 201 202 logging.basicConfig( 203 level=level, format="%(asctime)s %(levelname)s %(message)s", stream=sys.stderr 204 ) 205 206 body = BugClassifier().email_text() 207 208 if body: 209 send_email(body, Options["Simulate"]) 210 211 else: 212 log.info("nothing to do")
213 214 215 if __name__ == "__main__": 216 # import doctest 217 # doctest.testmod() 218 main() 219