]>
Commit | Line | Data |
---|---|---|
c3e3cdd9 AK |
1 | #!/usr/bin/python |
2 | import cStringIO | |
3 | import calendar | |
4 | import feedparser | |
5 | import formatter | |
6 | import htmllib | |
a41187bd | 7 | import mechanize |
c3e3cdd9 AK |
8 | import os |
9 | import random | |
10 | import string | |
11 | import time | |
12 | import traceback | |
13 | import urlparse | |
14 | import zephyr | |
15 | ||
16 | zephyr_sender = 'jira' | |
17 | zephyr_class = 'andersk-test' | |
18 | time_file = 'jirabot.time' | |
a41187bd | 19 | |
a41187bd EY |
20 | b = mechanize.Browser() |
21 | b.set_handle_robots(False) | |
3dae361a | 22 | b.add_client_certificate("https://idp.mit.edu:9443", "cert.pem", "cert.pem") |
a41187bd | 23 | b.addheaders = [("Accept-Language", "en-us,en;q=0.5"),] |
3dae361a | 24 | b.open("https://jira.mit.edu/jira/secure/Dashboard.jspa") |
a41187bd | 25 | b.follow_link(text="MIT Touchstone") |
3dae361a AK |
26 | b.select_form("wayfForm1") |
27 | b.submit() | |
28 | b.select_form(predicate=lambda f: any(c.name == 'login_certificate' | |
29 | for c in f.controls)) | |
30 | b.submit() | |
31 | b.select_form(nr=0) | |
32 | b.submit() | |
c3e3cdd9 AK |
33 | b.open("https://jira.mit.edu/jira/sr/jira.issueviews:searchrequest-rss/temp/SearchRequest.xml?&pid=10185&updated%3Aprevious=-1w&sorter/field=updated&sorter/order=DESC&tempMax=1000") |
34 | issues_rss = b.response().read() | |
35 | b.open("https://jira.mit.edu/jira/sr/jira.issueviews:searchrequest-comments-rss/temp/SearchRequest.xml?&pid=10185&updated%3Aprevious=-1w&sorter/field=updated&sorter/order=DESC&tempMax=1000") | |
36 | comments_rss = b.response().read() | |
37 | ||
38 | def parse_issue(e): | |
39 | issue = urlparse.urlparse(e.id)[2].rsplit('/', 1)[1] | |
40 | url = e.id | |
41 | msg = e.id + "\nThis issue was updated." | |
42 | ||
43 | return zephyr.ZNotice( | |
44 | sender=zephyr_sender, | |
45 | auth=False, | |
46 | cls=zephyr_class, | |
47 | instance=issue, | |
48 | fields=[e.title.encode('UTF-8'), msg.encode('UTF-8')], | |
49 | ) | |
50 | ||
51 | def parse_comment(e): | |
52 | url = urlparse.urlunsplit(urlparse.urlparse(e.id)[0:3] + (None,None)) | |
53 | issue = url.rsplit('/', 1)[1] | |
54 | ||
55 | s = cStringIO.StringIO() | |
56 | parser = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter(s))) | |
57 | parser.feed(e.summary.rsplit('<table>', 1)[0]) | |
58 | parser.close() | |
59 | s.seek(0) | |
60 | comment = s.read() | |
61 | ||
62 | msg = e.author + " added a comment:\n" + comment.rstrip() | |
63 | ||
64 | return zephyr.ZNotice( | |
65 | sender=zephyr_sender, | |
66 | auth=False, | |
67 | cls=zephyr_class, | |
68 | instance=issue, | |
69 | fields=[e.title.encode('UTF-8'), msg.encode('UTF-8')], | |
70 | sender='jira', | |
71 | auth=False, | |
72 | ) | |
73 | ||
74 | def zerror(msg): | |
75 | return zephyr.ZNotice( | |
76 | sender=zephyr_sender, | |
77 | auth=False, | |
78 | cls=zephyr_class, | |
79 | instance='jira-error', | |
80 | fields=['Jira bot error', msg.encode('UTF-8')] | |
81 | ) | |
82 | ||
83 | time_file_new = time_file + '.' + ''.join(random.sample(string.letters, 8)) | |
84 | ||
85 | try: | |
86 | os.rename(time_file, time_file_new) | |
87 | except OSError: | |
88 | exit() | |
89 | ||
90 | old_time = int(open(time_file_new).read()) | |
91 | new_time = old_time | |
92 | ||
93 | zephyr.init() | |
94 | zephyrs = [] | |
95 | ||
96 | for (thing, rss, parse) in [('issue', issues_rss, parse_issue), | |
97 | ('comment', comments_rss, parse_comment)]: | |
98 | try: | |
99 | feed = feedparser.parse(rss) | |
100 | for e in feed.entries: | |
101 | t = int(calendar.timegm(e.date_parsed)) | |
102 | if t <= old_time: | |
103 | continue | |
104 | if t > new_time: | |
105 | new_time = t | |
106 | try: | |
107 | z = parse(e) | |
108 | except: | |
109 | z = zerror("Error parsing " + thing + ":\n" + e.id + "\n" + traceback.format_exc()) | |
110 | zephyrs.append((t, z)) | |
111 | except: | |
112 | zephyrs.append((0, zerror("Error parsing " + thing + "s feed:\n" + traceback.format_exc()))) | |
113 | ||
114 | open(time_file_new, 'w').write(str(new_time)) | |
115 | ||
116 | os.rename(time_file_new, time_file) | |
117 | ||
118 | zephyrs.sort(key=lambda tz: tz[0]) | |
119 | for (t, z) in zephyrs: | |
120 | z.send() |