rssVideos: Abstract with download process as well
This commit is contained in:
parent
07af9360fa
commit
2dce725ee5
|
@ -43,13 +43,6 @@ def configure_logging(args: configargparse.Namespace) -> None:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RVCommand(enum.Enum):
|
|
||||||
download = "download"
|
|
||||||
list = "list"
|
|
||||||
watch = "watch"
|
|
||||||
binge = "binge"
|
|
||||||
|
|
||||||
|
|
||||||
class RVElement:
|
class RVElement:
|
||||||
parent: "RVDatabase"
|
parent: "RVDatabase"
|
||||||
item: minidom.Element
|
item: minidom.Element
|
||||||
|
@ -150,16 +143,6 @@ class RVElement:
|
||||||
assert self.ytdl_infos
|
assert self.ytdl_infos
|
||||||
return self.ytdl_infos["duration"]
|
return self.ytdl_infos["duration"]
|
||||||
|
|
||||||
@property
|
|
||||||
def skip(self) -> bool:
|
|
||||||
assert self.is_video
|
|
||||||
if (
|
|
||||||
self.parent.args.max_duration > 0
|
|
||||||
and self.duration > self.parent.args.max_duration
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_video(self) -> bool:
|
def is_video(self) -> bool:
|
||||||
# Duration might be missing in playlists and stuff
|
# Duration might be missing in playlists and stuff
|
||||||
|
@ -194,9 +177,6 @@ class RVElement:
|
||||||
if self.was_downloaded:
|
if self.was_downloaded:
|
||||||
log.debug(f"Downloaded previously: {self}")
|
log.debug(f"Downloaded previously: {self}")
|
||||||
return
|
return
|
||||||
if self.skip:
|
|
||||||
log.debug(f"Skipped: {self}")
|
|
||||||
return
|
|
||||||
self.download()
|
self.download()
|
||||||
|
|
||||||
MATCHES_DURATION_MULTIPLIERS = {"s": 1, "m": 60, "h": 3600, None: 1}
|
MATCHES_DURATION_MULTIPLIERS = {"s": 1, "m": 60, "h": 3600, None: 1}
|
||||||
|
@ -320,9 +300,10 @@ class RVDatabase:
|
||||||
log.debug(f"Known: {element}")
|
log.debug(f"Known: {element}")
|
||||||
|
|
||||||
def clean(self) -> None:
|
def clean(self) -> None:
|
||||||
|
log.debug("Cleaning")
|
||||||
filenames = set()
|
filenames = set()
|
||||||
for element in self.elements:
|
for element in self.elements:
|
||||||
if element.is_video and not element.skip:
|
if element.is_video:
|
||||||
filenames.add(element.filename)
|
filenames.add(element.filename)
|
||||||
for file in os.listdir():
|
for file in os.listdir():
|
||||||
if file == RVDatabase.SAVE_FILE:
|
if file == RVDatabase.SAVE_FILE:
|
||||||
|
@ -337,10 +318,6 @@ class RVDatabase:
|
||||||
if not self.args.dryrun:
|
if not self.args.dryrun:
|
||||||
os.unlink(file)
|
os.unlink(file)
|
||||||
|
|
||||||
def act_all(self) -> None:
|
|
||||||
for element in self.elements:
|
|
||||||
element.act()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ytdl_opts(self) -> dict:
|
def ytdl_opts(self) -> dict:
|
||||||
return {"format": self.args.format, "allsubtitles": self.args.subtitles}
|
return {"format": self.args.format, "allsubtitles": self.args.subtitles}
|
||||||
|
@ -383,6 +360,8 @@ def get_args() -> configargparse.Namespace:
|
||||||
+ "an RSS aggregator",
|
+ "an RSS aggregator",
|
||||||
default_config_files=[defaultConfigPath],
|
default_config_files=[defaultConfigPath],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Runtime settings
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-v",
|
"-v",
|
||||||
"--verbosity",
|
"--verbosity",
|
||||||
|
@ -393,6 +372,16 @@ def get_args() -> configargparse.Namespace:
|
||||||
parser.add(
|
parser.add(
|
||||||
"-c", "--config", required=False, is_config_file=True, help="Configuration file"
|
"-c", "--config", required=False, is_config_file=True, help="Configuration file"
|
||||||
)
|
)
|
||||||
|
parser.add(
|
||||||
|
"-n",
|
||||||
|
"--dryrun",
|
||||||
|
help="Only pretend to do actions",
|
||||||
|
action="store_const",
|
||||||
|
const=True,
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Input/Output
|
||||||
parser.add(
|
parser.add(
|
||||||
"--feed",
|
"--feed",
|
||||||
help="URL of the RSS feed (must be public for now)",
|
help="URL of the RSS feed (must be public for now)",
|
||||||
|
@ -405,21 +394,30 @@ def get_args() -> configargparse.Namespace:
|
||||||
env_var="RSS_VIDEOS_VIDEO_DIR",
|
env_var="RSS_VIDEOS_VIDEO_DIR",
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Which videos
|
||||||
parser.add(
|
parser.add(
|
||||||
"-n",
|
"--order",
|
||||||
"--dryrun",
|
choices=("old", "new", "random"),
|
||||||
help="Do not download the videos",
|
default="old",
|
||||||
action="store_const",
|
help="Sorting mechanism",
|
||||||
const=True,
|
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
|
parser.add("--guid", help="Regex to filter guid")
|
||||||
|
parser.add("--creator", help="Regex to filter by creator")
|
||||||
|
parser.add("--title", help="Regex to filter by title")
|
||||||
|
parser.add("--link", help="Regex to filter by link")
|
||||||
|
parser.add("--duration", help="Comparative to filter by duration")
|
||||||
|
# TODO Envrionment variables
|
||||||
parser.add(
|
parser.add(
|
||||||
"--max-duration",
|
"--max-duration",
|
||||||
help="Skip video longer than this amount of seconds",
|
help="(Deprecated, use --duration instead)",
|
||||||
env_var="RSS_VIDEOS_MAX_DURATION",
|
env_var="RSS_VIDEOS_MAX_DURATION",
|
||||||
type=int,
|
type=int,
|
||||||
default=0,
|
default=0,
|
||||||
)
|
)
|
||||||
|
# TODO Allow to ask
|
||||||
|
|
||||||
|
# How to download
|
||||||
parser.add(
|
parser.add(
|
||||||
"--format",
|
"--format",
|
||||||
help="Use this format to download videos."
|
help="Use this format to download videos."
|
||||||
|
@ -434,39 +432,17 @@ def get_args() -> configargparse.Namespace:
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.set_defaults(subcommand=RVCommand.download)
|
parser.add(
|
||||||
subparsers = parser.add_subparsers(title="subcommand")
|
"action",
|
||||||
|
|
||||||
sc_download = subparsers.add_parser("download")
|
|
||||||
sc_download.set_defaults(subcommand=RVCommand.download)
|
|
||||||
|
|
||||||
sc_list = subparsers.add_parser("list")
|
|
||||||
sc_list.set_defaults(subcommand=RVCommand.list)
|
|
||||||
|
|
||||||
sc_watch = subparsers.add_parser("watch")
|
|
||||||
sc_watch.set_defaults(subcommand=RVCommand.watch)
|
|
||||||
|
|
||||||
sc_binge = subparsers.add_parser("binge")
|
|
||||||
sc_binge.set_defaults(subcommand=RVCommand.binge)
|
|
||||||
|
|
||||||
# Common arguments for filtering
|
|
||||||
for sc in (sc_list, sc_watch, sc_binge):
|
|
||||||
sc.add(
|
|
||||||
"order",
|
|
||||||
choices=("old", "new", "random"),
|
|
||||||
nargs="?",
|
nargs="?",
|
||||||
default="old",
|
choices=("download", "list", "watch", "binge"),
|
||||||
help="Sorting mechanism",
|
default="download",
|
||||||
)
|
)
|
||||||
sc.add("--guid", help="Regex to filter guid")
|
|
||||||
sc.add("--creator", help="Regex to filter by creator")
|
|
||||||
sc.add("--title", help="Regex to filter by title")
|
|
||||||
sc.add("--link", help="Regex to filter by link")
|
|
||||||
sc.add("--duration", help="Comparative to filter by duration")
|
|
||||||
# TODO Allow to ask
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
args.videos = os.path.realpath(os.path.expanduser(args.videos))
|
args.videos = os.path.realpath(os.path.expanduser(args.videos))
|
||||||
|
if not args.duration and args.max_duration:
|
||||||
|
args.duration = str(args.max_duration)
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
@ -483,7 +459,7 @@ def main() -> None:
|
||||||
try:
|
try:
|
||||||
database.read_feed()
|
database.read_feed()
|
||||||
except urllib.error.URLError as err:
|
except urllib.error.URLError as err:
|
||||||
if args.subcommand == RVCommand.download or not cache:
|
if args.action == "download" or not cache:
|
||||||
raise err
|
raise err
|
||||||
else:
|
else:
|
||||||
log.warning("Cannot fetch RSS feed, using cached feed.", err)
|
log.warning("Cannot fetch RSS feed, using cached feed.", err)
|
||||||
|
@ -491,19 +467,19 @@ def main() -> None:
|
||||||
if cache:
|
if cache:
|
||||||
database.salvage_cache(cache)
|
database.salvage_cache(cache)
|
||||||
|
|
||||||
log.debug(f"Running subcommand")
|
if args.action == "download":
|
||||||
|
# TODO Clean on watch? / cache import with missing video / all researched
|
||||||
if args.subcommand == RVCommand.download:
|
|
||||||
database.clean()
|
database.clean()
|
||||||
database.act_all()
|
|
||||||
|
|
||||||
elif args.subcommand in (RVCommand.list, RVCommand.watch, RVCommand.binge):
|
log.debug(f"Running action")
|
||||||
for element in database.filter(args):
|
for element in database.filter(args):
|
||||||
if args.subcommand == RVCommand.list:
|
if args.action == "download":
|
||||||
|
element.act()
|
||||||
|
elif args.action == "list":
|
||||||
print(element)
|
print(element)
|
||||||
elif args.subcommand in (RVCommand.watch, RVCommand.binge):
|
elif args.action in ("watch", "binge"):
|
||||||
element.watch()
|
element.watch()
|
||||||
if args.subcommand == RVCommand.watch:
|
if args.action == "watch":
|
||||||
break
|
break
|
||||||
|
|
||||||
database.save()
|
database.save()
|
||||||
|
|
Loading…
Reference in a new issue