Snippets

Atri Bhattacharya Bugzilla query

Created by Atri Bhattacharya last modified
# vim: set et ts=4 sw=4 tw=80:
# Copyright (c) 2016, Atri Bhattacharya <badshah400@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

import sys
import csv
import urllib2
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

bugz_main = 'https://bugzilla.opensuse.org'
bugz_fb   = 'https://bugzilla.suse.com'
bugz_nov  = 'https://bugzilla.novell.com'

# TEST IF bugz_main IS ACCESSIBLE, IF SO FALL BACK TO bugz_fb
try:
    urllib2.urlopen(bugz_main)
except urllib2.URLError, e:
    bugz_main = bugz_fb
    pass

try:
    urllib2.urlopen(bugz_main)
except urllib2.URLError, e:
    bugz_main = bugz_nov
    pass

try:
    urllib2.urlopen(bugz_main)
except:
    print('Cannot access bugzilla at the moment, sorry!')
    sys.exit(-14)
    

def printbuginfo(bugid):
    url    = bugz_main + '/{:d}'.format(bugid)
    xmlurl = bugz_main + '/show_bug.cgi?ctype=xml&id={:d}'.format(bugid)
    xmlres = urllib2.urlopen(xmlurl)
    tree   = ET.parse(xmlres)
    root   = tree.getroot()
    node   = root.find('bug')
    crtime = node.find('creation_ts').text.split(' ')
    crstr  = crtime[0] + ' ' + crtime[1]
    prod   = node.find('product').text
    comp   = node.find('component').text
    sever  = node.find('bug_severity').text
    prior  = node.find('priority').text
    stat   = node.find('bug_status').text
    summ   = node.find('short_desc').text
    repid  = node.find('reporter').get('name')
    assid  = node.find('assigned_to').get('name')
    if assid == 'E-mail List' or assid == 'E-Mail List':
        assid += (' (' + node.find('assigned_to').text + ')')

    # Find the last comment_count, this corresponds to the total number of comments
    ldesc  = node.findall('long_desc')
    comms  = ldesc[-1].find('comment_count').text
    
    if int(comms) > 1:
        mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                 'Created at {:s} by {:s}, '
                 'Assigned to {:s}, '
                 '{:s} comments'.format(url, stat, sever, prior, summ, crstr,
                                        repid, assid, comms))
    elif int(comms) == 1:
        mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                 'Created at {:s} by {:s}, '
                 'Assigned to {:s}, '
                 '1 comment'.format(url, stat, sever, prior, summ, crstr,
                                    repid, assid))
    else:
        mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                 'Created at {:s} by {:s}, '
                 'Assigned to {:s}'.format(url, stat, sever, prior, summ, crstr,
                                           repid, assid))
    
    print(mess)

# For the IRC bugbot plugin delete the following line
term = sys.argv[1]
lim  = 3
oP = 'openSUSE'

# CONSTRUCT THE URL PART/PART
boourl       = bugz_main + '/buglist.cgi?'
limurl       = 'limit={:d}'.format(lim)

semode       = 'anywords'

# FOR NOW WE ONLY MATCH AGAINST THE COMPONENT, SUMMARY AND CLASSIFICATION
sefields     = ['component', 'short_desc', 'classification']

fieldurl     = ''
valurl       = ''
fcnt         = 0
for field in sefields:
    fcnt     += 1
    fieldurl += 'f{:d}={:s}&'.format(fcnt, field)
    valurl   += 'v{:d}={:s}&'.format(fcnt, term)

parturl      = (fieldurl + 
                'j_top=OR&o1={0:s}&o2={0:s}&o3={0:s}&'.format(semode) +
                'resolution=---&' +
                valurl)

url = (boourl + parturl
       + 'ctype=csv&order=bug_id%20DESC&' + limurl)
       
data = urllib2.urlopen(url)
cr   = csv.reader(data)

bug_ids = []
pr_ids  = []
desc    = []

ronum = 0
for r in cr:
    if (ronum == 0):
        ronum += 1
        continue
    bug_ids.append(r[0])
    pr_ids.append(r[1])
    desc.append(r[6])
    ronum += 1

if ronum <= 1:
    print('Sorry, my query for {:s} yielded no results'.format(term))
    sys.exit(-1)

if ronum < lim + 1:
    lim = ronum-1

for i in range(0,lim):
    printbuginfo(int(bug_ids[i]))
###
# Copyright (c) 2016, Atri Bhattacharya <badshah400@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

###

import sys
import csv
import urllib2
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

# supybot imports
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks

try:
    from supybot.i18n import PluginInternationalization
    _ = PluginInternationalization('BugSearch')
