summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Fink2025-03-05 08:13:23 +0100
committerDennis Fink2025-03-05 08:13:23 +0100
commit3b28310412b7d8e38a91c81351e6b2ee61065fda (patch)
treee749e8e57a7348f818512e5da90493b32ec754b9
parent01f53edc8a28b9a447812ea74115ff234d0a3f36 (diff)
downloadpatternutils-3b28310412b7d8e38a91c81351e6b2ee61065fda.tar.gz
patternutils-3b28310412b7d8e38a91c81351e6b2ee61065fda.zip
Add pmediainfo
-rw-r--r--patternutils/commands/pmediainfo.py98
-rw-r--r--pyproject.toml4
2 files changed, 102 insertions, 0 deletions
diff --git a/patternutils/commands/pmediainfo.py b/patternutils/commands/pmediainfo.py
new file mode 100644
index 0000000..0fa7b18
--- /dev/null
+++ b/patternutils/commands/pmediainfo.py
@@ -0,0 +1,98 @@
+import functools
+import itertools
+import os.path
+from typing import Any, Generator, Iterator, Optional
+
+import click
+from pymediainfo import MediaInfo
+
+from .. import config
+from .. import match as mat
+from .. import utils
+
+
+def apply_mediainfo(
+ walk_function: Iterator[os.DirEntry[str]],
+) -> Generator[Optional[dict[str, Any]], None, None]:
+ for f in walk_function:
+ media_info_raw = MediaInfo.parse(os.path.abspath(f))
+ if len(media_info_raw.tracks) <= 1:
+ click.secho(f"{f.name} cannot be parsed by mediainfo", fg="red", err=True)
+ yield None
+ else:
+ media_info = media_info_raw.to_data()
+ media_info["_path"] = f.path
+ media_info["_name"] = f.name
+ media_info["_abspath"] = os.path.abspath(f.path)
+ media_info["_realpath"] = os.path.realpath(f.path)
+ media_info["_relpath"] = os.path.relpath(f.path)
+ yield media_info
+
+
+@click.command(context_settings={"help_option_names": ("-h", "--help", "-?")})
+@click.option("-d", "--directory", multiple=True, default=["./"])
+@click.option(
+ "-r",
+ "--recursive",
+ is_flag=True,
+ default=False,
+ help="search directories recursively",
+)
+@click.option(
+ "--abort-on-unparseable",
+ is_flag=True,
+ default=False,
+ help="exit if a file cannot be parsed by mediainfo",
+)
+@click.option(
+ "--stream",
+ is_flag=True,
+ default=False,
+ help="Output a stream of objects instead a list of objects",
+)
+@click.option(
+ "--human-readable",
+ is_flag=True,
+ default=False,
+ help="output the JSON in a human readable format",
+)
+@click.option(
+ "-v", "--verbose", is_flag=True, default=False, help="explain what is being done"
+)
+@click.version_option()
+def pmediainfo(
+ directory: list[str],
+ recursive: bool,
+ abort_on_unparseable: bool,
+ stream: bool,
+ human_readable: bool,
+ verbose: bool,
+) -> None:
+ # Monkey patch walk function to include commandline options
+ walk_function = functools.partial(
+ utils.walk, recursive=recursive, match_directories=False
+ )
+ new_walk = itertools.chain.from_iterable(map(walk_function, directory))
+
+ has_unparseable_files = False
+ parsed_data = []
+
+ for media_info in apply_mediainfo(new_walk):
+ if media_info is None:
+ has_unparseable_files = True
+ if stream and abort_on_unparseable:
+ raise SystemExit
+ else:
+ if stream:
+ click.echo(utils.json_dumps(media_info, human_readable))
+ else:
+ parsed_data.append(media_info)
+
+ if not stream:
+ if has_unparseable_files and abort_on_unparseable:
+ raise SystemExit
+ click.echo(utils.json_dumps(parsed_data, human_readable))
+
+
+if __name__ == "__main__":
+ pmediainfo()
diff --git a/pyproject.toml b/pyproject.toml
index 265aa8c..f6942c2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,6 +24,9 @@ pygments = [
prss = [
"feedparser >=6.0.8, <7.0.0",
]
+pmediainfo = [
+ "pymediainfo >=6.1.0, <7.0.0",
+]
[project.scripts]
pmatch = "patternutils.commands.pmatch:pmatch"
@@ -33,6 +36,7 @@ tln = "patternutils.commands.tln:tln"
patterncfg = "patternutils.commands.patterncfg:patterncfg"
prss = "patternutils.commands.prss:prss"
pjson = "patternutils.commands.pjson:pjson"
+pmediainfo = "patternutils.commands.pmediainfo:pmediainfo"
[dependency-groups]
dev = [