Compare commits

...

3 Commits

Author SHA1 Message Date
Mike Lang 3f6263a037 playlist-manager: More fixes 2 months ago
Mike Lang d8953568b2 playlist_manager: Add --once option 2 months ago
Mike Lang 9d12d37053 playlist_manager: Fixes 2 months ago

@ -2,6 +2,7 @@
import logging import logging
import json import json
import signal import signal
from collections import namedtuple
import argh import argh
import gevent import gevent
@ -96,7 +97,7 @@ class PlaylistManager(object):
# the next time. # the next time.
conn = self.dbmanager.get_conn() conn = self.dbmanager.get_conn()
videos = query(conn, """ videos = query(conn, """
SELECT video_id, tags, COALESCE((video_ranges[1]).start, event_start) AS start_time SELECT id, video_id, tags, COALESCE((video_ranges[1]).start, event_start) AS start_time
FROM events FROM events
WHERE state = 'DONE' AND upload_location = ANY (%s) AND public WHERE state = 'DONE' AND upload_location = ANY (%s) AND public
""", self.upload_locations) """, self.upload_locations)
@ -117,14 +118,14 @@ class PlaylistManager(object):
""") """)
} }
self.dbmanager.put_conn(conn) self.dbmanager.put_conn(conn)
duplicates = set(playlists) & set(self.static_playlists) duplicates = set(playlists) & set(self.static_playlist_tags)
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))
) )
playlists.update({ playlists.update({
id: PlaylistConfig(tags, None, None) id: PlaylistConfig(tags, None, None)
for id, tags in self.static_playlists.items() for id, tags in self.static_playlist_tags.items()
}) })
return playlists return playlists
@ -157,16 +158,22 @@ class PlaylistManager(object):
self.reorder_in_playlist(playlist_id, entry, index) self.reorder_in_playlist(playlist_id, entry, index)
# Get an updated list of new videos # Get an updated list of new videos
playlist = self.get_playlist(playlist_id)
matching_video_ids = {video.video_id for video in matching} matching_video_ids = {video.video_id for video in matching}
playlist_video_ids = {entry.video_id for entry in self.get_playlist(playlist_id)} playlist_video_ids = {entry.video_id for entry in playlist}
# It shouldn't matter, but just for clarity let's sort them by event order # It shouldn't matter, but just for clarity let's sort them by event order
new_videos = sorted(matching_video_ids - playlist_video_ids, key=lambda v: v.start_time) new_videos = sorted(
matching_video_ids - playlist_video_ids,
key=lambda video_id: videos[video_id].start_time,
)
# Insert each new video one at a time # Insert each new video one at a time
logging.debug(f"Inserting new videos for playlist {playlist_id}: {new_videos}") logging.debug(f"Inserting new videos for playlist {playlist_id}: {new_videos}")
for video in new_videos: for video_id in new_videos:
index = self.find_insert_index(videos, playlist_config, self.get_playlist(playlist_id), video) # Note we update the cached playlist after each loop as it is modified by insertions.
self.insert_into_playlist(playlist_id, video.video_id, index) playlist = self.get_playlist(playlist_id)
index = self.find_insert_index(videos, playlist_config, playlist, videos[video_id])
self.insert_into_playlist(playlist_id, video_id, index)
except PlaylistOutdated: except PlaylistOutdated:
logging.warning("Restarting playlist update as playlist is out of date") logging.warning("Restarting playlist update as playlist is out of date")
continue continue
@ -185,11 +192,11 @@ class PlaylistManager(object):
if entry.video_id not in videos: if entry.video_id not in videos:
# Unknown videos should always remain in-place. # Unknown videos should always remain in-place.
continue continue
video = videos[video_id] video = videos[entry.video_id]
if video.id == playlist.first_event_id: if video.id == playlist_config.first_event_id:
new_index = 0 new_index = 0
elif video.id == playlist.last_event_id: elif video.id == playlist_config.last_event_id:
new_index = len(playlist) - 1 new_index = len(playlist) - 1
else: else:
continue continue
@ -277,8 +284,10 @@ class PlaylistManager(object):
""" """
logging.info(f"Inserting {video_id} at index {index} of {playlist_id}") logging.info(f"Inserting {video_id} at index {index} of {playlist_id}")
entry_id = self.api.insert_into_playlist(playlist_id, video_id, index) entry_id = self.api.insert_into_playlist(playlist_id, video_id, index)
# Update our copy # Update our copy, if we have one (which we should)
self.playlist_state.setdefault(playlist_id, []).insert(index, PlaylistEntry(entry_id, video_id) if playlist_id in self.playlist_state:
playlist = self.get_playlist(playlist_id)
playlist.insert(index, PlaylistEntry(entry_id, video_id))
def reorder_in_playlist(self, playlist_id, entry, new_index): def reorder_in_playlist(self, playlist_id, entry, new_index):
"""Take an existing entry in a given playlist and move it to the new index. """Take an existing entry in a given playlist and move it to the new index.
@ -434,6 +443,7 @@ def main(
playlists, playlists,
upload_location_allowlist="youtube", upload_location_allowlist="youtube",
interval=600, interval=600,
once=False,
metrics_port=8007, metrics_port=8007,
backdoor_port=0, backdoor_port=0,
): ):
@ -449,6 +459,7 @@ def main(
upload_location. upload_location.
interval is how often to check for new videos, default every 10min. interval is how often to check for new videos, default every 10min.
If --once is given, interval is ignored and we exit after one check.
""" """
common.PromLogCountsHandler.install() common.PromLogCountsHandler.install()
common.install_stacksampler() common.install_stacksampler()
@ -472,6 +483,9 @@ def main(
dbmanager = DBManager(dsn=dbconnect) dbmanager = DBManager(dsn=dbconnect)
manager = PlaylistManager(dbmanager, client, upload_locations, playlists) manager = PlaylistManager(dbmanager, client, upload_locations, playlists)
if once:
manager.run_once()
else:
while not stop.is_set(): while not stop.is_set():
try: try:
manager.run_once() manager.run_once()

Loading…
Cancel
Save