-
Notifications
You must be signed in to change notification settings - Fork 0
/
webhook.py
executable file
·142 lines (120 loc) · 3.65 KB
/
webhook.py
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
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python2
import os, json
try:
import yaml
from sh import pwd, cd, ErrorReturnCode_128
from flask import Flask, request, abort
except ImportError as e:
e.message = "Could not import the required libraries. Have you `pip install -r requirements.txt`d them?"
"""last-ditch: is there a virtualenv to activate?"""
activated = False
import os, glob
venv_shots = glob.glob(os.path.join('*', 'bin', 'activate_this.py'))
for shot in venv_shots:
try:
import imp
imp.load_source('activate_this', shot)
activated = True
break
except IOError:
pass
if activated:
try:
import yaml
from sh import pwd, cd, ErrorReturnCode_128
from flask import Flask, request, abort
except ImportError:
raise e
else:
raise e
try:
from sh import git
except ImportError as e:
e.message = "You need to have git installed to use this tool"
raise e
def load_config(config_file='config.yaml'):
try:
with open(config_file) as f:
config = yaml.load(f)
except IOError as e:
e.message = "could not read config file `config.yaml`. ... ... ??"
raise e
try:
host, port = config['listen']['host'], config['listen']['port']
repositories = config['repositories']
if not all('path' in r for r in repositories.values()):
raise KeyError('at least one repository is missing a url')
except KeyError as e:
e.message = 'bad config format'
raise e
return (host, port), repositories
def pull(url, path, remote=None):
here = str(pwd()).strip()
try:
cd(path)
except OSError:
print "path does not exist? {}".format(path)
cd(here)
return
try:
git.status()
except ErrorReturnCode_128:
print "{} is not a git repository!".format(path)
cd(here)
return
git.pull(remote or url, 'master')
git.checkout('-f')
cd(here)
def hookify(app, repositories):
@app.route('/', methods=['GET', 'POST'])
def hook():
try:
payload = json.loads(request.form['payload'])
url = payload['repository']['url']
except KeyError:
print "Bad Request!"
abort(400)
print 'heyheyhey'
try:
repo_config = repositories[url]
except KeyError:
print "Repository not in config"
abort(404)
pull(url, **repo_config)
return 'cool cool'
return app
def gunicornify(app, host, port):
return glapp
def run_flask(app, host, port):
app.run(host=host, port=port)
def run_gunicorn(app, host, port):
try:
from gunicorn.app.base import Application
from gunicorn.config import Config
except:
print "warning: couldn't import gunicorn -- running flask dev server"
run_flask(app, host, port)
return
class Glapp(Application):
def init(self, *start):
pass
def load(self):
return app
glapp = Glapp()
gonfig = Config()
gonfig.set('bind', '{}{}'.format(host, ':{}'.format(port) if port else ''))
glapp.cfg = gonfig
glapp.run()
if __name__ == '__main__':
import sys
(host, port), repositories = load_config()
flapp = Flask(__name__)
hookify(flapp, repositories)
server = sys.argv[1] if len(sys.argv) > 1 else 'gunicorn'
if server == 'gunicorn':
run_gunicorn(flapp, host, port)
elif server == 'debug':
flapp.debug = True
run_flask(flapp, host, port)
else:
run_flask(flapp, host, port)