__init__.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. '''
  2. This module contains a flask blueprint for db administration stuff
  3. Templates are self-contained in this directory
  4. '''
  5. from __future__ import print_function
  6. from datetime import datetime, timedelta, time
  7. from collections import defaultdict
  8. from flask import current_app, Blueprint, render_template, jsonify, abort, \
  9. request, redirect, url_for, flash
  10. from larigira.entrypoints_utils import get_avail_entrypoints
  11. from larigira.audiogen import get_audiogenerator
  12. from larigira.timegen_every import FrequencyAlarm
  13. from larigira.timegen import get_timegenerator, timegenerate
  14. from larigira import forms
  15. from larigira.config import get_conf
  16. from .suggestions import get_suggestions
  17. db = Blueprint('db', __name__,
  18. url_prefix=get_conf()['ROUTE_PREFIX'] + '/db',
  19. template_folder='templates')
  20. def request_wants_json():
  21. best = request.accept_mimetypes \
  22. .best_match(['application/json', 'text/html'])
  23. return best == 'application/json' and \
  24. request.accept_mimetypes[best] > \
  25. request.accept_mimetypes['text/html']
  26. def get_model():
  27. return current_app.larigira.controller.monitor.model
  28. @db.route('/')
  29. def home():
  30. return render_template('dbadmin_base.html')
  31. @db.route('/list')
  32. def events_list():
  33. model = current_app.larigira.controller.monitor.model
  34. alarms = tuple(model.get_all_alarms())
  35. events = [(alarm, model.get_actions_by_alarm(alarm))
  36. for alarm in alarms]
  37. return render_template('list.html', events=events)
  38. @db.route('/calendar')
  39. def events_calendar():
  40. model = current_app.larigira.controller.monitor.model
  41. today = datetime.now().date()
  42. maxdays = 30
  43. # {date: {datetime: [(alarm1,actions1), (alarm2,actions2)]}}
  44. days = defaultdict(lambda: defaultdict(list))
  45. freq_threshold = get_conf()['UI_CALENDAR_FREQUENCY_THRESHOLD']
  46. for alarm in model.get_all_alarms():
  47. if freq_threshold and alarm['kind'] == 'frequency' and \
  48. FrequencyAlarm(alarm).interval < freq_threshold:
  49. continue
  50. actions = tuple(model.get_actions_by_alarm(alarm))
  51. if not actions:
  52. continue
  53. t = datetime.fromtimestamp(int(today.strftime('%s')))
  54. for t in timegenerate(alarm, now=t, howmany=maxdays):
  55. if t is None or \
  56. t > datetime.combine(today+timedelta(days=maxdays), time()):
  57. break
  58. days[t.date()][t].append((alarm, actions))
  59. # { weeknum: [day1, day2, day3] }
  60. weeks = defaultdict(list)
  61. for d in sorted(days.keys()):
  62. weeks[d.isocalendar()[:2]].append(d)
  63. return render_template('calendar.html', days=days, weeks=weeks)
  64. @db.route('/add/time')
  65. def addtime():
  66. kinds = get_avail_entrypoints('larigira.timeform_create')
  67. def gen_info(gen):
  68. return dict(description=getattr(gen, 'description', ''))
  69. info = {kind: gen_info(get_timegenerator(kind))
  70. for kind in kinds}
  71. return render_template('add_time.html', kinds=kinds, info=info)
  72. @db.route('/edit/time/<int:alarmid>', methods=['GET', 'POST'])
  73. def edit_time(alarmid):
  74. model = get_model()
  75. timespec = model.get_alarm_by_id(alarmid)
  76. kind = timespec['kind']
  77. Form, receiver = tuple(forms.get_timeform(kind))
  78. form = Form()
  79. if request.method == 'GET':
  80. form.populate_from_timespec(timespec)
  81. if request.method == 'POST' and form.validate():
  82. data = receiver(form)
  83. model.update_alarm(alarmid, data)
  84. model.reload()
  85. return redirect(url_for('db.events_list',
  86. _anchor='event-%d' % alarmid))
  87. return render_template('add_time_kind.html',
  88. form=form,
  89. kind=kind,
  90. mode='edit',
  91. alarmid=alarmid,
  92. )
  93. @db.route('/add/time/<kind>', methods=['GET', 'POST'])
  94. def addtime_kind(kind):
  95. Form, receiver = tuple(forms.get_timeform(kind))
  96. form = Form()
  97. if request.method == 'POST' and form.validate():
  98. data = receiver(form)
  99. eid = get_model().add_alarm(data)
  100. return redirect(url_for('db.edit_event', alarmid=eid))
  101. return render_template('add_time_kind.html',
  102. form=form, kind=kind, mode='add')
  103. @db.route('/add/audio')
  104. def addaudio():
  105. kinds = get_avail_entrypoints('larigira.audioform_create')
  106. def gen_info(gen):
  107. return dict(description=getattr(gen, 'description', ''))
  108. info = {kind: gen_info(get_audiogenerator(kind))
  109. for kind in kinds}
  110. return render_template('add_audio.html', kinds=kinds, info=info)
  111. @db.route('/add/audio/<kind>', methods=['GET', 'POST'])
  112. def addaudio_kind(kind):
  113. Form, receiver = tuple(forms.get_audioform(kind))
  114. form = Form()
  115. if request.method == 'POST' and form.validate():
  116. data = receiver(form)
  117. model = current_app.larigira.controller.monitor.model
  118. eid = model.add_action(data)
  119. return jsonify(dict(inserted=eid, data=data))
  120. return render_template('add_audio_kind.html', form=form, kind=kind,
  121. suggestions=get_suggestions()
  122. )
  123. @db.route('/edit/audio/<int:actionid>', methods=['GET', 'POST'])
  124. def edit_audio(actionid):
  125. model = get_model()
  126. audiospec = model.get_action_by_id(actionid)
  127. kind = audiospec['kind']
  128. Form, receiver = tuple(forms.get_audioform(kind))
  129. form = Form()
  130. if request.method == 'GET':
  131. form.populate_from_audiospec(audiospec)
  132. if request.method == 'POST' and form.validate():
  133. data = receiver(form)
  134. model.update_action(actionid, data)
  135. model.reload()
  136. return redirect(url_for('db.events_list'))
  137. return render_template('add_audio_kind.html',
  138. form=form,
  139. kind=kind,
  140. mode='edit',
  141. suggestions=get_suggestions()
  142. )
  143. @db.route('/edit/event/<alarmid>')
  144. def edit_event(alarmid):
  145. model = current_app.larigira.controller.monitor.model
  146. alarm = model.get_alarm_by_id(int(alarmid))
  147. if alarm is None:
  148. abort(404)
  149. allactions = model.get_all_actions()
  150. actions = tuple(model.get_actions_by_alarm(alarm))
  151. return render_template('edit_event.html',
  152. alarm=alarm, all_actions=allactions,
  153. actions=actions,
  154. routeprefix=get_conf()['ROUTE_PREFIX']
  155. )
  156. @db.route('/api/alarm/<alarmid>/actions', methods=['POST'])
  157. def change_actions(alarmid):
  158. new_actions = request.form.getlist('actions[]')
  159. if new_actions is None:
  160. new_actions = []
  161. model = current_app.larigira.controller.monitor.model
  162. ret = model.update_alarm(int(alarmid),
  163. new_fields={'actions': [int(a) for a in
  164. new_actions]})
  165. return jsonify(dict(updated=alarmid, ret=ret))
  166. @db.route('/api/alarm/<int:alarmid>/delete', methods=['POST'])
  167. def delete_alarm(alarmid):
  168. model = current_app.larigira.controller.monitor.model
  169. try:
  170. alarm = model.get_alarm_by_id(int(alarmid))
  171. print(alarm['nick'])
  172. model.delete_alarm(alarmid)
  173. except KeyError:
  174. abort(404)
  175. if request_wants_json():
  176. return jsonify(dict(deleted=alarmid))
  177. flash('Evento %d `%s` cancellato' % (alarmid, alarm['nick']) )
  178. return redirect(url_for('db.events_list'))