@@ -15,17 +15,16 @@ class Webhook(object):
1515 :param secret: Optional secret, used to authenticate the hook comes from Github
1616 """
1717
18- def __init__ (self , app , endpoint = '/postreceive' , secret = None ):
19- app .add_url_rule (rule = endpoint , endpoint = endpoint , view_func = self ._postreceive ,
20- methods = ['POST' ])
18+ def __init__ (self , app , endpoint = "/postreceive" , secret = None ):
19+ app .add_url_rule (rule = endpoint , endpoint = endpoint , view_func = self ._postreceive , methods = ["POST" ])
2120
2221 self ._hooks = collections .defaultdict (list )
2322 self ._logger = logging .getLogger ('webhook' )
2423 if secret is not None and not isinstance (secret , bytes ):
2524 secret = secret .encode ('utf-8' )
2625 self ._secret = secret
2726
28- def hook (self , event_type = ' push' ):
27+ def hook (self , event_type = " push" ):
2928 """
3029 Registers a function as a hook. Multiple hooks can be registered for a given type, but the
3130 order in which they are invoke is unspecified.
@@ -42,8 +41,7 @@ def decorator(func):
4241 def _get_digest (self ):
4342 """Return message digest if a secret key was provided"""
4443
45- return hmac .new (
46- self ._secret , request .data , hashlib .sha1 ).hexdigest () if self ._secret else None
44+ return hmac .new (self ._secret , request .data , hashlib .sha1 ).hexdigest () if self ._secret else None
4745
4846 def _postreceive (self ):
4947 """Callback from Flask"""
@@ -55,86 +53,76 @@ def _postreceive(self):
5553 if not isinstance (digest , str ):
5654 digest = str (digest )
5755
58- if (len (sig_parts ) < 2 or sig_parts [0 ] != 'sha1'
59- or not hmac .compare_digest (sig_parts [1 ], digest )):
60- abort (400 , 'Invalid signature' )
56+ if len (sig_parts ) < 2 or sig_parts [0 ] != "sha1" or not hmac .compare_digest (sig_parts [1 ], digest ):
57+ abort (400 , "Invalid signature" )
6158
62- event_type = _get_header (' X-Github-Event' )
59+ event_type = _get_header (" X-Github-Event" )
6360 data = request .get_json ()
6461
6562 if data is None :
66- abort (400 , ' Request body must contain json' )
63+ abort (400 , " Request body must contain json" )
6764
68- self ._logger .info (
69- '%s (%s)' , _format_event (event_type , data ), _get_header ('X-Github-Delivery' ))
65+ self ._logger .info ("%s (%s)" , _format_event (event_type , data ), _get_header ("X-Github-Delivery" ))
7066
7167 for hook in self ._hooks .get (event_type , []):
7268 resp = hook (data )
7369 if resp : # Allow hook to respond if necessary
7470 return resp
7571
76- return '' , 204
72+ return "" , 204
73+
7774
7875def _get_header (key ):
7976 """Return message header"""
8077
8178 try :
8279 return request .headers [key ]
8380 except KeyError :
84- abort (400 , 'Missing header: ' + key )
81+ abort (400 , "Missing header: " + key )
82+
8583
8684EVENT_DESCRIPTIONS = {
87- 'commit_comment' : '{comment[user][login]} commented on '
88- '{comment[commit_id]} in {repository[full_name]}' ,
89- 'create' : '{sender[login]} created {ref_type} ({ref}) in '
90- '{repository[full_name]}' ,
91- 'delete' : '{sender[login]} deleted {ref_type} ({ref}) in '
92- '{repository[full_name]}' ,
93- 'deployment' : '{sender[login]} deployed {deployment[ref]} to '
94- '{deployment[environment]} in {repository[full_name]}' ,
95- 'deployment_status' : 'deployment of {deployement[ref]} to '
96- '{deployment[environment]} '
97- '{deployment_status[state]} in '
98- '{repository[full_name]}' ,
99- 'fork' : '{forkee[owner][login]} forked {forkee[name]}' ,
100- 'gollum' : '{sender[login]} edited wiki pages in {repository[full_name]}' ,
101- 'issue_comment' : '{sender[login]} commented on issue #{issue[number]} '
102- 'in {repository[full_name]}' ,
103- 'issues' : '{sender[login]} {action} issue #{issue[number]} in '
104- '{repository[full_name]}' ,
105- 'member' : '{sender[login]} {action} member {member[login]} in '
106- '{repository[full_name]}' ,
107- 'membership' : '{sender[login]} {action} member {member[login]} to team '
108- '{team[name]} in {repository[full_name]}' ,
109- 'page_build' : '{sender[login]} built pages in {repository[full_name]}' ,
110- 'ping' : 'ping from {sender[login]}' ,
111- 'public' : '{sender[login]} publicized {repository[full_name]}' ,
112- 'pull_request' : '{sender[login]} {action} pull #{pull_request[number]} in '
113- '{repository[full_name]}' ,
114- 'pull_request_review' : '{sender[login]} {action} {review[state]} review on pull #{pull_request[number]} in '
115- '{repository[full_name]}' ,
116- 'pull_request_review_comment' : '{comment[user][login]} {action} comment '
117- 'on pull #{pull_request[number]} in '
118- '{repository[full_name]}' ,
119- 'push' : '{pusher[name]} pushed {ref} in {repository[full_name]}' ,
120- 'release' : '{release[author][login]} {action} {release[tag_name]} in '
121- '{repository[full_name]}' ,
122- 'repository' : '{sender[login]} {action} repository '
123- '{repository[full_name]}' ,
124- 'status' : '{sender[login]} set {sha} status to {state} in '
125- '{repository[full_name]}' ,
126- 'team_add' : '{sender[login]} added repository {repository[full_name]} to '
127- 'team {team[name]}' ,
128- 'watch' : '{sender[login]} {action} watch in repository '
129- '{repository[full_name]}'
85+ "commit_comment" : "{comment[user][login]} commented on " "{comment[commit_id]} in {repository[full_name]}" ,
86+ "create" : "{sender[login]} created {ref_type} ({ref}) in " "{repository[full_name]}" ,
87+ "delete" : "{sender[login]} deleted {ref_type} ({ref}) in " "{repository[full_name]}" ,
88+ "deployment" : "{sender[login]} deployed {deployment[ref]} to "
89+ "{deployment[environment]} in {repository[full_name]}" ,
90+ "deployment_status" : "deployment of {deployement[ref]} to "
91+ "{deployment[environment]} "
92+ "{deployment_status[state]} in "
93+ "{repository[full_name]}" ,
94+ "fork" : "{forkee[owner][login]} forked {forkee[name]}" ,
95+ "gollum" : "{sender[login]} edited wiki pages in {repository[full_name]}" ,
96+ "issue_comment" : "{sender[login]} commented on issue #{issue[number]} " "in {repository[full_name]}" ,
97+ "issues" : "{sender[login]} {action} issue #{issue[number]} in " "{repository[full_name]}" ,
98+ "member" : "{sender[login]} {action} member {member[login]} in " "{repository[full_name]}" ,
99+ "membership" : "{sender[login]} {action} member {member[login]} to team " "{team[name]} in {repository[full_name]}" ,
100+ "page_build" : "{sender[login]} built pages in {repository[full_name]}" ,
101+ "ping" : "ping from {sender[login]}" ,
102+ "public" : "{sender[login]} publicized {repository[full_name]}" ,
103+ "pull_request" : "{sender[login]} {action} pull #{pull_request[number]} in " "{repository[full_name]}" ,
104+ "pull_request_review" : "{sender[login]} {action} {review[state]} "
105+ "review on pull #{pull_request[number]} in "
106+ "{repository[full_name]}" ,
107+ "pull_request_review_comment" : "{comment[user][login]} {action} comment "
108+ "on pull #{pull_request[number]} in "
109+ "{repository[full_name]}" ,
110+ "push" : "{pusher[name]} pushed {ref} in {repository[full_name]}" ,
111+ "release" : "{release[author][login]} {action} {release[tag_name]} in " "{repository[full_name]}" ,
112+ "repository" : "{sender[login]} {action} repository " "{repository[full_name]}" ,
113+ "status" : "{sender[login]} set {sha} status to {state} in " "{repository[full_name]}" ,
114+ "team_add" : "{sender[login]} added repository {repository[full_name]} to " "team {team[name]}" ,
115+ "watch" : "{sender[login]} {action} watch in repository " "{repository[full_name]}" ,
130116}
131117
118+
132119def _format_event (event_type , data ):
133120 try :
134121 return EVENT_DESCRIPTIONS [event_type ].format (** data )
135122 except KeyError :
136123 return event_type
137124
125+
138126# -----------------------------------------------------------------------------
139127# Copyright 2015 Bloomberg Finance L.P.
140128#
0 commit comments