Coverage for application / main.py: 33%
49 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-07 06:46 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-07 06:46 +0000
1import traceback
2from concurrent.futures import ThreadPoolExecutor, as_completed
3from json import JSONDecodeError
5from flask import flash, render_template, request, session
7from application import app
8from application.vars.annosaurus import *
11@app.route('/favicon.ico')
12def favicon():
13 return app.send_static_file('img/favicon.ico')
16@app.route('/')
17def index():
18 def fetch_json(url, headers=None):
19 try:
20 res = requests.get(url, headers=headers)
21 res.raise_for_status()
22 return res.json()
23 except requests.exceptions.RequestException as e:
24 print(f'\nERROR: failed to fetch {url}: {e}\n')
25 flash(f'Unable to connect to {url}', 'danger')
26 except JSONDecodeError:
27 print(f'\nERROR: failed to parse JSON from {url}\n')
28 return None
30 http_requests = [
31 dict(name='reviewers', url=f'{app.config["DARC_REVIEW_URL"]}/reviewer/all', headers=app.config['DARC_REVIEW_HEADERS']),
32 dict(name='stats', url=f'{app.config["DARC_REVIEW_URL"]}/stats', headers=app.config['DARC_REVIEW_HEADERS']),
33 dict(name='sequences', url=app.config['VARS_SEQUENCE_LIST_URL']),
34 dict(name='concepts', url=app.config['VARS_CONCEPT_LIST_URL'])
35 ]
36 results = {}
37 with ThreadPoolExecutor(max_workers=4) as executor:
38 futures = {
39 executor.submit(fetch_json, url=item['url'], headers=item.get('headers')): item['name']
40 for item in http_requests
41 }
42 for future in as_completed(futures):
43 name = futures[future]
44 results[name] = future.result()
46 stats = results.get('stats') or {}
47 session['reviewers'] = results.get('reviewers') or []
48 session['vars_video_sequences'] = results.get('sequences') or []
49 session['vars_concepts'] = results.get('concepts') or []
51 return render_template(
52 'index.html',
53 sequences=session['vars_video_sequences'],
54 unread_comment_count=stats.get('unread_comments', 0),
55 read_comment_count=stats.get('read_comments', 0),
56 total_comment_count=stats.get('total_comments', 0),
57 active_reviewers=stats.get('active_reviewers', []),
58 )
61# video player
62@app.get('/video')
63def video():
64 data = {'link': request.args.get('link'), 'time': request.args.get('time')}
65 return render_template('video.html', data=data), 200
68@app.errorhandler(404)
69def page_not_found(e):
70 return render_template('errors/404.html', err=''), 404
73@app.errorhandler(Exception)
74def server_error(e):
75 error = f'{type(e).__name__}: {e}'
76 print('\nApplication error 😔')
77 print(error)
78 print(traceback.format_exc())
79 requests.post(
80 url=f'{app.config.get("DARC_REVIEW_URL")}/log-error',
81 headers=app.config.get('DARC_REVIEW_HEADERS'),
82 json={'error': traceback.format_exc()},
83 )
84 return render_template('errors/500.html', err=error), 500