from flask import Flask, request, render_template import json from pathlib import Path from form_content import FormContent app = Flask(__name__) save_path = Path('data.txt') all_keys = set(FormContent.times | FormContent.topics | FormContent.languages) | { 'name', 'email', 'topic-other' } def get_data_stats() -> dict: data = {} summed = { key: { 'sum': 0, 'total': 0, 'percent': 0 } for key in all_keys } summed['topic-other'] = set() if save_path.exists(): for raw_line in save_path.read_text().split('\n'): if raw_line: line = json.loads(raw_line) data[line['email']] = line for line in data.values(): for key, value in dict.items(line): if key == 'topic-other' and value is not None: summed['topic-other'] = summed['topic-other'] | { value } if type(value) is bool: sum = summed[key]['sum'] if key in summed else 0 sum = sum + 1 if value is True else sum total = summed[key]['total'] + 1 if key in summed else 1 summed[key] = { 'sum': sum, 'total': total, 'percent': f'{((sum / total) * 100):.1f}' } summed['topic-other'] = list(summed['topic-other']) return summed stats_cache = (0, get_data_stats()) @app.route('/') def form(): return render_template('form.html', times=FormContent.times, topics=FormContent.topics, languages=FormContent.languages) @app.route('/submit', methods=['POST']) def submit(): if save_path.exists() and save_path.stat().st_size > 1_000_000: return { 'error': 'Database full.' }, 500 if len(request.data) > 1000: return { 'error': 'Request too long.' }, 400 data = request.get_json() if set(data) != all_keys: return { 'error': 'Invalid request format.' }, 400 with save_path.open(mode='a') as file: file.write(f'{json.dumps(data)}\n') return {}, 200 @app.route('/stats') def stats(): global stats_cache if save_path.exists() and save_path.stat().st_mtime > stats_cache[0]: stats_cache = (save_path.stat().st_mtime, get_data_stats()) return render_template('stats.html', times=FormContent.times, topics=FormContent.topics, languages=FormContent.languages, data=stats_cache[1]) if __name__ == '__main__': app.run(host='0.0.0.0', port=9700, debug=False)