except ImportError:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x


class BugSearch(callbacks.Plugin):
    """A plugin to search openSUSE's bugzilla installation"""
    threaded = True

    def query(self, irc, msg, args, term):
        """Command to search for relevant bugs on openSUSE bugzilla"""
        
        bugz_main = 'https://bugzilla.opensuse.org'
        bugz_fb   = 'https://bugzilla.suse.com'
        bugz_nov  = 'https://bugzilla.novell.com'

        # TEST IF bugz_main IS ACCESSIBLE, IF SO FALL BACK TO bugz_fb
        try:
            urllib2.urlopen(bugz_main)
        except urllib2.URLError, e:
            bugz_main = bugz_fb
            pass

        try:
            urllib2.urlopen(bugz_main)
        except urllib2.URLError, e:
            bugz_main = bugz_nov
            pass

        try:
            urllib2.urlopen(bugz_main)
        except:
            print('Cannot access bugzilla at the moment, sorry!')
            sys.exit(-14)

        def printbuginfo(bugid):
            url    = bugz_main + '/{:d}'.format(bugid)
            xmlurl = bugz_main + '/show_bug.cgi?ctype=xml&id={:d}'.format(bugid)
            xmlres = urllib2.urlopen(xmlurl)
            tree   = ET.parse(xmlres)
            root   = tree.getroot()
            node   = root.find('bug')
            crtime = node.find('creation_ts').text.split(' ')
            crstr  = crtime[0] + ' ' + crtime[1]
            prod   = node.find('product').text
            comp   = node.find('component').text
            sever  = node.find('bug_severity').text
            prior  = node.find('priority').text
            stat   = node.find('bug_status').text
            summ   = node.find('short_desc').text
            repid  = node.find('reporter').get('name')
            assid  = node.find('assigned_to').get('name')
            if assid == 'E-mail List' or assid == 'E-Mail List':
                assid += (' (' + node.find('assigned_to').text + ')')

            # Find the last comment_count, this corresponds to the total number of comments
            ldesc  = node.findall('long_desc')
            comms  = ldesc[-1].find('comment_count').text
            
            if int(comms) > 1:
                mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                         'Created at {:s} by {:s}, '
                         'Assigned to {:s}, '
                         '{:s} comments'.format(url, stat, sever, prior, summ, crstr,
                                               repid, assid, comms))
            elif int(comms) == 1:
                mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                         'Created at {:s} by {:s}, '
                         'Assigned to {:s}, '
                         '1 comment'.format(url, stat, sever, prior, summ, crstr,
                                               repid, assid))
            else:
                mess = (u'Bug {:s}, {:s}, {:s}, {:s}, {:s}, '
                         'Created at {:s} by {:s}, '
                         'Assigned to {:s}'.format(url, stat, sever, prior, summ, crstr,
                                                  repid, assid))

            irc.reply(mess)

        # For the IRC bugbot plugin delete the following line
        #term = 'FiReFoX'
        lim  = 3

        # CONSTRUCT THE URL PART/PART
        boourl       = bugz_main + '/buglist.cgi?'
        limurl       = 'limit={:d}'.format(lim)

        semode       = 'anywords'

        # FOR NOW WE ONLY MATCH AGAINST THE COMPONENT, SUMMARY AND CLASSIFICATION
        sefields     = ['component', 'short_desc', 'classification']

        fieldurl     = ''
        valurl       = ''
        fcnt         = 0
        for field in sefields:
            fcnt     += 1
            fieldurl += 'f{:d}={:s}&'.format(fcnt, field)
            valurl   += 'v{:d}={:s}&'.format(fcnt, term)

        parturl      = (fieldurl + 
                        'j_top=OR&o1={0:s}&o2={0:s}&o3={0:s}&'.format(semode) +
                        'resolution=---&' +
                        valurl)

        url = (boourl + parturl
               + 'ctype=csv&order=bug_id%20DESC&' + limurl)

        data = urllib2.urlopen(url)
        cr   = csv.reader(data)

        bug_ids = []
        pr_ids  = []
        desc    = []

        ronum = 0
        for r in cr:
            if (ronum == 0):
                ronum += 1
                continue
            bug_ids.append(r[0])
            pr_ids.append(r[1])
            desc.append(r[6])
            ronum += 1

        if ronum <= 1:
            irc.reply('Sorry, my query for {:s} yielded no results'.format(term))
            sys.exit(-1)

        if ronum < lim + 1:
            lim = ronum-1

        for i in range(0,lim):
            printbuginfo(int(bug_ids[i]))
        
    query = wrap(query, (['text']))
    
Class = BugSearch

# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.