aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rwxr-xr-xlater89
-rw-r--r--later.120
2 files changed, 87 insertions, 22 deletions
diff --git a/later b/later
index a5a25c8..3eb9ea0 100755
--- a/later
+++ b/later
@@ -1,13 +1,14 @@
#!/usr/bin/env python3
-import argparse
import datetime
+import getopt
import json
import os
import re
import sys
-from dataclasses import dataclass
+from dataclasses import dataclass, field
from datetime import datetime as dt
+from typing import Protocol
class YTDLPLogger:
@@ -25,6 +26,18 @@ def exit(message=""):
sys.exit(f"later: {message}" if message else 0)
+def usage(message=""):
+ lines = []
+ if message:
+ lines.append(f"later: {message}")
+ lines.append("")
+
+ lines.append("usage: later [options] [list]")
+ lines.append("options: [-u | --update-titles]")
+
+ sys.exit("\n".join(lines))
+
+
def get_xdg(directory, fallback):
env = f"XDG_{directory.upper()}_HOME"
if env in os.environ:
@@ -138,6 +151,54 @@ class TitleMap:
exit(f"cannot write title cache: {err}")
+class CommandFunction(Protocol):
+ def __call__(self, args: "Arguments", title_map: TitleMap) -> None:
+ pass
+
+
+@dataclass
+class Command:
+ name: str
+ fun: CommandFunction
+ implies_list: bool = True
+ args: bool = True
+
+
+@dataclass
+class Arguments:
+ command: Command
+ update_titles: bool = False
+ rest: list[str] = field(default_factory=list)
+
+
+def parse_args(argv, commands, default):
+ try:
+ options, args = getopt.gnu_getopt(argv, "u", "update-titles")
+ except getopt.GetoptError as e:
+ usage(e)
+
+ parsed_args = Arguments(command=commands[default])
+
+ for option in options:
+ match option:
+ case ("-u", _) | ("--update-titles", _):
+ parsed_args.update_titles = True
+
+ if args:
+ if args[0] in commands:
+ parsed_args.command = commands[args.pop(0)]
+
+ parsed_args.rest = args
+
+ if parsed_args.rest and not parsed_args.command.args:
+ usage(f'unexpected argument for "{parsed_args.command.name}"')
+
+ if not parsed_args.rest and parsed_args.command.args:
+ usage(f'"{parsed_args.command.name}" requires an argument')
+
+ return parsed_args
+
+
def entries(title_map):
def get_mtime(entry):
return entry.stat().st_mtime
@@ -163,20 +224,20 @@ def entries(title_map):
yield WatchLaterEntry(name=name, path=entry.path, mtime=mtime)
-parser = argparse.ArgumentParser(
- prog="later", description="List mpv's watch_later entries"
-)
-parser.add_argument(
- "-u",
- "--update-titles",
- action="store_true",
- help="update titles of videos using yt-dlp",
-)
-args = parser.parse_args()
+def list_entries(args, title_map):
+ for entry in entries(title_map):
+ print(entry.format(title_map))
+
+
+commands = {"list": Command("list", list_entries, implies_list=False, args=False)}
+
+args = parse_args(sys.argv[1:], commands, "list")
title_map = TitleMap(title_map_file, update=args.update_titles)
-for entry in entries(title_map):
- print(entry.format(title_map))
+args.command.fun(args=args, title_map=title_map)
+
+if args.command.implies_list:
+ list_entries(args, title_map)
title_map.maybe_commit()
diff --git a/later.1 b/later.1
index 4464da5..a4be6b0 100644
--- a/later.1
+++ b/later.1
@@ -1,4 +1,4 @@
-.Dd September 20, 2024
+.Dd October 26, 2024
.Dt LATER 1
.Os
.Sh NAME
@@ -6,12 +6,11 @@
.Nd list mpv's watch_later entries
.Sh SYNOPSIS
.Nm
-.Op Fl u | \-update-titles
-.Nm
-.Fl h | \-help
+.Op options
+.Op Ic list
.Sh DESCRIPTION
.Nm
-lists all watch_later entries as saved by
+is a program to manage watch_later entries as created by
.Xr mpv 1 .
.Pp
In order to display file names and URLs for an entry, the
@@ -19,12 +18,17 @@ In order to display file names and URLs for an entry, the
option must be set in
.Xr mpv 1 .
.Pp
-The options are as follows:
+The following options can be given for any command:
.Bl -tag -width "-h, --update-titles"
.It Fl u , Fl \-update-titles
update titles of videos using yt-dlp
-.It Fl h , Fl \-help
-show a concise help message
+.El
+.Pp
+The commands are as follows:
+.Bl -tag -width Ds
+.It Sy list
+Lists all watch_later entries.
+This command is implied if there are no remaining arguments.
.El
.Sh FILES
.Bl -tag -width "1"