def snapshot(season_id, episode_id, ms): # Load PNG from database. cur = get_db().cursor() cur.execute( 'SELECT png FROM snapshot' ' WHERE episode_id=:episode_id AND ms=:ms', { 'episode_id': episode_id, 'ms': ms }) res = cur.fetchone() if res is None: flask.abort(404, 'time not found') image = Image.open(io.BytesIO(res['png'])) # Draw text if requested. top_text = (b64decode(flask.request.args.get('topb64', '')).decode( 'ascii', 'ignore')) bottom_text = (b64decode(flask.request.args.get('btmb64', '')).decode( 'ascii', 'ignore')) if top_text != '' or bottom_text != '': drawtext(image, top_text, bottom_text) # Return as compressed JPEG. res = io.BytesIO() image.save(res, 'jpeg', quality=JPEG_QUALITY) return flask.Response(res.getvalue(), mimetype='image/jpeg')
def browse_episode(season_id, episode_id): cur = get_db().cursor() targs = {} # Retrieve season information. cur.execute('SELECT slug, icon_png, name FROM season WHERE id=:season_id', {'season_id': season_id}) res = cur.fetchone() targs['season'] = res['slug'] targs['season_name'] = res['name'] targs['season_has_icon'] = res['icon_png'] is not None # Retrieve episode information. cur.execute('SELECT slug, name FROM episode WHERE id=:episode_id', {'episode_id': episode_id}) res = cur.fetchone() targs['episode'] = res['slug'] targs['episode_name'] = res['name'] # Retrieve all subtitles. cur.execute( 'SELECT start_ms, end_ms, snapshot_ms, content FROM subtitle ' ' WHERE episode_id=:episode_id ORDER BY start_ms', {'episode_id': episode_id}) res = cur.fetchall() if len(res) == 0: flask.abort(404, 'no subtitles found') targs['subtitles'] = res def str_ms(ms): return strftimecode(timedelta(milliseconds=ms)) targs['str_ms'] = str_ms return flask.render_template('episode.html', **targs)
def search(): query = flask.request.args.get('q') if query is None: query = '' query = unquote(query) query = re.sub(r'[^a-zA-Z0-9 \']', '', query) query = query[0:MAX_SEARCH_LENGTH] if query == '': return flask.render_template('search.html', query='') cur = get_db().cursor() cur.execute('PRAGMA full_column_names = ON') cur.execute( ' SELECT episode.slug, season.slug, search.snapshot_ms, search.content ' ' FROM season ' 'INNER JOIN episode ON episode.season_id = season.id ' 'INNER JOIN (SELECT episode_id, snapshot_ms, content FROM subtitle_search ' ' WHERE content MATCH :query LIMIT :n_results) search ' ' ON search.episode_id = episode.id', { 'query': ' '.join('"%s"' % term for term in query.split()), 'n_results': N_SEARCH_RESULTS }) results = cur.fetchall() return flask.render_template('search.html', query=query, results=results, n_results=len(results))
def check_time(episode_id, ms): cur = get_db().cursor() cur.execute( 'SELECT ms FROM snapshot WHERE episode_id=:episode_id AND ms=:ms', { 'episode_id': episode_id, 'ms': ms }) return cur.fetchone() is not None
def read_library_command(): database.remove() db = database.get_db() with current_app.open_resource('schema.sql', mode='r') as f: db.cursor().executescript(f.read()) db.commit() library_data = load_library_file(Path(current_app.config.get('LIBRARY'))) database.populate(library_data)
def check_range(episode_id, ms1, ms2, max_length): if ms1 >= ms2 or ms1 < 0 or ms2 - ms1 > max_length.total_seconds() * 1000: return False else: cur = get_db().cursor() cur.execute('SELECT duration FROM episode WHERE id=:episode_id', {'episode_id': episode_id}) res = cur.fetchone() return (ms2 <= res['duration'] and check_time(episode_id, ms1) and check_time(episode_id, ms2))
def snapshot_tiny(season_id, episode_id, ms): cur = get_db().cursor() cur.execute( 'SELECT jpeg FROM snapshot_tiny ' ' WHERE episode_id=:episode_id AND ms=:ms', { 'episode_id': episode_id, 'ms': ms }) res = cur.fetchone() if res is None: flask.abort(404, 'time not found') return flask.Response(res['jpeg'], mimetype='image/jpeg')
def webm(season_id, episode_id, ms1, ms2): if not check_range(episode_id, ms1, ms2, flask.current_app.config.get('MAX_WEBM_LENGTH')): flask.abort(400, 'bad time range') cur = get_db().cursor() cur.execute('SELECT video_path FROM episode WHERE id=:episode_id', {'episode_id': episode_id}) res = cur.fetchone() video_path = res['video_path'] return flask.Response(ff.make_webm(video_path, ms1, ms2), mimetype='video/webm')
def season_icon(season_id): cur = get_db().cursor() # Retrieve season information. cur.execute('SELECT icon_png FROM season WHERE id=:season_id', {'season_id': season_id}) res = cur.fetchone() icon_data = res['icon_png'] if icon_data is None: flask.abort(404, 'no icon available') # Return icon. response = flask.make_response(icon_data) response.headers.set('Content-Type', 'image/png') return response
def gif_with_subtitles(season_id, episode_id, ms1, ms2): if not check_range(episode_id, ms1, ms2, flask.current_app.config.get('MAX_GIF_LENGTH')): flask.abort(400, 'bad time range') cur = get_db().cursor() cur.execute( 'SELECT video_path, subtitles_path FROM episode WHERE id=:episode_id', {'episode_id': episode_id}) res = cur.fetchone() video_path = res['video_path'] subtitles_path = res['subtitles_path'] return flask.Response(ff.make_gif_with_subtitles(video_path, subtitles_path, ms1, ms2), mimetype='image/gif')
def browse_season(season_id): cur = get_db().cursor() targs = {} # Retrieve season information. cur.execute('SELECT slug, icon_png, name FROM season WHERE id=:season_id', {'season_id': season_id}) res = cur.fetchone() targs['season'] = res['slug'] targs['season_name'] = res['name'] targs['season_has_icon'] = res['icon_png'] is not None # Retrieve episodes. cur.execute( 'SELECT slug, name, duration, snapshot_ms FROM episode ' ' WHERE season_id=:season_id', {'season_id': season_id}) targs['episodes'] = cur.fetchall() def str_ms(ms): return strftimecode(timedelta(milliseconds=ms)) targs['str_ms'] = str_ms return flask.render_template('season.html', **targs)
def index(): cur = get_db().cursor() cur.execute('SELECT slug, name FROM season') return flask.render_template('index.html', seasons=cur.fetchall())
def browse_moment(season_id, episode_id, ms): cur = get_db().cursor() targs = {'ms': ms} # Retrieve season information. cur.execute('SELECT slug, icon_png, name FROM season WHERE id=:season_id', {'season_id': season_id}) res = cur.fetchone() targs['season'] = res['slug'] targs['season_name'] = res['name'] targs['season_has_icon'] = res['icon_png'] is not None # Retrieve episode information. cur.execute('SELECT slug, name FROM episode WHERE id=:episode_id', {'episode_id': episode_id}) res = cur.fetchone() targs['episode'] = res['slug'] targs['episode_name'] = res['name'] # Locate relevant subtitles. cur.execute( 'SELECT content, start_ms, end_ms, snapshot_ms FROM subtitle ' ' WHERE episode_id=:episode_id ' ' AND MIN(ABS(start_ms-:ms), ABS(end_ms-:ms))<=:ms_range', { 'episode_id': episode_id, 'ms': ms, 'ms_range': CLOSE_SUBTITLE_SECS * 1000 }) subtitles = cur.fetchall() targs['subtitles'] = subtitles targs['current_line'] = next( map( lambda row: strip_html(row['content']), filter(lambda row: ms >= row['start_ms'] and ms <= row['end_ms'], subtitles)), '') # Locate surrounding images. nav_list = [ms] cur.execute( ' SELECT ms FROM snapshot WHERE episode_id=:episode_id AND ms<:ms ' 'ORDER BY ms DESC LIMIT :steps', { 'episode_id': episode_id, 'ms': ms, 'steps': NAV_STEPS }) nav_list += [row['ms'] for row in cur.fetchall()] cur.execute( ' SELECT ms FROM snapshot WHERE episode_id=:episode_id AND ms>:ms ' 'ORDER BY ms ASC LIMIT :steps', { 'episode_id': episode_id, 'ms': ms, 'steps': NAV_STEPS }) nav_list += [row['ms'] for row in cur.fetchall()] nav_list.sort() targs['nav_list'] = nav_list def encode_text(content): return b64encode(strip_html(content).encode('utf-8')) targs['encode_text'] = encode_text return flask.render_template('moment.html', **targs)