blob: c428cdcad7ae15e84b7131b0feb4748216184003 (
plain)
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
#!/bin/bash
# -*- coding: utf-8 -*-
###########################################################################
# #
# envbot - an IRC bot in bash #
# Copyright (C) 2007-2008 Arvid Norlander #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###########################################################################
#---------------------------------------------------------------------
## Check bugs using the program bugz and return output from it.
## @pybugz bugz is a tool to search Gentoo bug reports (or other bugzillas)<br />
## @pybugz From eix pybugz:<br />
## @pybugz Description: Command line interface to (Gentoo) Bugzilla
## @Dependencies This module therefore depends on:<br />
## @Dependencies pybugz
## @Config_variables To set bugzilla to use something like this in config:<br />
## @Config_variables <pre>config_module_bugzilla_tracker_name[0]='gentoo'
## @Config_variables config_module_bugzilla_tracker_url[0]='https://bugs.gentoo.org/'</pre>
## @Config_variables Must end in trailing slash! Also the first entry will be the default.<br />
## @Config_variables You also need to specify flood limiting<br />
## @Config_variables (how often in seconds)<br />
## @Config_variables <tt>config_module_bugzilla_rate='10'</tt>
#---------------------------------------------------------------------
module_bugzilla_INIT() {
modinit_API='2'
modinit_HOOKS='after_load'
commands_register "$1" 'bugs_search' 'bugs search' || return 1
commands_register "$1" 'bug' || return 1
helpentry_module_bugzilla_description="Search in bugzilla bug trackers."
helpentry_bugzilla_bugs_search_syntax='[-t <tracker>] [-(all|closed)] <pattern>'
helpentry_bugzilla_bugs_search_description='Search for <pattern> in <tracker> (or the default tracker).'
helpentry_bugzilla_bug_syntax='[-t <tracker>] <id>'
helpentry_bugzilla_bug_description='Look up the bug with <id> in <tracker> (or the default tracker).'
}
module_bugzilla_UNLOAD() {
unset module_bugzilla_last_query module_bugzilla_default_bugtracker
unset module_bugzilla_parse_config module_bugzilla_find_tracker
hash_reset 'bugzilla_tracker'
}
module_bugzilla_REHASH() {
module_bugzilla_parse_config
}
#---------------------------------------------------------------------
## Initialize the hash of name -> url mapping
## @Type Private
#---------------------------------------------------------------------
module_bugzilla_parse_config() {
hash_reset 'bugzilla_tracker'
local index
for index in "${!config_module_bugzilla_tracker_name[@]}"; do
hash_set 'bugzilla_tracker' \
"${config_module_bugzilla_tracker_name[index]}" \
"${config_module_bugzilla_tracker_url[index]}"
done
module_bugzilla_default_bugtracker="${config_module_bugzilla_tracker_url[0]}"
}
#---------------------------------------------------------------------
## Find what tracker to use from the parameters.
## @param Name of parameter variable.
## @param Name of bugtracker variable.
## @Type Private
#---------------------------------------------------------------------
module_bugzilla_find_tracker() {
if [[ "${!1}" =~ ^(-(tracker|t)\ +([A-Za-z0-9]+)\ +)(.+) ]]; then
local tindex="${BASH_REMATCH[3]}"
# Store result back in variable.
printf -v "$1" '%s' "${BASH_REMATCH[4]}"
local turl
hash_get 'bugzilla_tracker' "$tindex" 'turl'
if [[ $turl ]]; then
printf -v "$2" '%s' "$turl"
else
feedback_generic_error "$sendernick" "bugs search" "No such bug tracker found."
fi
else
printf -v "$2" '%s' "${module_bugzilla_default_bugtracker}"
fi
}
# Called after module has loaded.
# Check for bugz
module_bugzilla_after_load() {
if ! hash bugz > /dev/null 2>&1; then
log_error "Couldn't find bugz command line tool. The bugzilla module depend on that tool (emerge pybugz to get it on Gentoo)."
return 1
fi
if [[ -z ${config_module_bugzilla_tracker_url[0]} ]]; then
log_error "Please set at least config_module_bugzilla_url[0] in config."
return 1
fi
if [[ -z ${config_module_bugzilla_tracker_name[0]} ]]; then
log_error "Please set at least config_module_bugzilla_name[0] in config."
return 1
fi
if [[ -z $config_module_bugzilla_rate ]]; then
log_error "Please set config_module_bugzilla_rate in config."
return 1
fi
module_bugzilla_parse_config
unset module_bugzilla_last_query
module_bugzilla_last_query='0'
}
module_bugzilla_handler_bugs_search() {
# Accept this anywhere, unless someone can give a good reason not to.
local sender="$1"
local channel="$2"
local sendernick=
parse_hostmask_nick "$sender" 'sendernick'
# If it isn't in a channel send message back to person who send it,
# otherwise send in channel
if ! [[ $2 =~ ^# ]]; then
channel="$sendernick"
fi
local parameters="$3"
local bugtracker
module_bugzilla_find_tracker 'parameters' 'bugtracker'
if [[ "$parameters" =~ ^(-(all|closed)\ +)?(.+) ]]; then
local mode="${BASH_REMATCH[2]}"
local pattern="${BASH_REMATCH[@]: -1}"
# Simple flood limiting
if time_check_interval "$module_bugzilla_last_query" "$config_module_bugzilla_rate"; then
time_get_current 'module_bugzilla_last_query'
local bugs_parameters=""
if [[ $mode = "all" ]]; then
bugs_parameters="-s all"
elif [[ $mode = "closed" ]]; then
bugs_parameters="-s CLOSED -s RESOLVED"
fi
log_info_file bugzilla.log "$sender made the bot run pybugz search on \"$pattern\""
# We unset TERM because otherwise bugz output some control codes
local result="$(unset TERM; ulimit -t 4; bugz -fqb "$bugtracker" search $bugs_parameters "$pattern")"
local lines="$(wc -l <<< "$result")"
local header footer
# Some odd formatting chars are always returned (in some versions of pybugz), so we can't check for empty string.
if [[ ${#result} -le 10 ]]; then
header="No bugs matching \"$pattern\" found"
elif [[ $lines -gt 1 ]]; then
header="First bug matching \"$pattern\": "
footer=" ($lines more bugs found)"
else
header="One bug matching \"$pattern\" found: "
fi
if [[ $(head -n 1 <<< "$result") =~ \ ([0-9]+)\ +([^ ]+)\ +(.*)$ ]]; then
local pretty_result="${format_bold}${bugtracker}${BASH_REMATCH[1]}${format_bold} ${format_bold}Description${format_bold}: ${BASH_REMATCH[3]} ${format_bold}Assigned To${format_bold}: ${BASH_REMATCH[2]}"
fi
send_msg "$channel" "${header}${pretty_result}${footer}"
else
log_error_file bugzilla.log "FLOOD DETECTED in bugzilla module"
fi
else
feedback_bad_syntax "$sendernick" "bugs search" "[-t tracker] [-(all|closed)] <pattern>"
fi
}
module_bugzilla_handler_bug() {
# Accept this anywhere, unless someone can give a good reason not to.
local sender="$1"
local channel="$2"
local sendernick=
parse_hostmask_nick "$sender" 'sendernick'
# If it isn't in a channel send message back to person who send it,
# otherwise send in channel
if ! [[ $2 =~ ^# ]]; then
channel="$sendernick"
fi
local parameters="$3"
local bugtracker
module_bugzilla_find_tracker 'parameters' 'bugtracker'
# Extract bug ID
if [[ "$parameters" =~ ^([0-9]+) ]]; then
local id="${BASH_REMATCH[1]}"
# Simple flood limiting
if time_check_interval "$module_bugzilla_last_query" "$config_module_bugzilla_rate"; then
time_get_current 'module_bugzilla_last_query'
log_info_file bugzilla.log "$sender made the bot check with pybugz for bug \"$id\""
# We unset TERM because otherwise bugz output some control codes
local result="$(unset TERM; ulimit -t 4; bugz -fqb "$bugtracker" get -n "$id" | grep -E 'Title|Status|Resolution')"
local resultread pretty_result
local title status resolution
# Read the data out of the multiline result.
while read -r resultread; do
if [[ $resultread =~ ^Title[\ :]+([^ ].*) ]]; then
title="${BASH_REMATCH[1]}"
elif [[ $resultread =~ ^Status[\ :]+([^ ].*) ]]; then
status="${BASH_REMATCH[1]}"
elif [[ $resultread =~ ^Resolution[\ :]+([^ ].*) ]]; then
resolution="${BASH_REMATCH[1]}"
fi
done <<< "$result"
# Yes this is a bit of a mess
if [[ "$title" ]]; then
# This info is always here
pretty_result="${format_bold}Bug $id${format_bold} (${format_bold}Status${format_bold} $status"
# The resolution may not exist, add it if it does.
if [[ $resolution ]]; then
pretty_result+=", ${format_bold}Resolution${format_bold} $resolution"
fi
# And add the title in. Does not depend on if resolution exist.
pretty_result+="): $title (${bugtracker}${id})"
else
pretty_result="Bug $id not found"
fi
send_msg "$channel" "${pretty_result}"
else
log_error_file bugzilla.log "FLOOD DETECTED in bugzilla module"
fi
else
feedback_bad_syntax "$sendernick" "bug" "[-t tracker] <id>"
fi
}
|