forked from pcapriotti/github-trac
-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathgithub.py
More file actions
132 lines (96 loc) · 4.77 KB
/
Copy pathgithub.py
File metadata and controls
132 lines (96 loc) · 4.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from trac.core import *
from trac.config import Option, IntOption, ListOption, BoolOption
from trac.web.api import IRequestFilter, IRequestHandler, Href
from trac.util.translation import _
from trac.web.api import parse_query_string
from hook import CommitHook
import simplejson
from git import Git
class GithubPlugin(Component):
implements(IRequestHandler, IRequestFilter)
key = Option('github', 'apitoken', '', doc="""Your GitHub API Token found here: https://github.com/account, """)
closestatus = Option('github', 'closestatus', '', doc="""This is the status used to close a ticket. It defaults to closed.""")
browser = Option('github', 'browser', '', doc="""Place your GitHub Source Browser URL here to have the /browser entry point redirect to GitHub.""")
autofetch = Option('github', 'autofetch', '', doc="""Should we auto fetch the repo when we get a commit hook from GitHub.""")
branches = Option('github', 'branches', "all", doc="""Restrict commit hook to these branches. """
"""Defaults to special value 'all', do not restrict commit hook""")
comment_template = Option('github', 'comment_template', "Changeset: {commit[id]}", doc="""This will be appended to your commit message and used as trac comment""")
repo = Option('trac', 'repository_dir', '', doc="""This is your repository dir""")
def __init__(self):
self.hook = CommitHook(self.env, self.comment_template)
self.env.log.debug("API Token: %s" % self.key)
self.env.log.debug("Browser: %s" % self.browser)
self.processHook = False
# IRequestHandler methods
def match_request(self, req):
self.env.log.debug("Match Request")
serve = req.path_info.rstrip('/') == ('/github/%s' % self.key) and req.method == 'POST'
if serve:
self.processHook = True
#This is hacky but it's the only way I found to let Trac post to this request
# without a valid form_token
req.form_token = None
self.env.log.debug("Handle Request: %s" % serve)
return serve
def process_request(self, req):
if self.processHook:
self.processCommitHook(req)
# This has to be done via the pre_process_request handler
# Seems that the /browser request doesn't get routed to match_request :(
def pre_process_request(self, req, handler):
if self.browser:
serve = req.path_info.startswith('/browser')
self.env.log.debug("Handle Pre-Request /browser: %s" % serve)
if serve:
self.processBrowserURL(req)
serve2 = req.path_info.startswith('/changeset')
self.env.log.debug("Handle Pre-Request /changeset: %s" % serve2)
if serve2:
self.processChangesetURL(req)
return handler
def post_process_request(self, req, template, data, content_type):
return (template, data, content_type)
def processChangesetURL(self, req):
self.env.log.debug("processChangesetURL")
browser = self.browser.replace('/tree/master', '/commit/')
url = req.path_info.replace('/changeset/', '')
if not url:
browser = self.browser
url = ''
redirect = '%s%s' % (browser, url)
self.env.log.debug("Redirect URL: %s" % redirect)
out = 'Going to GitHub: %s' % redirect
req.redirect(redirect)
def processBrowserURL(self, req):
self.env.log.debug("processBrowserURL")
browser = self.browser.replace('/master', '/')
rev = req.args.get('rev')
url = req.path_info.replace('/browser', '')
if not rev:
rev = ''
redirect = '%s%s%s' % (browser, rev, url)
self.env.log.debug("Redirect URL: %s" % redirect)
out = 'Going to GitHub: %s' % redirect
req.redirect(redirect)
def processCommitHook(self, req):
self.env.log.debug("processCommitHook")
status = self.closestatus
if not status:
status = 'closed'
data = req.args.get('payload')
branches = (parse_query_string(req.query_string).get('branches') or self.branches).split(',')
self.env.log.debug("Using branches: %s", branches)
if data:
jsondata = simplejson.loads(data)
ref = jsondata['ref'].split('/')[-1]
if ref in branches or 'all' in branches:
for i in jsondata['commits']:
self.hook.process(i, status, jsondata)
else:
self.env.log.debug("Not running hook, ref %s is not in %s", ref, branches)
if self.autofetch:
repo = Git(self.repo)
try:
repo.execute(['git', 'fetch'])
except:
self.env.log.debug("git fetch failed!")