[Planner Dev] A new bugzilla plugin (preview)



Hi,

This a a first preview of another version for the bugzilla plugin.
It is definitively incomplete but does:
 - get the product list from the url
 - imports the bugs from a product

I'll add later the bug description and a bugzilla real synchronisation
(it actually only imports bugs).
I'll try to also bind the UI so that script may do more interaction with
it (I'm thinking about undo/redo task cases here for example).

Regarding the python module, it still need some work for freeing the
memory in an efficient and clean way. For what I could notice, even if I
free the namespace in which the script is executed, callbacks still
exists which is not the expected behaviour. I'll dig that point further.

Regards,
Xavier Ordoquy.
#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade

import planner

import httplib
import urllib
import sgmllib
import htmlentitydefs

class QueryParser(sgmllib.SGMLParser):
    def __init__(self):
        sgmllib.SGMLParser.__init__(self)
        self.is_in_product = 0
        self.products = []

    def start_select(self, attrs):
        for att in attrs:
            if att[0] == 'name' and att[1] == 'product':
                self.is_in_product = 1

    def end_select(self):
        self.is_in_product = 0

    def start_option(self, attrs):
        if self.is_in_product == 1:
            for att in attrs:
                if att[0] == 'value':
                    self.products.append(att[1])


class BuglistParser(sgmllib.SGMLParser):
    def __init__(self):
        sgmllib.SGMLParser.__init__(self)
        self.is_in_bug = 0
        self.bugs = []

    def start_tr(self, attrs):
        for att in attrs:
            if att[0] == 'class':
                self.is_in_bug = 1

    def end_tr(self):
        self.is_in_bug = 0

    def start_a(self, attrs):
        if self.is_in_bug == 1:
            for att in attrs:
                if att[0] == 'href':
                    self.bugs.append(int(att[1][att[1].find('=')+1:]))

##############################################################################

def get_products(url):
    if url[:7] == 'http://':
        url = url[7:]
    if url.find('/') != -1:
        base = url[:url.find('/')]
        path = url[url.find('/'):]+'query.cgi'
    else:
        base = url
        path = '/query.cgi'
    conn = httplib.HTTPConnection(base)
    conn.request('GET', path)
    r1 = conn.getresponse()
    #print r1.status, r1.reason
    data1 = r1.read()
    p = QueryParser()
    p.feed(data1)
    p.close()
    products = p.products
    conn.close()
    return products

def on_refresh_button_clicked(*args):
    global products
    widget = xml.get_widget('bugzilla_url')
    url = widget.get_text()
    if url != '':
        products = get_products(url)
        widget = xml.get_widget('product_list')
        menu = gtk.Menu()
        for product in products:
            menuitem = gtk.MenuItem(product)
            menu.add(menuitem)
            menuitem.show()
        widget.set_menu(menu)

def on_bugzilla_get_ok_clicked(*args):
    widget = xml.get_widget('bugzilla_url')
    url = widget.get_text()
    widget = xml.get_widget('product_list')
    position = widget.get_history()
    product = products[position]
    if url != '':
        if url[:7] == 'http://':
            url = url[7:]
        if url.find('/') != -1:
            base = url[:url.find('/')]
            path = url[url.find('/'):]+'buglist.cgi'
        else:
            base = url
            path = '/buglist.cgi'
        conn = httplib.HTTPConnection(base)
        path = path +'?short_desc_type=allwordssubstr&short_desc=&product=%s&long_desc_type=allwordssubstr&long_desc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=anywords&keywords=&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&emailtype1=substring&email1=&emailtype2=substring&email2=&bugidtype=include&bug_id=&changedin=&chfieldfrom=&chfieldto=Now&chfieldvalue=&cmdtype=doit&order=Bug+Number&field0-0-0=noop&type0-0-0=noop&value0-0-0=' % (product)
        conn.request('GET', path)
        r1 = conn.getresponse()
        #print r1.status, r1.reason
        data1 = r1.read()
        p = BuglistParser()
        p.feed(data1)
        p.close()
        print len(p.bugs)
        conn.close()
    widget = xml.get_widget('bugzilla_get')
    widget.destroy()
    for bug in p.bugs:
        task = planner.Task()
        task.set_name('[Bug #%i]' % bug)
        project.insert_task(task=task) 

if __name__ == '__main__':
    global xml
    xml = gtk.glade.XML('./mpp-bugzilla.glade')
    xml.signal_autoconnect(globals())
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>

<glade-interface>

<widget class="GtkDialog" id="bugzilla_get">
  <property name="visible">True</property>
  <property name="title" translatable="yes">Bugzilla Import</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="has_separator">True</property>

  <child internal-child="vbox">
    <widget class="GtkVBox" id="dialog-vbox1">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child internal-child="action_area">
	<widget class="GtkHButtonBox" id="dialog-action_area1">
	  <property name="visible">True</property>
	  <property name="layout_style">GTK_BUTTONBOX_END</property>

	  <child>
	    <widget class="GtkButton" id="bugzilla_get_help">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-help</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-11</property>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkButton" id="bugzilla_get_cancel">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-cancel</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-6</property>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkButton" id="bugzilla_get_ok">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-ok</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-5</property>
	      <signal name="clicked" handler="on_bugzilla_get_ok_clicked" last_modification_time="Thu, 13 May 2004 20:27:19 GMT"/>
	    </widget>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">True</property>
	  <property name="pack_type">GTK_PACK_END</property>
	</packing>
      </child>

      <child>
	<widget class="GtkCheckButton" id="new_bugs_only">
	  <property name="visible">True</property>
	  <property name="can_focus">True</property>
	  <property name="label" translatable="yes">New bugs only</property>
	  <property name="use_underline">True</property>
	  <property name="relief">GTK_RELIEF_NORMAL</property>
	  <property name="active">False</property>
	  <property name="inconsistent">False</property>
	  <property name="draw_indicator">True</property>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">False</property>
	  <property name="pack_type">GTK_PACK_END</property>
	</packing>
      </child>

      <child>
	<widget class="GtkHBox" id="hbox3">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">0</property>

	  <child>
	    <widget class="GtkLabel" id="loading">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">Loading Bugs</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">False</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="padding">5</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkProgressBar" id="progress_loading">
	      <property name="visible">True</property>
	      <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
	      <property name="fraction">0</property>
	      <property name="pulse_step">0.1</property>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">True</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">10</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	  <property name="pack_type">GTK_PACK_END</property>
	</packing>
      </child>

      <child>
	<widget class="GtkHBox" id="hbox1">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">5</property>

	  <child>
	    <widget class="GtkLabel" id="label1">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">Bugzilla URL</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">False</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="padding">5</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkEntry" id="bugzilla_url">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="editable">True</property>
	      <property name="visibility">True</property>
	      <property name="max_length">0</property>
	      <property name="text" translatable="yes">http://bugzilla.gnome.org/</property>
	      <property name="has_frame">True</property>
	      <property name="invisible_char" translatable="yes">*</property>
	      <property name="activates_default">False</property>
	    </widget>
	    <packing>
	      <property name="padding">1</property>
	      <property name="expand">True</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkButton" id="refresh_button">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-refresh</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <signal name="clicked" handler="on_refresh_button_clicked" last_modification_time="Thu, 13 May 2004 09:49:24 GMT"/>
	    </widget>
	    <packing>
	      <property name="padding">0</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">10</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>

      <child>
	<widget class="GtkHBox" id="hbox4">
	  <property name="visible">True</property>
	  <property name="homogeneous">False</property>
	  <property name="spacing">5</property>

	  <child>
	    <widget class="GtkLabel" id="label3">
	      <property name="visible">True</property>
	      <property name="label" translatable="yes">Products</property>
	      <property name="use_underline">False</property>
	      <property name="use_markup">False</property>
	      <property name="justify">GTK_JUSTIFY_LEFT</property>
	      <property name="wrap">False</property>
	      <property name="selectable">False</property>
	      <property name="xalign">0.5</property>
	      <property name="yalign">0.5</property>
	      <property name="xpad">0</property>
	      <property name="ypad">0</property>
	    </widget>
	    <packing>
	      <property name="padding">5</property>
	      <property name="expand">False</property>
	      <property name="fill">False</property>
	    </packing>
	  </child>

	  <child>
	    <widget class="GtkOptionMenu" id="product_list">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="history">-1</property>

	      <child>
		<widget class="GtkMenu" id="menu1">
		</widget>
	      </child>
	    </widget>
	    <packing>
	      <property name="padding">1</property>
	      <property name="expand">True</property>
	      <property name="fill">True</property>
	    </packing>
	  </child>
	</widget>
	<packing>
	  <property name="padding">10</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>
    </widget>
  </child>
</widget>

<widget class="GtkDialog" id="bugzilla_load">
  <property name="title" translatable="yes">dialog1</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="default_width">600</property>
  <property name="default_height">300</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="has_separator">True</property>

  <child internal-child="vbox">
    <widget class="GtkVBox" id="dialog-vbox2">
      <property name="visible">True</property>
      <property name="homogeneous">False</property>
      <property name="spacing">0</property>

      <child internal-child="action_area">
	<widget class="GtkHButtonBox" id="dialog-action_area2">
	  <property name="visible">True</property>
	  <property name="layout_style">GTK_BUTTONBOX_END</property>

	  <child>
	    <widget class="GtkButton" id="bugzilla_load_cancel">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-cancel</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-6</property>
	    </widget>
	  </child>

	  <child>
	    <widget class="GtkButton" id="bugzilla_load_ok">
	      <property name="visible">True</property>
	      <property name="can_default">True</property>
	      <property name="can_focus">True</property>
	      <property name="label">gtk-ok</property>
	      <property name="use_stock">True</property>
	      <property name="relief">GTK_RELIEF_NORMAL</property>
	      <property name="response_id">-5</property>
	    </widget>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">True</property>
	  <property name="pack_type">GTK_PACK_END</property>
	</packing>
      </child>

      <child>
	<widget class="GtkLabel" id="label2">
	  <property name="visible">True</property>
	  <property name="label" translatable="yes">All the bugs has
been downloaded.
Press OK to insert them
In MrProject</property>
	  <property name="use_underline">False</property>
	  <property name="use_markup">False</property>
	  <property name="justify">GTK_JUSTIFY_CENTER</property>
	  <property name="wrap">False</property>
	  <property name="selectable">False</property>
	  <property name="xalign">0.5</property>
	  <property name="yalign">0.5</property>
	  <property name="xpad">0</property>
	  <property name="ypad">0</property>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">False</property>
	  <property name="fill">False</property>
	</packing>
      </child>

      <child>
	<widget class="GtkScrolledWindow" id="scrolledwindow1">
	  <property name="visible">True</property>
	  <property name="can_focus">True</property>
	  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
	  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
	  <property name="shadow_type">GTK_SHADOW_NONE</property>
	  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>

	  <child>
	    <widget class="GtkTreeView" id="bugzilla_bugs_treeview">
	      <property name="visible">True</property>
	      <property name="can_focus">True</property>
	      <property name="headers_visible">True</property>
	      <property name="rules_hint">True</property>
	      <property name="reorderable">False</property>
	      <property name="enable_search">True</property>
	    </widget>
	  </child>
	</widget>
	<packing>
	  <property name="padding">0</property>
	  <property name="expand">True</property>
	  <property name="fill">True</property>
	</packing>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]