comparison hgext/bugzilla.py @ 15870:f4c859293ed4 stable

bugzilla: make XMLRPC interface support http and https access Inadvertently support is currently only for https. For some reason I thought xmlrpclib.SafeTransport did http and https, but it is https only. So create http and https XMLRPC transports that retain cookies. Decide which to use by inspecting the Bugzilla URL.
author Jim Hague <jim.hague@acm.org>
date Wed, 11 Jan 2012 16:54:29 +0000
parents 29f55c0e39e7
children b468cea3f29d
comparison
equal deleted inserted replaced
15848:012b285cf643 15870:f4c859293ed4
253 ''' 253 '''
254 254
255 from mercurial.i18n import _ 255 from mercurial.i18n import _
256 from mercurial.node import short 256 from mercurial.node import short
257 from mercurial import cmdutil, mail, templater, util 257 from mercurial import cmdutil, mail, templater, util
258 import re, time, xmlrpclib 258 import re, time, urlparse, xmlrpclib
259 259
260 class bzaccess(object): 260 class bzaccess(object):
261 '''Base class for access to Bugzilla.''' 261 '''Base class for access to Bugzilla.'''
262 262
263 def __init__(self, ui): 263 def __init__(self, ui):
471 raise util.Abort(_('unknown database schema')) 471 raise util.Abort(_('unknown database schema'))
472 return ids[0][0] 472 return ids[0][0]
473 473
474 # Buzgilla via XMLRPC interface. 474 # Buzgilla via XMLRPC interface.
475 475
476 class CookieSafeTransport(xmlrpclib.SafeTransport): 476 class cookietransportrequest(object):
477 """A SafeTransport that retains cookies over its lifetime. 477 """A Transport request method that retains cookies over its lifetime.
478 478
479 The regular xmlrpclib transports ignore cookies. Which causes 479 The regular xmlrpclib transports ignore cookies. Which causes
480 a bit of a problem when you need a cookie-based login, as with 480 a bit of a problem when you need a cookie-based login, as with
481 the Bugzilla XMLRPC interface. 481 the Bugzilla XMLRPC interface.
482 482
483 So this is a SafeTransport which looks for cookies being set 483 So this is a helper for defining a Transport which looks for
484 in responses and saves them to add to all future requests. 484 cookies being set in responses and saves them to add to all future
485 It appears a SafeTransport can do both HTTP and HTTPS sessions, 485 requests.
486 which saves us having to do a CookieTransport too.
487 """ 486 """
488 487
489 # Inspiration drawn from 488 # Inspiration drawn from
490 # http://blog.godson.in/2010/09/how-to-make-python-xmlrpclib-client.html 489 # http://blog.godson.in/2010/09/how-to-make-python-xmlrpclib-client.html
491 # http://www.itkovian.net/base/transport-class-for-pythons-xml-rpc-lib/ 490 # http://www.itkovian.net/base/transport-class-for-pythons-xml-rpc-lib/
535 parser.feed(payload) 534 parser.feed(payload)
536 parser.close() 535 parser.close()
537 536
538 return unmarshaller.close() 537 return unmarshaller.close()
539 538
539 # The explicit calls to the underlying xmlrpclib __init__() methods are
540 # necessary. The xmlrpclib.Transport classes are old-style classes, and
541 # it turns out their __init__() doesn't get called when doing multiple
542 # inheritance with a new-style class.
543 class cookietransport(cookietransportrequest, xmlrpclib.Transport):
544 def __init__(self, use_datetime=0):
545 xmlrpclib.Transport.__init__(self, use_datetime)
546
547 class cookiesafetransport(cookietransportrequest, xmlrpclib.SafeTransport):
548 def __init__(self, use_datetime=0):
549 xmlrpclib.SafeTransport.__init__(self, use_datetime)
550
540 class bzxmlrpc(bzaccess): 551 class bzxmlrpc(bzaccess):
541 """Support for access to Bugzilla via the Bugzilla XMLRPC API. 552 """Support for access to Bugzilla via the Bugzilla XMLRPC API.
542 553
543 Requires a minimum Bugzilla version 3.4. 554 Requires a minimum Bugzilla version 3.4.
544 """ 555 """
551 bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi" 562 bzweb = bzweb.rstrip("/") + "/xmlrpc.cgi"
552 563
553 user = self.ui.config('bugzilla', 'user', 'bugs') 564 user = self.ui.config('bugzilla', 'user', 'bugs')
554 passwd = self.ui.config('bugzilla', 'password') 565 passwd = self.ui.config('bugzilla', 'password')
555 566
556 self.bzproxy = xmlrpclib.ServerProxy(bzweb, CookieSafeTransport()) 567 self.bzproxy = xmlrpclib.ServerProxy(bzweb, self.transport(bzweb))
557 self.bzproxy.User.login(dict(login=user, password=passwd)) 568 self.bzproxy.User.login(dict(login=user, password=passwd))
569
570 def transport(self, uri):
571 if urlparse.urlparse(uri, "http")[0] == "https":
572 return cookiesafetransport()
573 else:
574 return cookietransport()
558 575
559 def get_bug_comments(self, id): 576 def get_bug_comments(self, id):
560 """Return a string with all comment text for a bug.""" 577 """Return a string with all comment text for a bug."""
561 c = self.bzproxy.Bug.comments(dict(ids=[id])) 578 c = self.bzproxy.Bug.comments(dict(ids=[id]))
562 return ''.join([t['text'] for t in c['bugs'][str(id)]['comments']]) 579 return ''.join([t['text'] for t in c['bugs'][str(id)]['comments']])