playlist_manager: Fetch first/last event info when fetching playlists

And switch to passing around a namedtuple of these + tags instead of just tags.

To avoid confusion with the list of videos in the playlist, we refer to this data as the "playlist config".
pull/400/head
Mike Lang 4 months ago committed by Mike Lang
parent 115fd8bba3
commit fae5267941

@ -14,6 +14,7 @@ from common.database import DBManager, query
from common.googleapis import GoogleAPIClient from common.googleapis import GoogleAPIClient
PlaylistConfig = namedtuple("Playlist", ["tags", "first_event_id", "last_event_id"])
PlaylistEntry = namedtuple("PlaylistEntry", ["entry_id", "video_id"]) PlaylistEntry = namedtuple("PlaylistEntry", ["entry_id", "video_id"])
@ -61,13 +62,13 @@ class PlaylistManager(object):
logging.debug(f"Found {len(videos)} eligible videos") logging.debug(f"Found {len(videos)} eligible videos")
logging.info("Getting dynamic playlists") logging.info("Getting dynamic playlists")
playlist_tags = self.get_playlist_tags() playlists = self.get_playlist_config()
logging.debug(f"Found {len(playlist_tags)} playlists") logging.debug(f"Found {len(playlists)} playlists")
# start all workers # start all workers
workers = {} workers = {}
for playlist_id, tags in playlist_tags.items(): for playlist_id, playlist_config in playlists.items():
workers[playlist_id] = gevent.spawn(self.update_playlist, playlist_id, tags, videos) workers[playlist_id] = gevent.spawn(self.update_playlist, playlist_id, playlist_config, videos)
# check each one for success, reset on failure # check each one for success, reset on failure
for playlist_id, worker in workers.items(): for playlist_id, worker in workers.items():
@ -90,26 +91,32 @@ class PlaylistManager(object):
self.dbmanager.put_conn(conn) self.dbmanager.put_conn(conn)
return {video.video_id: video for video in videos} return {video.video_id: video for video in videos}
def get_playlist_tags(self): def get_playlist_config(self):
conn = self.dbmanager.get_conn() conn = self.dbmanager.get_conn()
playlist_tags = { playlists = {
row.playlist_id: [tag.lower() for tag in row.tags] row.playlist_id: PlaylistConfig(
for row in query(conn, "SELECT playlist_id, tags FROM playlists") [tag.lower() for tag in row.tags],
row.first_event_id,
row.last_event_id,
) for row in query(conn, "SELECT playlist_id, tags, first_event_id, last_event_id FROM playlists")
} }
self.dbmanager.put_conn(conn) self.dbmanager.put_conn(conn)
duplicates = set(playlist_tags) & set(self.static_playlist_tags) duplicates = set(playlists) & set(self.static_playlists)
if duplicates: if duplicates:
raise ValueError( raise ValueError(
"Some playlists are listed in both static and dynamic playlist sources: {}".format(", ".join(duplicates)) "Some playlists are listed in both static and dynamic playlist sources: {}".format(", ".join(duplicates))
) )
playlist_tags.update(self.static_playlist_tags) playlists.update({
return playlist_tags id: PlaylistConfig(tags, None, None)
for id, tags in self.static_playlists.items()
})
return playlists
def update_playlist(self, playlist_id, tags, videos): def update_playlist(self, playlist_id, playlist_config, videos):
# Filter the video list for videos with matching tags # Filter the video list for videos with matching tags
matching = [ matching = [
video for video in videos.values() video for video in videos.values()
if all(tag in [t.lower() for t in video.tags] for tag in tags) if all(tag in [t.lower() for t in video.tags] for tag in playlist_config.tags)
] ]
logging.debug(f"Found {len(matching)} matching videos for playlist {playlist_id}") logging.debug(f"Found {len(matching)} matching videos for playlist {playlist_id}")
# If we have nothing to add, short circuit without doing any API calls to save quota. # If we have nothing to add, short circuit without doing any API calls to save quota.

Loading…
Cancel
Save