home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / launchpadbugs / html_buglist.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  12.9 KB  |  306 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''
  5. TODO:
  6.     * maybe move initialisation of libxml2 parser to utils
  7. '''
  8. import libxml2
  9. import urlparse
  10. import re
  11. from bugbase import LPBugInfo, Bug as LPBug
  12. from buglistbase import LPBugList, LPBugPage
  13. from lphelper import user, unicode_for_libxml2, sort
  14. from lpconstants import BASEURL
  15. from exceptions import parse_error
  16. from lptime import LPTime
  17. from utils import valid_lp_url, bugnumber_to_url
  18.  
  19. def noerr(ctx, str):
  20.     pass
  21.  
  22. libxml2.registerErrorHandler(noerr, None)
  23.  
  24. class BugInfo(LPBugInfo):
  25.     
  26.     def __init__(self, nr, url, status, importance, summary, package = None, all_tasks = False):
  27.         url = valid_lp_url(url, BASEURL.BUG)
  28.         LPBugInfo.__init__(self, nr, url, status, importance, summary, package, all_tasks)
  29.  
  30.  
  31.  
  32. class BugInfoWatches(LPBugInfo):
  33.     
  34.     def __init__(self, lp_url, lp_bugnr, lp_title, watch_url, watch_bugnr, watch_status, private, all_tasks):
  35.         url = valid_lp_url(lp_url, BASEURL.BUG)
  36.         LPBugInfo.__init__(self, lp_bugnr, url, None, None, lp_title, None, all_tasks)
  37.         if not watch_url:
  38.             pass
  39.         self.watch_url = 'unknown'
  40.         self.watch_bugnr = watch_bugnr
  41.         if not watch_status:
  42.             pass
  43.         self.watch_status = 'unknown'
  44.         self.private = private
  45.  
  46.  
  47. re_url_to_project = re.compile('/(\\w+)/\\+bug/\\d+')
  48.  
  49. class ExpBugInfo(LPBugInfo):
  50.     
  51.     def __init__(self, bugnumber, url, importance, summary, private, package, date_last_update, all_tasks = False):
  52.         url = valid_lp_url(url, BASEURL.BUG)
  53.         if package is None:
  54.             u = urlparse.urlsplit(url)
  55.             m = re_url_to_project.match(u[2])
  56.             if m:
  57.                 package = m.group(1)
  58.             
  59.         
  60.         LPBugInfo.__init__(self, bugnumber, url, None, importance, summary, package, all_tasks)
  61.         self.private = private
  62.         self.date_last_update = date_last_update
  63.  
  64.  
  65.  
  66. class BugPage(LPBugPage):
  67.     '''
  68.     grab content of a single bug-table    
  69.     '''
  70.     
  71.     def find_parse_function(connection, url, all_tasks):
  72.         url = valid_lp_url(url, BASEURL.BUGPAGE)
  73.         lp_content = connection.get(url)
  74.         xmldoc = libxml2.htmlParseDoc(unicode_for_libxml2(lp_content.text), 'UTF-8')
  75.         u = urlparse.urlsplit(url)
  76.         if '+milestone' in u[2]:
  77.             result = BugPage.parse_html_milestone_bugpage(xmldoc, all_tasks, url)
  78.         elif '+expirable-bugs' in u[2]:
  79.             result = BugPage.parse_html_expirable_bugpage(xmldoc, all_tasks, url)
  80.         elif 'bugs/bugtrackers' in u[2]:
  81.             result = BugPage.parse_html_bugtracker_bugpage(xmldoc, all_tasks, url)
  82.         else:
  83.             result = BugPage.parse_html_bugpage(xmldoc, all_tasks, url)
  84.         return result
  85.  
  86.     find_parse_function = staticmethod(find_parse_function)
  87.     
  88.     def parse_html_bugpage(xmldoc, all_tasks, debug_url):
  89.         
  90.         def _parse():
  91.             if xmldoc.xpathEval('//div/p[contains(.,"There are currently no open bugs.")]') or xmldoc.xpathEval('//div/p[contains(.,"No results for search")]'):
  92.                 raise StopIteration
  93.             xmldoc.xpathEval('//div/p[contains(.,"No results for search")]')
  94.             col = int(xmldoc.xpathEval('count(//table[@id="buglisting"]//thead//tr//th[not(@*)])'))
  95.             for span in xmldoc.xpathEval('//table[@id="buglisting"]//thead//tr//@colspan'):
  96.                 col += int(span.content)
  97.             
  98.             if not col == 6 and col == 7:
  99.                 raise AssertionError, 'Parsing of this page (%s) is not     supported by python-launchpad-bugs' % debug_url
  100.             bug_table_rows = xmldoc.xpathEval('//table[@id="buglisting"]//tbody//tr')
  101.             for row in bug_table_rows:
  102.                 out = []
  103.                 for i in xrange(2, col + 1):
  104.                     if i == 3:
  105.                         expr = 'td[' + str(i) + ']//a'
  106.                     else:
  107.                         expr = 'td[' + str(i) + ']/text()'
  108.                     res = row.xpathEval(expr)
  109.                     parse_error(res, 'BugPage.parse_html_bugpage._parse.row[%s]' % i, xml = row, url = debug_url)
  110.                     if i == 3:
  111.                         out.append(res[0].prop('href'))
  112.                     
  113.                     out.append(res[0].content)
  114.                 
  115.                 out.pop(3)
  116.                 if len(out) == 6:
  117.                     out.append(out.pop(3))
  118.                 else:
  119.                     out.append(None)
  120.                 yield BugInfo(out[0], out[1], out[4], out[3], out[2], out[5], all_tasks)
  121.             
  122.  
  123.         next = xmldoc.xpathEval('//div[@class="lesser"]//a[@rel="next"]//@href')
  124.         m = xmldoc.xpathEval('//td[@class="batch-navigation-index"]')
  125.         if m:
  126.             m = m.pop()
  127.             n = re.search('(\\d+)\\s+results?', m.content)
  128.             parse_error(n, 'BugPage.parse_html_bugpage.length', url = debug_url)
  129.             length = n.group(1)
  130.             n = m.xpathEval('strong')
  131.             batchsize = (int(n[1].content) - int(n[0].content)) + 1
  132.         else:
  133.             length = batchsize = 0
  134.         if next:
  135.             return (_parse(), next[0].content, batchsize, int(length))
  136.         return (_parse(), False, batchsize, int(length))
  137.  
  138.     parse_html_bugpage = staticmethod(parse_html_bugpage)
  139.     
  140.     def parse_html_milestone_bugpage(xmldoc, all_tasks, debug_url):
  141.         
  142.         def _parse():
  143.             bug_table_rows = xmldoc.xpathEval('//table[@id="milestone_bugtasks"]//tbody//tr')
  144.             for row in bug_table_rows:
  145.                 x = row.xpathEval('td[1]//span/img')
  146.                 parse_error(x, 'BugPage.parse_html_milestone_bugpage.importance', xml = row, url = debug_url)
  147.                 importance = x[0].prop('alt').strip('()').title()
  148.                 x = row.xpathEval('td[2]')
  149.                 parse_error(x, 'BugPage.parse_html_milestone_bugpage.nr', xml = row, url = debug_url)
  150.                 nr = x[0].content
  151.                 x = row.xpathEval('td[3]/a')
  152.                 parse_error(x, 'BugPage.parse_html_milestone_bugpage.url', xml = row, url = debug_url)
  153.                 url = x[0].prop('href')
  154.                 summary = x[0].content
  155.                 x = row.xpathEval('td[5]//a')
  156.                 if x:
  157.                     usr = user.parse_html_user(x[0])
  158.                 else:
  159.                     usr = user(None)
  160.                 x = row.xpathEval('td[6]/span[2]')
  161.                 parse_error(x, 'BugPage.parse_html_milestone_bugpage.status', xml = row, url = debug_url)
  162.                 status = x[0].content
  163.                 x = BugInfo(nr, url, status, importance, summary, None, all_tasks)
  164.                 x.assignee = usr
  165.                 yield x
  166.             
  167.  
  168.         m = xmldoc.xpathEval('//h2[@id="bug-count"]')
  169.         return (_parse(), False, batchsize, length)
  170.  
  171.     parse_html_milestone_bugpage = staticmethod(parse_html_milestone_bugpage)
  172.     
  173.     def parse_html_bugtracker_bugpage(xmldoc, all_tasks, debug_url):
  174.         
  175.         def _parse():
  176.             rows = xmldoc.xpathEval('//table[@class="sortable listing" and @id="latestwatches"]/tbody//tr')
  177.             for row in rows:
  178.                 (lp_url, lp_bugnr, lp_title, watch_url, watch_bugnr, watch_status, private) = [
  179.                     None] * 7
  180.                 data = row.xpathEval('td')
  181.                 parse_error(len(data) == 3, 'BugPage.parse_html_bugtracker_bugpage.len_td=%s' % len(data), xml = row, url = debug_url)
  182.                 x = data[0].xpathEval('a')
  183.                 if x:
  184.                     lp_url = x[0].prop('href')
  185.                     lp_bugnr = int(lp_url.split('/').pop())
  186.                     lp_title = x[0].content.split(':', 1)[-1].strip('\n ')
  187.                     x = data[1].xpathEval('a')
  188.                     parse_error(x, 'BugPage.parse_html_bugtracker_bugpage.watch_url', xml = row, url = debug_url)
  189.                     watch_url = x[0].prop('href')
  190.                     watch_bugnr = x[0].content
  191.                     watch_status = data[2].content
  192.                 else:
  193.                     x = data[0].content
  194.                     parse_error('(Private)' in x, 'BugPage.parse_html_bugtracker_bugpage.private', xml = row, url = debug_url)
  195.                     private = True
  196.                     x = x.split('#').pop()
  197.                     lp_bugnr = int(x.split(':').pop(0))
  198.                     lp_url = bugnumber_to_url(lp_bugnr)
  199.                 b = BugInfoWatches(lp_url, lp_bugnr, lp_title, watch_url, watch_bugnr, watch_status, bool(private), all_tasks)
  200.                 yield b
  201.             
  202.  
  203.         next = xmldoc.xpathEval('//td[@class="batch-navigation-links"]//a[@rel="next"]//@href')
  204.         m = xmldoc.xpathEval('//td[@class="batch-navigation-index"]')
  205.         if m:
  206.             m = m.pop()
  207.             n = re.search('(\\d+)\\s+results?', m.content)
  208.             parse_error(n, 'BugPage.parse_html_bugpage.length', url = debug_url)
  209.             length = n.group(1)
  210.             n = m.xpathEval('strong')
  211.             batchsize = (int(n[1].content) - int(n[0].content)) + 1
  212.         else:
  213.             length = batchsize = 0
  214.         if next:
  215.             return (_parse(), next[0].content, batchsize, int(length))
  216.         return (_parse(), False, batchsize, int(length))
  217.  
  218.     parse_html_bugtracker_bugpage = staticmethod(parse_html_bugtracker_bugpage)
  219.     
  220.     def parse_html_expirable_bugpage(xmldoc, all_tasks, debug_url):
  221.         
  222.         def _parse():
  223.             rows = xmldoc.xpathEval('//table[@class="listing" and @id="buglisting"]//tbody//tr')
  224.             for row in rows:
  225.                 col_count = len(row.xpathEval('td'))
  226.                 None(parse_error if col_count < col_count else col_count < 7, 'BugPage.parse_html_expirable_bugpage.col_count', xml = row, url = debug_url)
  227.                 m = row.xpathEval('td[1]/img')
  228.                 parse_error(m, 'BugPage.parse_html_expirable_bugpage.importance', xml = row, url = debug_url)
  229.                 importance = m[0].prop('title').split()[0]
  230.                 m = row.xpathEval('td[2]')
  231.                 parse_error(m, 'BugPage.parse_html_expirable_bugpage.bugnumber', xml = row, url = debug_url)
  232.                 bugnumber = int(m[0].content)
  233.                 m = row.xpathEval('td[3]/a')
  234.                 parse_error(m, 'BugPage.parse_html_expirable_bugpage.url', xml = row, url = debug_url)
  235.                 url = m[0].prop('href')
  236.                 summary = m[0].content
  237.                 m = row.xpathEval('td[4]/img')
  238.                 private = False
  239.                 if m:
  240.                     private = m[0].prop('alt').lower() == 'private'
  241.                 
  242.                 if col_count == 6:
  243.                     m = row.xpathEval('td[5]')
  244.                     parse_error(m, 'BugPage.parse_html_expirable_bugpage.package', xml = row, url = debug_url)
  245.                     package = m[0].content
  246.                     if package == '\xe2\x80\x94':
  247.                         package = None
  248.                     
  249.                     m = row.xpathEval('td[6]')
  250.                     parse_error(m, 'BugPage.parse_html_expirable_bugpage.date_last_update.1', xml = row, url = debug_url)
  251.                     date_last_update = LPTime(m[0].content)
  252.                 elif col_count == 5:
  253.                     package = None
  254.                     m = row.xpathEval('td[5]')
  255.                     parse_error(m, 'BugPage.parse_html_expirable_bugpage.date_last_update.2', xml = row, url = debug_url)
  256.                     date_last_update = LPTime(m[0].content)
  257.                 
  258.                 yield ExpBugInfo(bugnumber, url, importance, summary, private, package, date_last_update, all_tasks)
  259.             
  260.  
  261.         next = xmldoc.xpathEval('//td[@class="batch-navigation-links"]//a[@rel="next"]//@href')
  262.         m = xmldoc.xpathEval('//td[@class="batch-navigation-index"]')
  263.         if m:
  264.             m = m.pop()
  265.             n = re.search('(\\d+)\\s+results?', m.content)
  266.             parse_error(n, 'BugPage.parse_html_bugpage.length', url = debug_url)
  267.             length = n.group(1)
  268.             n = m.xpathEval('strong')
  269.             batchsize = (int(n[1].content) - int(n[0].content)) + 1
  270.         else:
  271.             length = batchsize = 0
  272.         if next:
  273.             return (_parse(), next[0].content, batchsize, int(length))
  274.         return (_parse(), False, batchsize, int(length))
  275.  
  276.     parse_html_expirable_bugpage = staticmethod(parse_html_expirable_bugpage)
  277.  
  278.  
  279. class BugList(LPBugList):
  280.     '''
  281.     returns a SET of LPBugInfo objects
  282.     searches baseurl and its following pages
  283.     '''
  284.     
  285.     def __init__(self, baseurl, connection = None, all_tasks = False, progress_hook = None):
  286.         if hasattr(baseurl, 'baseurl'):
  287.             baseurl.baseurl = valid_lp_url(baseurl.baseurl, BASEURL.BUGLIST)
  288.         else:
  289.             baseurl = valid_lp_url(baseurl, BASEURL.BUGLIST)
  290.         LPBugList.__init__(self, baseurl, connection, all_tasks, BugPage, progress_hook)
  291.  
  292.     
  293.     def add(self, item):
  294.         if not isinstance(item, (LPBugInfo, LPBug)):
  295.             raise AssertionError
  296.         LPBugList.add(self, item)
  297.  
  298.     
  299.     def sort(self, optsort):
  300.         
  301.         cmp_func = lambda x, y: sort(x, y, optsort.strip('-'))
  302.         isreverse = optsort.startswith('-')
  303.         return sorted(self, cmp = cmp_func, reverse = isreverse)
  304.  
  305.  
  306.