From 34a33fdeb6a227d0ffae2ad55b0180ea16385770 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Fri, 7 Oct 2022 22:57:31 +1100 Subject: [PATCH] partially implement playlist links in video descriptions We make them conceptually "part of the footer" so they're updated only when the video is otherwise updated (which would generally mean MODIFIED). --- postgres/setup.sh | 4 ++- sheetsync/sheetsync/main.py | 9 ++++-- thrimshim/thrimshim/main.py | 60 ++++++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/postgres/setup.sh b/postgres/setup.sh index eee7f5d..98483d4 100644 --- a/postgres/setup.sh +++ b/postgres/setup.sh @@ -144,8 +144,10 @@ CREATE TABLE editors ( -- Playlists are communicated to playlist manager via this table. -- Sheetsync will wipe and re-populate this table periodically to match what is in the sheet CREATE TABLE playlists ( + playlist_id TEXT PRIMARY KEY, + name TEXT NOT NULL, tags TEXT[] NOT NULL, - playlist_id TEXT PRIMARY KEY + show_in_description BOOLEAN NOT NULL ); EOSQL diff --git a/sheetsync/sheetsync/main.py b/sheetsync/sheetsync/main.py index 3bf0cb1..868f943 100644 --- a/sheetsync/sheetsync/main.py +++ b/sheetsync/sheetsync/main.py @@ -364,6 +364,11 @@ class SheetSync(object): overwriting the entire playlists table""" playlists = [] for row in rows: + # TODO redo sheet parsing for new columns + # Defaults for now: + name = "" + show_in_description = false + if len(row) != 3: continue tags, _, playlist_id = row @@ -373,7 +378,7 @@ class SheetSync(object): playlist_id = playlist_id.strip() if len(playlist_id) != 34 or not playlist_id.startswith('PL'): continue - playlists.append((tags, playlist_id)) + playlists.append((playlist_id, tags, name, show_in_description)) # We want to wipe and replace all the current entries in the table. # The easiest way to do this is a DELETE then an INSERT, all within a transaction. # The "with" block will perform everything under it within a transaction, rolling back @@ -381,7 +386,7 @@ class SheetSync(object): logging.info("Updating playlists table with {} playlists".format(len(playlists))) with self.conn: query(self.conn, "DELETE FROM playlists") - execute_values(self.conn.cursor(), "INSERT INTO playlists(tags, playlist_id) VALUES %s", playlists) + execute_values(self.conn.cursor(), "INSERT INTO playlists(playlist_id, tags, name, show_in_description) VALUES %s", playlists) @argh.arg('dbconnect', help= diff --git a/thrimshim/thrimshim/main.py b/thrimshim/thrimshim/main.py index 67b2679..50eb5fc 100644 --- a/thrimshim/thrimshim/main.py +++ b/thrimshim/thrimshim/main.py @@ -259,11 +259,46 @@ def update_row(ident, editor=None): for extra in extras: del new_row[extra] + # Check a row with id = ident is in the database + conn = app.db_manager.get_conn() + built_query = sql.SQL(""" + SELECT id, state, {} + FROM events + WHERE id = %s + """).format(sql.SQL(', ').join( + sql.Identifier(key) for key in sheet_columns + )) + results = database.query(conn, built_query, ident) + old_row = results.fetchone()._asdict() + if old_row is None: + return 'Row {} not found'.format(ident), 404 + assert old_row['id'] == ident + + playlists = query(conn, """ + SELECT playlist_id, name, tags + FROM playlists + WHERE show_in_description + """) + # Filter for matching playlists for this video + playlists = [ + playlist for playlist in playlists + if all( + tag.lower() in [t.lower() for t in old_row['tags']] + for tag in playlist.tags + ) + ] + # Include headers and footers - if 'video_title' in new_row: - new_row['video_title'] = app.title_header + new_row['video_title'] - if 'video_description' in new_row: - new_row['video_description'] += app.description_footer + playlist_info = get_playlist_info(conn) + new_row['video_title'] = app.title_header + new_row['video_title'] + description_lines = ["This video is part of the following playlists:"] + description_lines += [ + # TODO check this url + "{} [https://youtube.com/playlist/{}]".format(playlist.name, playlist.playlist_id) + for playlist in playlists + ] + description_lines.append(app.description_footer) + new_row['video_description'] += "\n".join(description_lines) # Validate youtube requirements on title and description if len(new_row['video_title']) > MAX_TITLE_LENGTH: @@ -306,21 +341,6 @@ def update_row(ident, editor=None): if not new_row['thumbnail_image'].startswith(b'\x89PNG\r\n\x1a\n'): return 'thumbnail_image must be a PNG', 400 - conn = app.db_manager.get_conn() - # Check a row with id = ident is in the database - built_query = sql.SQL(""" - SELECT id, state, {} - FROM events - WHERE id = %s - """).format(sql.SQL(', ').join( - sql.Identifier(key) for key in sheet_columns - )) - results = database.query(conn, built_query, ident) - old_row = results.fetchone()._asdict() - if old_row is None: - return 'Row {} not found'.format(ident), 404 - assert old_row['id'] == ident - if new_row['state'] == 'MODIFIED': if old_row['state'] not in ['DONE', 'MODIFIED']: return 'Video is in state {} and cannot be modified'.format(old_row['state']), 403 @@ -374,8 +394,6 @@ def update_row(ident, editor=None): return 'Fields {} must be non-null for video to be cut'.format(', '.join(missing)), 400 if len(new_row.get('video_title', '')) <= len(app.title_header): return 'Video title must not be blank', 400 - if len(new_row.get('video_description', '')) <= len(app.description_footer): - return 'Video description must not be blank. If you have nothing else to say, just repeat the title.', 400 elif new_row['state'] != 'UNEDITED': return 'Invalid state {}'.format(new_row['state']), 400 new_row['uploader'] = None