def _get_videos(ytcc: core.Ytcc, ids: List[int]) -> Iterable[MappedVideo]: ids = list(_get_ids(ids)) if ids: ytcc.set_video_id_filter(ids) ytcc.set_watched_filter(None) return ytcc.list_videos()
def tag(ytcc: core.Ytcc, name: str, tags: Tuple[str, ...]): """Set tags of a playlist. Sets the TAGS associated with the playlist called NAME. If no tags are given, all tags are removed from the given playlist. """ ytcc.tag_playlist(name, list(tags))
def update(ytcc: core.Ytcc, max_fail: Optional[int], max_backlog: Optional[int]): """Check if new videos are available. Downloads metadata of new videos (if any) without playing or downloading the videos. """ ytcc.update(max_fail, max_backlog)
def tui(ytcc: core.Ytcc, tags: List[str], since: datetime, till: datetime, playlists: List[str], ids: List[int], watched: bool, unwatched, order_by: Optional[List[Tuple[VideoAttr, Direction]]]): """Start an interactive terminal user interface.""" apply_filters(ytcc, tags, since, till, playlists, ids, watched, unwatched) if order_by is not None: ytcc.set_listing_order(order_by) Interactive(ytcc).run()
def unmark(ytcc: core.Ytcc, ids: Tuple[int, ...]): """Mark videos as unwatched. Marks videos as unwatched. If no IDs are given, ytcc tries to read IDs from stdin. If no IDs are given and no IDs were read from stdin, no videos are marked as watched. """ processed_ids = list(_get_ids(list(ids))) if processed_ids: ytcc.mark_unwatched(processed_ids)
def cleanup(ytcc: core.Ytcc, keep: Optional[int]): """Remove all watched videos from the database. WARNING!!! This removes all metadata of watched, marked as watched, and downloaded videos from ytcc's database. This cannot be undone! In most cases you won't need this command, but it is useful to keep the database size small. """ if keep is None: keep = config.ytcc.max_update_backlog ytcc.cleanup(keep)
def rename(ytcc: core.Ytcc, old: str, new: str): """Rename a playlist. Renames the playlist OLD to NEW. """ try: ytcc.rename_playlist(old, new) except NameConflictError as nce: logger.error("'%s'", str(nce)) raise Exit(1) from nce
def mark(ytcc: core.Ytcc, ids: Tuple[int, ...]): """Mark videos as watched. Marks videos as watched without playing or downloading them. If no IDs are given, ytcc tries to read IDs from stdin. If no IDs are given and no IDs were read from stdin, no videos are marked as watched. """ processed_ids = list(_get_ids(list(ids))) if processed_ids: ytcc.mark_watched(processed_ids)
def unsubscribe(ytcc: core.Ytcc, name: str): """Unsubscribe from a playlist. Unsubscribes from the playlist identified by NAME. """ try: ytcc.delete_playlist(name) except PlaylistDoesNotExistException as err: logger.error("Playlist '%s' does not exist", name) raise Exit(1) from err else: logger.info("Unsubscribed from %s", name)
def list_videos_impl(ytcc: core.Ytcc, tags: List[str], since: datetime, till: datetime, playlists: List[str], ids: List[int], attributes: List[str], watched: bool, unwatched: bool, order_by: Optional[List[Tuple[VideoAttr, Direction]]]) -> None: apply_filters(ytcc, tags, since, till, playlists, ids, watched, unwatched) if attributes: printer.filter = attributes else: printer.filter = config.ytcc.video_attrs if order_by is not None: ytcc.set_listing_order(order_by) printer.print(VideoPrintable(ytcc.list_videos()))
def download(ytcc: core.Ytcc, ids: Tuple[int, ...], path: Path, audio_only: bool, no_mark: bool): """Download videos. Downloads the videos identified by the given video IDs. If no IDs are given, ytcc tries to read IDs from stdin. If no IDs are given and no IDs were read from stdin, all unwatched videos are downloaded. """ videos = _get_videos(ytcc, list(ids)) for video in videos: logger.info("Downloading video '%s' from playlist(s) %s", video.title, ", ".join(f"'{pl.name}'" for pl in video.playlists)) if ytcc.download_video(video, str(path), audio_only) and not no_mark: ytcc.mark_watched(video)
def subscriptions(ytcc: core.Ytcc, attributes: List[PlaylistAttr]): """List all subscriptions.""" if not filter: printer.filter = config.ytcc.playlist_attrs else: printer.filter = attributes printer.print(PlaylistPrintable(ytcc.list_playlists()))
def subscribe(ytcc: core.Ytcc, name: str, url: str): """Subscribe to a playlist. The NAME argument is the name used to refer to the playlist. The URL argument is the URL to a playlist that is supported by youtube-dl. """ try: ytcc.add_playlist(name, url) except BadURLException as bad_url: logger.error("The given URL does not point to a playlist or is not supported by " "youtube-dl") raise Exit(1) from bad_url except NameConflictError as name_conflict: logger.error("The given name is already used for another playlist " "or the playlist is already subscribed") raise Exit(1) from name_conflict
def setUp(self): self.current_dir = os.path.dirname(__file__) self.ytcc = Ytcc(os.path.join(self.current_dir, "data/ytcc_test.conf")) self.db_conn = self.ytcc.db insert_list = [ ("V-ozGFl3Jks", "tmptYnCut", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488348731.0, 1), ("a1gOeiyIqPs", "tmp99Yc1l", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488348519.0, 1), ("0ounUgOrcqo", "tmppfXKp6", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488345630.0, 1), ("7mckB-NdKWY", "tmpiM62pN", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488345565.0, 0), ("RmRPt93uAsQ", "tmpIXBgjd", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488344217.0, 0), ("nDPy3RyKdrg", "tmpwA0TjG", "", "UCsLiV4WJfkTEHH0b9PmRklw", 1488343000.0, 0), ("L0_F805qUIM", "tmpKDOkro", "", "UCxexYYtOetqikZqriLuTS-g", 1488344253.0, 1), ("lXWrdlDEzQs", "tmpEvCR4s", "", "UCxexYYtOetqikZqriLuTS-g", 1488343152.0, 1), ("cCnXsCQNkr8", "tmp1rpsWK", "", "UCxexYYtOetqikZqriLuTS-g", 1488343046.0, 1), ("rSxVs0XeQa4", "tmpc5Y2pd", "", "UCxexYYtOetqikZqriLuTS-g", 1488342015.0, 0), ("gQAsWrGfsrw", "tmpn1M1Oa", "", "UCxexYYtOetqikZqriLuTS-g", 1488341324.0, 0), ] self.db_conn.add_channel("Webdriver Torso", "UCsLiV4WJfkTEHH0b9PmRklw") self.db_conn.add_channel("Webdriver YPP", "UCxexYYtOetqikZqriLuTS-g") self.db_conn.add_videos(insert_list) self.video_id = self.db_conn._execute_query_with_result( "select id from video where title = 'tmpIXBgjd';")[0][0]
def __init__(self, core: Ytcc): self.core = core self.videos = list(core.list_videos()) self.previous_action = Action.from_config() self.action = self.previous_action def makef(arg): return lambda: self.set_action(arg) self.hooks = {action.hotkey: makef(action) for action in list(Action)}
def setUp(self): self.current_dir = os.path.dirname(__file__) self.ytcc = Ytcc(os.path.join(self.current_dir, "data/ytcc_test.conf")) self.db_conn = self.ytcc.database self.db_conn.engine.execute("delete from video") self.db_conn.engine.execute("delete from channel") self.db_conn.add_channel( Channel(displayname="Webdriver Torso", yt_channelid="UCsLiV4WJfkTEHH0b9PmRklw")) self.db_conn.add_channel( Channel(displayname="Webdriver YPP", yt_channelid="UCxexYYtOetqikZqriLuTS-g"))
def play(ytcc: core.Ytcc, ids: Tuple[int, ...], audio_only: bool, no_meta: bool, no_mark: bool): """Play videos. Plays the videos identified by the given video IDs. If no IDs are given, ytcc tries to read IDs from stdin. If no IDs are given and no IDs were read from stdin, all unwatched videos are played. """ videos = _get_videos(ytcc, list(ids)) loop_executed = False for video in videos: loop_executed = True if not no_meta: print_meta(video, sys.stderr) if ytcc.play_video(video, audio_only) and mark: ytcc.mark_watched(video) elif not no_mark: logger.warning("The video player terminated with an error. " "The last video is not marked as watched!") if not loop_executed: logger.info("No videos to watch. No videos match the given criteria.")
def setUp(self): self.current_dir = os.path.dirname(__file__) self.ytcc = Ytcc(os.path.join(self.current_dir, "data/ytcc_test.conf")) self.db_conn = self.ytcc.database insert_list = [ Video(yt_videoid="V-ozGFl3Jks", title="tmptYnCut", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488348731.0, watched=True), Video(yt_videoid="a1gOeiyIqPs", title="tmp99Yc1l", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488348519.0, watched=True), Video(yt_videoid="0ounUgOrcqo", title="tmppfXKp6", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488345630.0, watched=True), Video(yt_videoid="7mckB-NdKWY", title="tmpiM62pN", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488345565.0, watched=False), Video(yt_videoid="RmRPt93uAsQ", title="tmpIXBgjd", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488344217.0, watched=False), Video(yt_videoid="nDPy3RyKdrg", title="tmpwA0TjG", description="", publisher="UCsLiV4WJfkTEHH0b9PmRklw", publish_date=1488343000.0, watched=False), Video(yt_videoid="L0_F805qUIM", title="tmpKDOkro", description="", publisher="UCxexYYtOetqikZqriLuTS-g", publish_date=1488344253.0, watched=True), Video(yt_videoid="lXWrdlDEzQs", title="tmpEvCR4s", description="", publisher="UCxexYYtOetqikZqriLuTS-g", publish_date=1488343152.0, watched=True), Video(yt_videoid="cCnXsCQNkr8", title="tmp1rpsWK", description="", publisher="UCxexYYtOetqikZqriLuTS-g", publish_date=1488343046.0, watched=True), Video(yt_videoid="rSxVs0XeQa4", title="tmpc5Y2pd", description="", publisher="UCxexYYtOetqikZqriLuTS-g", publish_date=1488342015.0, watched=False), Video(yt_videoid="gQAsWrGfsrw", title="tmpn1M1Oa", description="", publisher="UCxexYYtOetqikZqriLuTS-g", publish_date=1488341324.0, watched=False), ] self.db_conn.session.execute("delete from video") self.db_conn.session.execute("delete from channel") self.db_conn.add_channel( Channel(displayname="Webdriver Torso", yt_channelid="UCsLiV4WJfkTEHH0b9PmRklw")) self.db_conn.add_channel( Channel(displayname="Webdriver YPP", yt_channelid="UCxexYYtOetqikZqriLuTS-g")) self.db_conn.add_videos(insert_list) self.video = self.db_conn.session.query(Video).filter( Video.title == "tmpIXBgjd").one() self.video_id = self.video.id
def setUp(self): self.current_dir = os.path.dirname(__file__) self.ytcc = Ytcc(os.path.join(self.current_dir, "data/ytcc_test.conf")) self.db_conn = self.ytcc.database
def import_(ytcc: core.Ytcc, file: Path): """Import YouTube subscriptions from OPML file. You can export your YouTube subscriptions at https://www.youtube.com/subscription_manager. """ ytcc.import_yt_opml(file)
def apply_filters(ytcc: core.Ytcc, tags: List[str], since: datetime, till: datetime, playlists: List[str], ids: List[int], watched: bool, unwatched: bool) -> None: if watched and unwatched: watched_filter = None elif watched and not unwatched: watched_filter = True else: watched_filter = False ytcc.set_tags_filter(tags) ytcc.set_date_begin_filter(since) ytcc.set_date_end_filter(till) ytcc.set_playlist_filter(playlists) ytcc.set_video_id_filter(ids) ytcc.set_watched_filter(watched_filter)
def setUp(self): self.current_dir = os.path.dirname(__file__) self.ytcc = Ytcc(os.path.join(self.current_dir, "data/ytcc_test.conf")) self.db_conn = self.ytcc.db self.db_conn.add_channel("Webdriver Torso", "UCsLiV4WJfkTEHH0b9PmRklw") self.db_conn.add_channel("Webdriver YPP", "UCxexYYtOetqikZqriLuTS-g")