This is Pluto, the webhook server.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pluto.py 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import time,string
  2. from flask import Flask, render_template, redirect, url_for, request, g, make_response
  3. from model import *
  4. from util import *
  5. app = Flask('pluto')
  6. app.debug = True
  7. @app.before_request
  8. def init_globals():
  9. for cls in type.__subclasses__(DBObject):
  10. setattr(g, cls.__name__, cls)
  11. app.jinja_env.filters['ctime'] = time.ctime
  12. app.jinja_env.filters['jloads'] = jloads
  13. app.jinja_env.filters['hloads'] = header_loads
  14. app.jinja_env.filters['split'] = string.split
  15. app.jinja_env.globals['safe_load'] = safe_load
  16. @app.errorhandler(404)
  17. def error_404(error):
  18. return render_template('404.html', entity='page'), 404
  19. @app.route('/')
  20. def root():
  21. return render_template('index.html')
  22. @app.route('/hook', methods=['GET', 'POST'])
  23. def hook():
  24. response = make_response(render_template('api_hit.txt'))
  25. response.headers['Content-type'] = 'text/json'
  26. triggered = filter(lambda hook: hook.trigger(request.path, request.headers, jloads(request.data), response), Hook.all())
  27. Log.create(time.time(), request.path, header_dumps(request.headers), request.data, ','.join(str(hook.rowid) for hook in triggered))
  28. return response
  29. @app.route('/logs')
  30. def logs():
  31. n = request.values.get('n', 10)
  32. return render_template('logs.html', logs=Log.most_recent(n), n=n)
  33. @app.route('/debuglogs', methods=['GET', 'POST'])
  34. def debuglogs():
  35. n = request.values.get('n', 10)
  36. return render_template('debuglogs.html', logs=DebugLog.most_recent(n), n=n)
  37. @app.route('/hooks')
  38. def hooks():
  39. return render_template('hooks.html', hooks=Hook.all())
  40. @app.route('/hooks/new', methods=['GET', 'POST'])
  41. def hooks_new():
  42. if request.method == 'POST':
  43. hook = Hook.create(
  44. request.values['name'], None, # FIXME no author yet
  45. checkbox(request, 'disabled'),
  46. checkbox(request, 'debugged'),
  47. )
  48. return redirect('/hook/%d'%(hook.rowid,))
  49. return render_template('hooks_new.html')
  50. @app.route('/hook/<int:hookid>')
  51. def hook_obj(hookid):
  52. try:
  53. hook = Hook.get_one(rowid=hookid)
  54. except NoSuchEntity:
  55. return render_template('404.html', entity='hook'), 404
  56. except TooManyEntities:
  57. return render_template('500.html', cause='too many hooks'), 500
  58. return render_template('hook.html', hook=hook)
  59. @app.route('/hook/<int:hookid>/edit', methods=['GET', 'POST'])
  60. def hook_edit(hookid):
  61. try:
  62. hook = Hook.get_one(rowid=hookid)
  63. except NoSuchEntity:
  64. return render_template('404.html', entity='hook'), 404
  65. except TooManyEntities:
  66. return render_template('500.html', cause='too many hooks'), 500
  67. if request.method == 'POST':
  68. hook.name = request.values['name']
  69. hook.disabled = checkbox(request, 'disabled')
  70. hook.debugged = checkbox(request, 'debugged')
  71. hook.update()
  72. return redirect('/hook/%d'%(hook.rowid,))
  73. return render_template('hook_edit.html', hook=hook)
  74. @app.route('/hook/<int:hookid>/newcond', methods=['GET', 'POST'])
  75. def hook_new_cond(hookid):
  76. try:
  77. hook = Hook.get_one(rowid=hookid)
  78. except NoSuchEntity:
  79. return render_template('404.html', entity='hook'), 404
  80. except TooManyEntities:
  81. return render_template('500.html', cause='too many hooks'), 500
  82. if request.method == 'POST':
  83. cond = Condition.create(
  84. hook.rowid,
  85. request.values['selector'], request.values['s1'], request.values['s2'], request.values['s3'],
  86. request.values['test'], request.values['t1'], request.values['t2'], request.values['t3'],
  87. checkbox(request, 'invert'),
  88. )
  89. return redirect('/cond/%d'%(cond.rowid,))
  90. return render_template('hook_new_cond.html', hook=hook)
  91. @app.route('/hook/<int:hookid>/newact', methods=['GET', 'POST'])
  92. def hook_new_act(hookid):
  93. try:
  94. hook = Hook.get_one(rowid=hookid)
  95. except NoSuchEntity:
  96. return render_template('404.html', entity='hook'), 404
  97. except TooManyEntities:
  98. return render_template('500.html', cause='too many hooks'), 500
  99. if request.method == 'POST':
  100. act = Action.create(
  101. hook.rowid,
  102. request.values['action'], request.values['a1'], request.values['a2'], request.values['a3'],
  103. )
  104. return redirect('/act/%d'%(act.rowid,))
  105. return render_template('hook_new_act.html', hook=hook)
  106. @app.route('/hook/<int:hookid>/delete', methods=['GET', 'POST'])
  107. def hook_delete(hookid):
  108. try:
  109. hook = Hook.get_one(rowid=hookid)
  110. except NoSuchEntity:
  111. return render_template('404.html', entity='hook'), 404
  112. except TooManyEntities:
  113. return render_template('500.html', cause='too many hooks'), 500
  114. if request.method == 'POST':
  115. hook.delete()
  116. return redirect(url_for('hooks'))
  117. return render_template('hook_delete.html', hook=hook)
  118. @app.route('/cond/<int:condid>')
  119. def cond_obj(condid):
  120. try:
  121. cond = Condition.get_one(rowid=condid)
  122. except NoSuchEntity:
  123. return render_template('404.html', entity='condition'), 404
  124. except TooManyEntities:
  125. return render_template('500.html', cause='too many conditions'), 500
  126. return render_template('cond.html', cond=cond)
  127. @app.route('/cond/<int:condid>/edit', methods=['GET', 'POST'])
  128. def cond_edit(condid):
  129. try:
  130. cond = Condition.get_one(rowid=condid)
  131. except NoSuchEntity:
  132. return render_template('404.html', entity='condition'), 404
  133. except TooManyEntities:
  134. return render_template('500.html', cause='too many conditions'), 500
  135. if request.method == 'POST':
  136. cond.selector = request.values['selector']
  137. cond.s1 = request.values['s1']
  138. cond.s2 = request.values['s2']
  139. cond.s3 = request.values['s3']
  140. cond.test = request.values['test']
  141. cond.t1 = request.values['t1']
  142. cond.t2 = request.values['t2']
  143. cond.t3 = request.values['t3']
  144. cond.invert = checkbox(request, 'invert')
  145. cond.update()
  146. return redirect('/cond/%d'%(cond.rowid,))
  147. return render_template('cond_edit.html', cond=cond)
  148. @app.route('/cond/<int:condid>/delete', methods=['GET', 'POST'])
  149. def cond_delete(condid):
  150. try:
  151. cond = Condition.get_one(rowid=condid)
  152. except NoSuchEntity:
  153. return render_template('404.html', entity='condition'), 404
  154. except TooManyEntities:
  155. return render_template('500.html', cause='too many conditions'), 500
  156. if request.method == 'POST':
  157. cond.delete()
  158. return redirect('/hook/%d'%(cond.hook,))
  159. return render_template('cond_delete.html', cond=cond)
  160. @app.route('/act/<int:actid>')
  161. def act_obj(actid):
  162. try:
  163. act = Action.get_one(rowid=actid)
  164. except NoSuchEntity:
  165. return render_template('404.html', entity='action'), 404
  166. except TooManyEntities:
  167. return render_template('500.html', cause='too many actions'), 500
  168. return render_template('act.html', act=act)
  169. @app.route('/act/<int:actid>/edit', methods=['GET', 'POST'])
  170. def act_edit(actid):
  171. try:
  172. act = Action.get_one(rowid=actid)
  173. except NoSuchEntity:
  174. return render_template('404.html', entity='action'), 404
  175. except TooManyEntities:
  176. return render_template('500.html', cause='too many actions'), 500
  177. if request.method == 'POST':
  178. act.action = request.values['action']
  179. act.a1 = request.values['a1']
  180. act.a2 = request.values['a2']
  181. act.a3 = request.values['a3']
  182. act.update()
  183. return redirect('/act/%d'%(act.rowid,))
  184. return render_template('act_edit.html', act=act)
  185. @app.route('/act/<int:actid>/delete', methods=['GET', 'POST'])
  186. def act_delete(actid):
  187. try:
  188. act = Action.get_one(rowid=actid)
  189. except NoSuchEntity:
  190. return render_template('404.html', entity='action'), 404
  191. except TooManyEntities:
  192. return render_template('500.html', cause='too many actions'), 500
  193. if request.method == 'POST':
  194. act.delete()
  195. return redirect('/hook/%d'%(act.hook,))
  196. return render_template('act_delete.html', act=act)
  197. if __name__ == '__main__':
  198. app.run(host='0.0.0.0', port=8080)