]> andersk Git - jira-zephyrbot.git/blame - jirabot.py
Warn about failures to acquire the lock instead of exiting.
[jira-zephyrbot.git] / jirabot.py
CommitLineData
c3e3cdd9
AK
1#!/usr/bin/python
2import cStringIO
3import calendar
4import feedparser
5import formatter
6import htmllib
a41187bd 7import mechanize
c3e3cdd9
AK
8import os
9import random
10import string
11import time
12import traceback
13import urlparse
14import zephyr
15
16zephyr_sender = 'jira'
17zephyr_class = 'andersk-test'
18time_file = 'jirabot.time'
a41187bd 19
8b8cecc4
AK
20def jira_init():
21 b = mechanize.Browser()
22 b.set_handle_robots(False)
23 b.add_client_certificate("https://idp.mit.edu:9443", "cert.pem", "cert.pem")
24 b.addheaders = [("Accept-Language", "en-us,en;q=0.5"),]
25 return b
26
27def jira_login(b):
28 b.open("https://jira.mit.edu/jira/secure/Dashboard.jspa")
0ebeacca
AK
29 try:
30 b.follow_link(text="MIT Touchstone")
31 except mechanize.LinkNotFoundError:
32 return
33 if (urlparse.urlparse(b.geturl())[1] == "jira.mit.edu"):
34 return
8b8cecc4
AK
35 b.select_form("wayfForm1")
36 b.submit()
37 b.select_form(predicate=lambda f: any(c.name == 'login_certificate'
38 for c in f.controls))
39 b.submit()
40 b.select_form(nr=0)
41 b.submit()
c3e3cdd9 42
0344134a
AK
43def feed_to_zephyrs(thing, rss, parse):
44 zephyrs = []
45 try:
46 feed = feedparser.parse(rss)
47 for e in feed.entries:
48 global old_time, new_time
49 t = int(calendar.timegm(e.date_parsed))
50 if t <= old_time:
51 continue
52 if t > new_time:
53 new_time = t
54 try:
55 z = parse(e)
56 except:
57 z = zerror("Error parsing " + thing + ":\n" + e.id + "\n" + traceback.format_exc())
58 zephyrs.append((t, z))
59 except:
60 zephyrs.append((0, zerror("Error parsing " + thing + "s feed:\n" + traceback.format_exc())))
61 return zephyrs
62
c3e3cdd9
AK
63def parse_issue(e):
64 issue = urlparse.urlparse(e.id)[2].rsplit('/', 1)[1]
65 url = e.id
66 msg = e.id + "\nThis issue was updated."
67
68 return zephyr.ZNotice(
69 sender=zephyr_sender,
70 auth=False,
71 cls=zephyr_class,
72 instance=issue,
7f50f108 73 fields=[e.title, msg],
c3e3cdd9
AK
74 )
75
76def parse_comment(e):
77 url = urlparse.urlunsplit(urlparse.urlparse(e.id)[0:3] + (None,None))
78 issue = url.rsplit('/', 1)[1]
79
80 s = cStringIO.StringIO()
81 parser = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter(s)))
82 parser.feed(e.summary.rsplit('<table>', 1)[0])
83 parser.close()
84 s.seek(0)
85 comment = s.read()
86
87 msg = e.author + " added a comment:\n" + comment.rstrip()
88
89 return zephyr.ZNotice(
90 sender=zephyr_sender,
91 auth=False,
92 cls=zephyr_class,
93 instance=issue,
7f50f108 94 fields=[e.title, msg],
c3e3cdd9
AK
95 )
96
97def zerror(msg):
98 return zephyr.ZNotice(
99 sender=zephyr_sender,
100 auth=False,
101 cls=zephyr_class,
102 instance='jira-error',
7f50f108 103 fields=['Jira bot error', msg]
c3e3cdd9
AK
104 )
105
8b8cecc4 106b = jira_init()
8bf2b029 107zephyr.init()
8b8cecc4 108
8bf2b029
AK
109while True:
110 jira_login(b)
111 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")
112 issues_rss = b.response().read()
113 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")
114 comments_rss = b.response().read()
8b8cecc4 115
8bf2b029 116 time_file_new = time_file + '.' + ''.join(random.sample(string.letters, 8))
c3e3cdd9 117
8bf2b029
AK
118 try:
119 os.rename(time_file, time_file_new)
120 except OSError:
4311bd26
AK
121 print "warning: could not acquire timestamp lock"
122 time.sleep(17)
123 continue
c3e3cdd9 124
8bf2b029
AK
125 old_time = int(open(time_file_new).read())
126 new_time = old_time
c3e3cdd9 127
8bf2b029
AK
128 zephyrs = (feed_to_zephyrs('issue', issues_rss, parse_issue) +
129 feed_to_zephyrs('comment', comments_rss, parse_comment))
c3e3cdd9 130
8bf2b029 131 open(time_file_new, 'w').write(str(new_time))
c3e3cdd9 132
8bf2b029 133 os.rename(time_file_new, time_file)
c3e3cdd9 134
8bf2b029
AK
135 zephyrs.sort(key=lambda tz: tz[0])
136 for (t, z) in zephyrs:
137 z.send()
138 time.sleep(60)
This page took 0.336473 seconds and 5 git commands to generate.