| 1 | #!/usr/bin/python |
|---|
| 2 | # -*- encoding: utf-8 -*- |
|---|
| 3 | |
|---|
| 4 | ## |
|---|
| 5 | ## tracaccess.py |
|---|
| 6 | ## Created on Sat Dec 23 00:10:54 2006 |
|---|
| 7 | ## by Antti Kaihola <antti.kaihola@linux-aktivaattori.org> |
|---|
| 8 | ## |
|---|
| 9 | ## Copyright (C) 2006 Antti Kaihola |
|---|
| 10 | ## This program is free software; you can redistribute it and/or modify |
|---|
| 11 | ## it under the terms of the GNU General Public License as published by |
|---|
| 12 | ## the Free Software Foundation; either version 2 of the License, or |
|---|
| 13 | ## (at your option) any later version. |
|---|
| 14 | ## |
|---|
| 15 | ## This program is distributed in the hope that it will be useful, |
|---|
| 16 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 | ## GNU General Public License for more details. |
|---|
| 19 | ## |
|---|
| 20 | ## You should have received a copy of the GNU General Public License |
|---|
| 21 | ## along with this program; if not, write to the Free Software |
|---|
| 22 | ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 23 | ## |
|---|
| 24 | |
|---|
| 25 | |
|---|
| 26 | import urllib2, cookielib |
|---|
| 27 | from itertools import izip, chain |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | def open_tickets_csv(base_url, report_number, username=None, password=None): |
|---|
| 31 | """ |
|---|
| 32 | >>> print open_tickets_csv('http://trac.ambitone.com/ambidjangolib', 3).readline().strip() |
|---|
| 33 | __color__,__group__,ticket,summary,component,version,type,owner,created,_changetime,_description,_reporter |
|---|
| 34 | """ |
|---|
| 35 | login_url = '%s/login' % base_url |
|---|
| 36 | report_url = '%s/report/%d?format=csv' % (base_url, report_number) |
|---|
| 37 | if username: |
|---|
| 38 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() |
|---|
| 39 | passman.add_password(None, base_url, username, password) |
|---|
| 40 | auth_handler = urllib2.HTTPDigestAuthHandler(passman) |
|---|
| 41 | jar = cookielib.CookieJar() |
|---|
| 42 | cookie_processor = urllib2.HTTPCookieProcessor(jar) |
|---|
| 43 | opener = urllib2.build_opener(cookie_processor, auth_handler) |
|---|
| 44 | urllib2.install_opener(opener) |
|---|
| 45 | try: |
|---|
| 46 | urllib2.urlopen(login_url) |
|---|
| 47 | print 'Login page returned no error' |
|---|
| 48 | except urllib2.HTTPError, e: |
|---|
| 49 | print 'Login page returned', e |
|---|
| 50 | if e.code not in (401, 403): |
|---|
| 51 | raise |
|---|
| 52 | return urllib2.urlopen(report_url) |
|---|
| 53 | |
|---|
| 54 | |
|---|
| 55 | def parse_tickets_csv(site_name, fp): |
|---|
| 56 | """ |
|---|
| 57 | >>> p = parse_tickets_csv(iter(('a,b,c\\n', '1,2,3\\n', '4,5,6\\n'))) |
|---|
| 58 | >>> p.next() == dict(a='1', b='2', c='3') |
|---|
| 59 | True |
|---|
| 60 | >>> p.next() == dict(a='4', b='5', c='6') |
|---|
| 61 | True |
|---|
| 62 | """ |
|---|
| 63 | fields = [field.replace('_', '') |
|---|
| 64 | for field in fp.next().strip().split(',')] |
|---|
| 65 | for row in fp: |
|---|
| 66 | yield dict(chain(izip(fields, row.strip().split(',')), |
|---|
| 67 | (('site_name', site_name),) )) |
|---|
| 68 | |
|---|
| 69 | |
|---|
| 70 | def import_tickets_csv(site_name, base_url, report_number, username=None, password=None): |
|---|
| 71 | """ |
|---|
| 72 | >>> t = import_tickets_csv('http://trac.ambitone.com/ambidjangolib', 3).next() |
|---|
| 73 | >>> t == dict(__group__=' Release', created='1166805521', |
|---|
| 74 | ... _changetime='1166805521', component='meta', |
|---|
| 75 | ... summary='create a logo for ambidjangolib', |
|---|
| 76 | ... _description='Replace the trac paw logo with something else.', |
|---|
| 77 | ... version='', _reporter='akaihola', owner='akaihola', |
|---|
| 78 | ... __color__='5', ticket='4', type='defect') |
|---|
| 79 | True |
|---|
| 80 | """ |
|---|
| 81 | return parse_tickets_csv(site_name, open_tickets_csv(base_url, report_number, username, password)) |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | if __name__ == '__main__': |
|---|
| 85 | from doctest import testmod |
|---|
| 86 | testmod() |
|---|