Import patch from Christoph Berg to support Gnats and cookies.
authorPierre Habouzit <madcoder@debian.org>
Fri, 16 Mar 2007 21:33:09 +0000 (22:33 +0100)
committerPierre Habouzit <madcoder@debian.org>
Fri, 16 Mar 2007 21:33:09 +0000 (22:33 +0100)
Thanks a _lot_ Christoph !

Signed-off-by: Christoph Berg <myon@debian.org>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
btslink.cfg
cookies.txt [new file with mode: 0644]
remote/__init__.py
remote/base.py
remote/gnats.py [new file with mode: 0644]
utils/config.py

index 5b5b78b7fb0210a8765dc2c2360be1a42ff4cadc..ebdf3d1b22cdf5fd1fcc8a637c4f48184f308c34 100644 (file)
@@ -3,6 +3,7 @@ user     = bts-link-upstream@lists.alioth.debian.org
 reply-to = bts-link-devel@lists.alioth.debian.org
 tagsidx  = http://bugs.debian.org/~ajt/madcoder-upstream-link
 spool    = /home/madcoder/debian/bts-link/db-h
+cookies  = /home/madcoder/debian/bts-link/cookies.txt
 ldap     = ldap://bts2ldap.debian.net:10101
 
 ;*****************************************************************************
@@ -210,6 +211,16 @@ uri      = http://bugzilla.xfce.org
 type     = bugzilla
 uri      = http://xprint.mozdev.org/bugs
 
+;*************************************************************************}}}*
+;
+; Gnats
+;
+;*************************************************************************{{{*
+
+[mutt]
+type     = gnats
+uri      = http://bugs.mutt.org
+
 ;*************************************************************************}}}*
 ;
 ; Mantis
diff --git a/cookies.txt b/cookies.txt
new file mode 100644 (file)
index 0000000..5faae32
--- /dev/null
@@ -0,0 +1 @@
+bugs.mutt.org  FALSE   /       FALSE   1972358590      gnatsweb-db-mutt        password&g%60vft&user&guest
index f369b3cf650e8809d82b7d8e680603473b8d3aee..7f0e755a8a6e5dc9fa0fdf06647e75e1c72564ed 100644 (file)
@@ -32,11 +32,13 @@ import commands
 
 from base import RemoteBts, ParseExn, DupeExn
 
-def wget(uri):
+def wget(uri, cookies=None):
     opts = []
     opts.append("--user-agent='btslink <bts-link-devel@lists.alioth.debian.org>'")
     opts.append("--no-check-certificate")
     opts.append("-q -o /dev/null")
+    if cookies:
+        opts.append("--load-cookies %s" % cookies)
     opts.append("-O -")
     return commands.getoutput("wget %s '%s'" % (' '.join(opts), uri))
 
index b5588643d037f6cfece95b69aec0a4fb317352d5..62c9da2db75284bc9dccd02f8421e1ebf44362d0 100644 (file)
@@ -281,5 +281,5 @@ class RemoteBts:
     def _bugId(self, data):
         return data.id
 
-import bugzilla, mantis, rt, savane, sourceforge, trac
+import bugzilla, gnats, mantis, rt, savane, sourceforge, trac
 
diff --git a/remote/gnats.py b/remote/gnats.py
new file mode 100644 (file)
index 0000000..6f08637
--- /dev/null
@@ -0,0 +1,67 @@
+# vim:set encoding=utf-8:
+###############################################################################
+# Copyright:
+#   © 2007 Christoph Berg <myon@debian.org>
+#   Copied from rt.py:
+#   © 2006 Sanghyeon Seo <sanxiyn@gmail.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. 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.
+# 3. Neither the name of the University nor the names of its contributors
+#    may be used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 urllib, urlparse, cgi
+
+from BeautifulSoup import BeautifulSoup
+from __init__ import *
+
+# <tr><td nowrap><b>State:</b></td>
+# <td><tt>open</tt></td></tr>
+
+def parse_table(soup, key):
+    cell = soup.firstText(key).findParent('td')
+    return cell.findNextSibling('td').first('tt').string
+
+# Cookie: gnatsweb-global=email&cb%40df7cb.de&database&mutt&Submitter-Id&any&columns&Notify-List%20Category%20Synopsis%20Confidential%20Severity%20Priority%20Responsible%20State%20Keywords%20Date-Required%20Class%20Submitter-Id%20Arrival-Date%20Closed-Date%20Last-Modified%20Originator%20Release; gnatsweb-db-mutt=password&g%60vft&user&guest
+
+class GnatsData:
+    def __init__(self, uri, id):
+        soup = BeautifulSoup(wget(uri, "cookies.txt"))
+
+        self.id = id or failwith(uri, "Gnats: no id")
+        self.status = parse_table(soup, 'State:') or failwith(uri, "Gnats: no status")
+        self.resolution = None
+
+class RemoteGnats(RemoteBts):
+    def __init__(self, cnf):
+        bugre  = r'^%(uri)s/([0-9]+)$'
+        urifmt = '%(uri)s/%(id)s'
+        RemoteBts.__init__(self, cnf, bugre, urifmt, GnatsData)
+
+    def isClosing(self, status, resolution):
+        return status in ('closed',)
+
+    def isWontfix(self, status, resolution):
+        return status in ('suspended',)
+
+RemoteBts.register('gnats', RemoteGnats)
index c15ea93db8a0fd0992de87ceeb55587dfd81463e..862cbd287296b1a76ed76d87c896cf3e4ec76b1e 100644 (file)
@@ -57,6 +57,9 @@ class _Config(RawConfigParser):
     def spool(self):
         return self.get('general', 'spool')
 
+    def cookies(self):
+        return self.get('general', 'cookies')
+
     def ldap(self):
         return self.get('general', 'ldap')