From ec0cd3aa66ea7301f1a2410978490ff37c3a9ef1 Mon Sep 17 00:00:00 2001 From: Romain Bignon Date: Fri, 31 Jan 2014 17:11:32 +0100 Subject: [PATCH] support new versions of redmine --- modules/redmine/browser.py | 57 ++++++++++++++++++++++----------- modules/redmine/pages/index.py | 6 ++-- modules/redmine/pages/issues.py | 14 +++++--- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/modules/redmine/browser.py b/modules/redmine/browser.py index 4b03940f..4aff057c 100644 --- a/modules/redmine/browser.py +++ b/modules/redmine/browser.py @@ -115,33 +115,52 @@ class RedmineBrowser(BaseBrowser): preview_html.find("legend").drop_tree() return lxml.html.tostring(preview_html) + METHODS = {'POST': {'project_id': 'project_id', + 'column': 'query[column_names][]', + 'value': 'values[%s][]', + 'field': 'fields[]', + 'operator': 'operators[%s]', + }, + 'GET': {'project_id': 'project_id', + 'column': 'c[]', + 'value': 'v[%s][]', + 'field': 'f[]', + 'operator': 'op[%s]', + } + } + def query_issues(self, project_name, **kwargs): self.location('/projects/%s/issues' % project_name) token = self.page.get_authenticity_token() - data = (('project_id', project_name), - ('query[column_names][]', 'tracker'), + method = self.page.get_query_method() + data = ((self.METHODS[method]['project_id'], project_name), + (self.METHODS[method]['column'], 'tracker'), ('authenticity_token', token), - ('query[column_names][]', 'status'), - ('query[column_names][]', 'priority'), - ('query[column_names][]', 'subject'), - ('query[column_names][]', 'assigned_to'), - ('query[column_names][]', 'updated_on'), - ('query[column_names][]', 'category'), - ('query[column_names][]', 'fixed_version'), - ('query[column_names][]', 'done_ratio'), - ('query[column_names][]', 'author'), - ('query[column_names][]', 'start_date'), - ('query[column_names][]', 'due_date'), - ('query[column_names][]', 'estimated_hours'), - ('query[column_names][]', 'created_on'), + (self.METHODS[method]['column'], 'status'), + (self.METHODS[method]['column'], 'priority'), + (self.METHODS[method]['column'], 'subject'), + (self.METHODS[method]['column'], 'assigned_to'), + (self.METHODS[method]['column'], 'updated_on'), + (self.METHODS[method]['column'], 'category'), + (self.METHODS[method]['column'], 'fixed_version'), + (self.METHODS[method]['column'], 'done_ratio'), + (self.METHODS[method]['column'], 'author'), + (self.METHODS[method]['column'], 'start_date'), + (self.METHODS[method]['column'], 'due_date'), + (self.METHODS[method]['column'], 'estimated_hours'), + (self.METHODS[method]['column'], 'created_on'), ) for key, value in kwargs.iteritems(): if value: - data += (('values[%s][]' % key, value),) - data += (('fields[]', key),) - data += (('operators[%s]' % key, '~'),) + data += ((self.METHODS[method]['value'] % key, value),) + data += ((self.METHODS[method]['field'], key),) + data += ((self.METHODS[method]['operator'] % key, '~'),) - self.location('/issues?set_filter=1&per_page=100', urllib.urlencode(data)) + if method == 'POST': + self.location('/issues?set_filter=1&per_page=100', urllib.urlencode(data)) + else: + data += (('set_filter', '1'), ('per_page', '100')) + self.location(self.buildurl('/issues', *data)) assert self.is_on_page(IssuesPage) return {'project': self.page.get_project(project_name), diff --git a/modules/redmine/pages/index.py b/modules/redmine/pages/index.py index a384b709..3d146fca 100644 --- a/modules/redmine/pages/index.py +++ b/modules/redmine/pages/index.py @@ -23,9 +23,9 @@ from weboob.tools.browser import BasePage class LoginPage(BasePage): def login(self, username, password): - self.browser.select_form(nr=1) - self.browser['username'] = username - self.browser['password'] = password + self.browser.select_form(predicate=lambda f: f.attrs.get('method', '') == 'post') + self.browser['username'] = username.encode(self.browser.ENCODING) + self.browser['password'] = password.encode(self.browser.ENCODING) self.browser.submit() diff --git a/modules/redmine/pages/issues.py b/modules/redmine/pages/issues.py index f7fe9d86..20cd522f 100644 --- a/modules/redmine/pages/issues.py +++ b/modules/redmine/pages/issues.py @@ -61,7 +61,10 @@ class BaseIssuePage(BasePage): try: select = self.parser.select(self.document.getroot(), 'select#%s' % name, 1) except BrokenPageError: - return + try: + select = self.parser.select(self.document.getroot(), 'select#%s_1' % name, 1) + except BrokenPageError: + return for option in select.findall('option'): if option.attrib['value'].isdigit(): yield (option.attrib['value'], option.text) @@ -95,6 +98,9 @@ class IssuesPage(BaseIssuePage): 'statuses': 'values_status_id', } + def get_query_method(self): + return self.document.xpath('//form[@id="query_form"]')[0].attrib['method'].upper() + def iter_issues(self): try: issues = self.parser.select(self.document.getroot(), 'table.issues', 1) @@ -268,9 +274,9 @@ class IssuePage(NewIssuePage): params['updates'] = [] for div in self.parser.select(content, 'div.journal'): update = {} - update['id'] = div.find('h4').find('div').find('a').text[1:] - alist = div.find('h4').findall('a') - if len(alist) == 3: + alist = div.find('h4').xpath('.//a') + update['id'] = alist[0].text[1:] + if len(alist) == 4: update['author'] = (int(alist[-2].attrib['href'].split('/')[-1]), to_unicode(alist[-2].text)) else: