def get_current_song(stream_id): with DBManager.create_session_scope() as session: cur_song = session.query(PleblistSong).filter(PleblistSong.stream_id == stream_id, PleblistSong.date_played.is_(None)).order_by(PleblistSong.date_added.asc()).first() if cur_song is None: return None session.expunge(cur_song) return cur_song
def remove_command(self, command): self.remove_command_aliases(command) with DBManager.create_session_scope() as db_session: self.db_session.expunge(command.data) db_session.delete(command.data) db_session.delete(command)
def command_checkalias(**options): if 'alias' not in request.form: return make_response(jsonify({'error': 'Missing `alias` parameter.'}), 400) request_alias = request.form['alias'].lower() command_manager = CommandManager(None) internal_commands = command_manager.get_internal_commands() db_command_aliases = [] with DBManager.create_session_scope() as db_session: for command in db_session.query(Command): db_command_aliases.extend(command.command.split('|')) for alias in internal_commands: db_command_aliases.append(alias) db_command_aliases = set(db_command_aliases) if request_alias in db_command_aliases: return make_response(jsonify({'error': 'Alias already in use'})) else: return make_response(jsonify({'success': 'good job'}))
def create_stream(self, status): log.info('Attempting to create a stream!') with DBManager.create_session_scope(expire_on_commit=False) as db_session: stream_chunk = db_session.query(StreamChunk).filter_by(broadcast_id=status['broadcast_id']).one_or_none() if stream_chunk is not None: stream = stream_chunk.stream else: log.info('checking if there is an active stream already') stream = db_session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start.desc()).first() if stream is None: log.info('No active stream, create new!') stream = Stream(status['created_at'], title=status['title']) db_session.add(stream) db_session.commit() log.info('added stream!') stream_chunk = StreamChunk(stream, status['broadcast_id'], status['created_at']) db_session.add(stream_chunk) db_session.commit() stream.stream_chunks.append(stream_chunk) log.info('Created stream chunk') self.current_stream = stream self.current_stream_chunk = stream_chunk db_session.expunge_all() log.info('added shit to current_stream etc')
def pleblist_add(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'youtube_id' not in request.form: return make_response(jsonify({'error': 'Missing data youtube_id'}), 400) if 'password' not in request.form: return make_response(jsonify({'error': 'Missing data password'}), 400) salted_password = generate_password_hash(config['web']['pleblist_password'], config['web']['pleblist_password_salt']) try: user_password = base64.b64decode(request.form['password']) except binascii.Error: return make_response(jsonify({'error': 'Invalid data password'}), 400) if not user_password == salted_password: return make_response(jsonify({'error': 'Invalid password'}), 401) with DBManager.create_session_scope() as session: youtube_id = request.form['youtube_id'] current_stream = session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) song_requested = PleblistSong(current_stream.id, youtube_id) session.add(song_requested) song_info = session.query(PleblistSongInfo).filter_by(pleblist_song_youtube_id=youtube_id).first() if song_info is None and song_requested.song_info is None: PleblistManager.init(config['youtube']['developer_key']) song_info = PleblistManager.create_pleblist_song_info(song_requested.youtube_id) if song_info is not False: session.add(song_info) session.commit() return jsonify({'success': True})
def pleblist_next(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'song_id' not in request.form: return make_response(jsonify({'error': 'Missing data song_id'}), 400) if 'password' not in request.form: return make_response(jsonify({'error': 'Missing data password'}), 400) salted_password = generate_password_hash(config['web']['pleblist_password'], config['web']['pleblist_password_salt']) try: user_password = base64.b64decode(request.form['password']) except binascii.Error: return make_response(jsonify({'error': 'Invalid data password'}), 400) if not user_password == salted_password: return make_response(jsonify({'error': 'Invalid password'}), 401) with DBManager.create_session_scope() as session: try: current_song = session.query(PleblistSong).filter(PleblistSong.id == int(request.form['song_id'])).order_by(PleblistSong.date_added.asc()).first() except ValueError: return make_response(jsonify({'error': 'Invalid data song_id'}), 400) if current_song is None: return make_response(jsonify({'error': 'No song active in the pleblist'}), 404) current_song.date_played = datetime.datetime.now() session.commit() # TODO: Add more data. # Was this song forcefully skipped? Or did it end naturally. return jsonify({'message': 'Success!'})
def refresh_video_url(self): if self.online is False: return if self.current_stream_chunk is None or self.current_stream is None: return if self.current_stream_chunk.video_url is not None: return log.info('Attempting to fetch video url for broadcast {0}'.format(self.current_stream_chunk.broadcast_id)) video_url, video_preview_image_url = self.fetch_video_url(self.current_stream_chunk) if video_url is not None: log.info('Successfully fetched a video url: {0}'.format(video_url)) with DBManager.create_session_scope(expire_on_commit=False) as db_session: self.current_stream_chunk.video_url = video_url self.current_stream_chunk.video_preview_image_url = video_preview_image_url db_session.add(self.current_stream_chunk) db_session.commit() db_session.expunge_all() log.info('successfully commited it and shit') else: log.info('Not video for broadcast found')
def create_command(self, alias_str, **options): """ TODO: Does this part of the code work as expected? Right now if the second alias is already used, it could result in us creating a command with an alias that's already in use. """ aliases = alias_str.lower().replace('!', '').split('|') main_alias = aliases[0] if main_alias in self.data: # Command with this alias already exists, return its instance! return self.data[main_alias], False command = Command(command=alias_str, **options) command.data = CommandData(command.id) self.add_command_aliases(command) with DBManager.create_session_scope( expire_on_commit=False) as db_session: db_session.add(command) db_session.add(command.data) db_session.commit() db_session.expunge(command) db_session.expunge(command.data) self.db_session.add(command.data) self.commit() return command, True
def pleblist_blacklist(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) # TODO: implement this return make_response(jsonify({'error': 'NOT IMPLEMENTED'}), 400)
def remove_highlight(self, id): """ Returns True if a highlight was removed, otherwise return False """ with DBManager.create_session_scope() as db_session: num_rows = db_session.query(StreamChunkHighlight).filter(StreamChunkHighlight.id == id).delete() return (num_rows == 1)
def pleblist_blacklist(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by( Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) # TODO: implement this return make_response(jsonify({'error': 'NOT IMPLEMENTED'}), 400)
def pleblist_list_by_stream(stream_id): with DBManager.create_session_scope() as session: songs = session.query(PleblistSong).filter_by(stream_id=stream_id).all() payload = { '_total': len(songs), 'songs': [song.jsonify() for song in songs], } return jsonify(payload)
def pleblist_list_by_stream(stream_id): with DBManager.create_session_scope() as session: songs = session.query(PleblistSong).filter_by( stream_id=stream_id).all() payload = { '_total': len(songs), 'songs': [song.jsonify() for song in songs], } return jsonify(payload)
def commands_edit(command_id, **options): with DBManager.create_session_scope() as db_session: command = db_session.query(Command).filter_by( id=command_id).one_or_none() if command is None: return render_template('admin/command_404.html'), 404 return render_template('admin/edit_command.html', command=command, user=options.get('user', None))
def pleblist_history_redirect(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start.desc()).first() if current_stream is not None: return redirect('/pleblist/history/{}/'.format(current_stream.id), 303) last_stream = session.query(Stream).filter_by(ended=True).order_by(Stream.stream_start.desc()).first() if last_stream is not None: return redirect('/pleblist/history/{}/'.format(last_stream.id), 303) return render_template('pleblist_history_no_stream.html'), 404
def update_highlight(self, id, **options): """ Returns True if a highlight was modified, otherwise return False """ if 'offset' in options: options['highlight_offset'] = options.pop('offset') with DBManager.create_session_scope() as db_session: num_rows = db_session.query(StreamChunkHighlight).filter(StreamChunkHighlight.id == id).update(options) return (num_rows == 1)
def pleblist_history_stream(stream_id): with DBManager.create_session_scope() as session: stream = session.query(Stream).filter_by(id=stream_id).one_or_none() if stream is None: return render_template('pleblist_history_404.html'), 404 songs = session.query(PleblistSong).filter(PleblistSong.stream_id == stream.id).order_by(PleblistSong.date_added.asc(), PleblistSong.date_played.asc()).all() total_length_left = sum([song.song_info.duration if song.date_played is None and song.song_info is not None else 0 for song in songs]) return render_template('pleblist_history.html', stream=stream, songs=songs, total_length_left=total_length_left)
def pleblist_list(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) songs = session.query(PleblistSong).filter(PleblistSong.stream_id == current_stream.id, PleblistSong.date_played.is_(None)).all() payload = { '_total': len(songs), 'songs': [song.jsonify() for song in songs], } return jsonify(payload)
def pleblist_history_redirect(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by( Stream.stream_start.desc()).first() if current_stream is not None: return redirect('/pleblist/history/{}/'.format(current_stream.id), 303) last_stream = session.query(Stream).filter_by(ended=True).order_by( Stream.stream_start.desc()).first() if last_stream is not None: return redirect('/pleblist/history/{}/'.format(last_stream.id), 303) return render_template('pleblist_history_no_stream.html'), 404
def decorated_function(*args, **kwargs): if 'user' not in session: abort(403) with DBManager.create_session_scope() as db_session: user = db_session.query(User).filter_by( username=session['user']['username']).one_or_none() if user is None: abort(403) if user.level < level: abort(403) db_session.expunge(user) kwargs['user'] = user return f(*args, **kwargs)
def pleblist_list(): with DBManager.create_session_scope() as session: current_stream = session.query(Stream).filter_by(ended=False).order_by( Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) songs = session.query(PleblistSong).filter( PleblistSong.stream_id == current_stream.id, PleblistSong.date_played.is_(None)).all() payload = { '_total': len(songs), 'songs': [song.jsonify() for song in songs], } return jsonify(payload)
def go_offline(self): with DBManager.create_session_scope(expire_on_commit=False) as db_session: self.current_stream.ended = True self.current_stream.stream_end = self.first_offline self.current_stream_chunk.chunk_end = self.first_offline db_session.add(self.current_stream) db_session.add(self.current_stream_chunk) db_session.commit() db_session.expunge_all() self.last_stream = self.current_stream self.current_stream = None self.current_stream_chunk = None
def pleblist_validate(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'youtube_id' not in request.form: return make_response(jsonify({'error': 'Missing data youtube_id'}), 400) with DBManager.create_session_scope() as session: youtube_id = request.form['youtube_id'] print(youtube_id) song_info = session.query(PleblistSongInfo).filter_by( pleblist_song_youtube_id=youtube_id).first() if song_info is not None: return jsonify({ 'message': 'success', 'song_info': song_info.jsonify() }) PleblistManager.init(config['youtube']['developer_key']) song_info = PleblistManager.create_pleblist_song_info(youtube_id) if not song_info and len(youtube_id) > 11: youtube_id = youtube_id[:11] song_info = session.query(PleblistSongInfo).filter_by( pleblist_song_youtube_id=youtube_id).first() if song_info is not None: return jsonify({ 'message': 'success', 'new_youtube_id': youtube_id, 'song_info': song_info.jsonify() }) else: song_info = PleblistManager.create_pleblist_song_info( youtube_id) if song_info: print(song_info) session.add(song_info) session.commit() return jsonify({ 'message': 'success', 'new_youtube_id': youtube_id, 'song_info': song_info.jsonify() }) return jsonify({'message': 'invalid youtube id', 'song_info': None})
def pleblist_validate(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'youtube_id' not in request.form: return make_response(jsonify({'error': 'Missing data youtube_id'}), 400) with DBManager.create_session_scope() as session: youtube_id = request.form['youtube_id'] print(youtube_id) song_info = session.query(PleblistSongInfo).filter_by(pleblist_song_youtube_id=youtube_id).first() if song_info is not None: return jsonify({ 'message': 'success', 'song_info': song_info.jsonify() }) PleblistManager.init(config['youtube']['developer_key']) song_info = PleblistManager.create_pleblist_song_info(youtube_id) if not song_info and len(youtube_id) > 11: youtube_id = youtube_id[:11] song_info = session.query(PleblistSongInfo).filter_by(pleblist_song_youtube_id=youtube_id).first() if song_info is not None: return jsonify({ 'message': 'success', 'new_youtube_id': youtube_id, 'song_info': song_info.jsonify() }) else: song_info = PleblistManager.create_pleblist_song_info(youtube_id) if song_info: print(song_info) session.add(song_info) session.commit() return jsonify({ 'message': 'success', 'new_youtube_id': youtube_id, 'song_info': song_info.jsonify() }) return jsonify({ 'message': 'invalid youtube id', 'song_info': None })
def pleblist_history_stream(stream_id): with DBManager.create_session_scope() as session: stream = session.query(Stream).filter_by(id=stream_id).one_or_none() if stream is None: return render_template('pleblist_history_404.html'), 404 songs = session.query(PleblistSong).filter( PleblistSong.stream_id == stream.id).order_by( PleblistSong.date_added.asc(), PleblistSong.date_played.asc()).all() total_length_left = sum([ song.song_info.duration if song.date_played is None and song.song_info is not None else 0 for song in songs ]) return render_template('pleblist_history.html', stream=stream, songs=songs, total_length_left=total_length_left)
def create_highlight(self, **options): """ Returns an error message (string) if something went wrong, otherwise returns True """ if self.online is False or self.current_stream_chunk is None: return 'The stream is not online' if self.current_stream_chunk.video_url is None: return 'No video URL fetched for this chunk yet, try in 5 minutes' try: highlight = StreamChunkHighlight(self.current_stream_chunk, **options) with DBManager.create_session_scope(expire_on_commit=False) as db_session: db_session.add(highlight) db_session.add(self.current_stream_chunk) except: log.exception('uncaught exception in create_highlight') return 'Unknown reason, ask pajlada' return True
def create_stream_chunk(self, status): if self.current_stream_chunk is not None: # There's already a stream chunk started! self.current_stream_chunk.chunk_end = datetime.datetime.now() DBManager.session_add_expunge(self.current_stream_chunk) with DBManager.create_session_scope(expire_on_commit=False) as db_session: stream_chunk = db_session.query(StreamChunk).filter_by(broadcast_id=status['broadcast_id']).one_or_none() if stream_chunk is None: log.info('Creating stream chunk, from create_stream_chunk') stream_chunk = StreamChunk(self.current_stream, status['broadcast_id'], status['created_at']) self.current_stream_chunk = stream_chunk db_session.add(stream_chunk) db_session.commit() else: log.info('We already have a stream chunk!') self.current_stream_chunk = stream_chunk db_session.expunge_all() db_session.close() self.current_stream.stream_chunks.append(stream_chunk)
def command_remove(command_id, **options): with DBManager.create_session_scope() as db_session: command = db_session.query(Command).filter_by( id=command_id).one_or_none() if command is None: return make_response(jsonify({'error': 'Invalid command ID'}), 404) if command.level > options['user'].level: abort(403) db_session.delete(command.data) db_session.delete(command) payload = {'event': 'command.remove', 'data': {'command_id': command_id}} payload_bytes = json.dumps(payload).encode('utf-8') try: with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client: client.connect(config['sock']['sock_file']) client.sendall(payload_bytes) return make_response(jsonify({'success': 'good job'})) except: log.exception('???') return make_response(jsonify({'error': 'Could not push update'}))
def __init__(self, bot): self.bot = bot self.current_stream_chunk = None # should this even exist? self.num_offlines = 0 self.first_offline = None self.bot.execute_every(self.STATUS_CHECK_INTERVAL, self.refresh_stream_status) self.bot.execute_every(self.VIDEO_URL_CHECK_INTERVAL, self.refresh_video_url) """ This will load the latest stream so we can post an accurate "time since last online" figure. """ with DBManager.create_session_scope(expire_on_commit=False) as db_session: self.current_stream = db_session.query(Stream).filter_by(ended=False).order_by(Stream.stream_start.desc()).first() self.last_stream = db_session.query(Stream).filter_by(ended=True).order_by(Stream.stream_end.desc()).first() if self.current_stream: self.current_stream_chunk = db_session.query(StreamChunk).filter_by(stream_id=self.current_stream.id).order_by(StreamChunk.chunk_start.desc()).first() log.info('Set current stream chunk here to {0}'.format(self.current_stream_chunk)) db_session.expunge_all()
def pleblist_add(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'youtube_id' not in request.form: return make_response(jsonify({'error': 'Missing data youtube_id'}), 400) if 'password' not in request.form: return make_response(jsonify({'error': 'Missing data password'}), 400) salted_password = generate_password_hash( config['web']['pleblist_password'], config['web']['pleblist_password_salt']) try: user_password = base64.b64decode(request.form['password']) except binascii.Error: return make_response(jsonify({'error': 'Invalid data password'}), 400) if not user_password == salted_password: return make_response(jsonify({'error': 'Invalid password'}), 401) with DBManager.create_session_scope() as session: youtube_id = request.form['youtube_id'] current_stream = session.query(Stream).filter_by(ended=False).order_by( Stream.stream_start).first() if current_stream is None: return make_response(jsonify({'error': 'Stream offline'}), 400) song_requested = PleblistSong(current_stream.id, youtube_id) session.add(song_requested) song_info = session.query(PleblistSongInfo).filter_by( pleblist_song_youtube_id=youtube_id).first() if song_info is None and song_requested.song_info is None: PleblistManager.init(config['youtube']['developer_key']) song_info = PleblistManager.create_pleblist_song_info( song_requested.youtube_id) if song_info is not False: session.add(song_info) session.commit() return jsonify({'success': True})
def pleblist_next(): if not request.method == 'POST': return make_response(jsonify({'error': 'Invalid request method'}), 405) if 'song_id' not in request.form: return make_response(jsonify({'error': 'Missing data song_id'}), 400) if 'password' not in request.form: return make_response(jsonify({'error': 'Missing data password'}), 400) salted_password = generate_password_hash( config['web']['pleblist_password'], config['web']['pleblist_password_salt']) try: user_password = base64.b64decode(request.form['password']) except binascii.Error: return make_response(jsonify({'error': 'Invalid data password'}), 400) if not user_password == salted_password: return make_response(jsonify({'error': 'Invalid password'}), 401) with DBManager.create_session_scope() as session: try: current_song = session.query(PleblistSong).filter( PleblistSong.id == int(request.form['song_id'])).order_by( PleblistSong.date_added.asc()).first() except ValueError: return make_response(jsonify({'error': 'Invalid data song_id'}), 400) if current_song is None: return make_response( jsonify({'error': 'No song active in the pleblist'}), 404) current_song.date_played = datetime.datetime.now() session.commit() # TODO: Add more data. # Was this song forcefully skipped? Or did it end naturally. return jsonify({'message': 'Success!'})
def banphrases(**options): with DBManager.create_session_scope() as db_session: banphrases = db_session.query(Filter).filter_by( enabled=True, type='banphrase').all() return render_template('admin/banphrases.html', banphrases=banphrases)
def commands_create(**options): if request.method == 'POST': if 'aliases' not in request.form: abort(403) alias_str = request.form.get('aliases', '').replace('!', '').lower() delay_all = request.form.get('cd', Command.DEFAULT_CD_ALL) delay_user = request.form.get('usercd', Command.DEFAULT_CD_USER) level = request.form.get('level', Command.DEFAULT_LEVEL) cost = request.form.get('cost', 0) try: delay_all = int(delay_all) delay_user = int(delay_user) level = int(level) cost = int(cost) except ValueError: abort(403) if len(alias_str) == 0: abort(403) if delay_all < 0 or delay_all > 9999: abort(403) if delay_user < 0 or delay_user > 9999: abort(403) if level < 0 or level > 2000: abort(403) if cost < 0 or cost > 9999999: abort(403) options = { 'delay_all': delay_all, 'delay_user': delay_user, 'level': level, 'cost': cost, } valid_action_types = ['say', 'me', 'whisper', 'reply'] action_type = request.form.get('reply', 'say').lower() if action_type not in valid_action_types: abort(403) response = request.form.get('response', '') if len(response) == 0: abort(403) action = {'type': action_type, 'message': response} options['action'] = action command_manager = CommandManager(None) internal_commands = command_manager.get_internal_commands() db_command_aliases = [] with DBManager.create_session_scope() as db_session: for command in db_session.query(Command): db_command_aliases.extend(command.command.split('|')) for alias in internal_commands: db_command_aliases.append(alias) db_command_aliases = set(db_command_aliases) alias_list = alias_str.split('|') for alias in alias_list: if alias in db_command_aliases: return render_template('admin/create_command_fail.html') command = Command(command=alias_str, **options) command.data = CommandData(command.id) with DBManager.create_session_scope( expire_on_commit=False) as db_session: db_session.add(command) db_session.add(command.data) db_session.commit() db_session.expunge(command) db_session.expunge(command.data) SocketClientManager.send('command.update', {'command_id': command.id}) return render_template('admin/create_command_success.html', command=command) else: return render_template('admin/create_command.html')
def links_whitelist(**options): with DBManager.create_session_scope() as db_session: links = db_session.query(WhitelistedLink).filter_by().all() return render_template('admin/links_whitelist.html', links=links)
def command_update(command_id, **options): if not request.method == 'POST': return make_response( jsonify({'error': 'Invalid request method. (Expected POST)'}), 400) if len(request.form) == 0: return make_response(jsonify({'error': 'Missing parameter to edit.'}), 400) valid_names = [ 'enabled', 'level', 'delay_all', 'delay_user', 'cost', 'can_execute_with_whisper', 'sub_only' ] valid_action_names = ['type', 'message'] with DBManager.create_session_scope() as db_session: command = db_session.query(Command).filter_by( id=command_id).one_or_none() if command is None: return make_response(jsonify({'error': 'Invalid command ID'}), 404) if command.level > options['user'].level: abort(403) parsed_action = json.loads(command.action_json) options = {} for key in request.form: if key.startswith('data_'): name = key[5:] value = request.form[key] if name.startswith('action_'): name = name[7:] if name in valid_action_names and name in parsed_action and command.action.type == 'message': value_type = type(parsed_action[name]) if value_type is bool: parsed_value = True if value == '1' else False elif value_type is int: try: parsed_value = int(value) except ValueError: continue else: parsed_value = value parsed_action[name] = parsed_value command.action_json = json.dumps(parsed_action) else: if name in valid_names: value_type = type(getattr(command, name)) if value_type is bool: parsed_value = True if value == '1' else False elif value_type is int: try: parsed_value = int(value) except ValueError: continue else: parsed_value = value options[name] = parsed_value command.set(**options) if SocketClientManager.send('command.update', {'command_id': command_id}) is True: return make_response(jsonify({'success': 'good job'})) else: return make_response(jsonify({'error': 'Could not push update'}))
twitch = oauth.remote_app( 'twitch', consumer_key=config['webtwitchapi']['client_id'], consumer_secret=config['webtwitchapi']['client_secret'], request_token_params={'scope': 'user_read'}, base_url='https://api.twitch.tv/kraken/', request_token_url=None, access_token_method='POST', access_token_url='https://api.twitch.tv/kraken/oauth2/token', authorize_url='https://api.twitch.tv/kraken/oauth2/authorize', ) DBManager.init(config['main']['db']) TimeManager.init_timezone(config['main'].get('timezone', 'UTC')) with DBManager.create_session_scope() as db_session: num_decks = db_session.query(func.count(Deck.id)).scalar() custom_web_content = {} for web_content in db_session.query(WebContent).filter( WebContent.content is not None): custom_web_content[web_content.page] = web_content.content has_decks = num_decks > 0 errors.init(app) api.config = config modules = config['web'].get('modules', '').split() bot_commands_list = []