Skip to content

Commit fa70ddf

Browse files
committed
CLI: Allow multiple files for directly passed video files
1 parent 7b89184 commit fa70ddf

File tree

2 files changed

+101
-43
lines changed

2 files changed

+101
-43
lines changed

vspreview/init.py

Lines changed: 80 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,32 @@
1313
from PyQt6.QtWidgets import QApplication
1414

1515
from .core.logger import set_log_level, setup_logger
16+
1617
# import vsenv as early as possible:
1718
# This is so other modules cannot accidentally use and lock us into a different policy.
1819
from .core.vsenv import set_vsengine_loop
1920
from .main import MainWindow
2021
from .plugins import get_installed_plugins
2122
from .plugins.abstract import FileResolverPlugin, ResolvedScript
22-
from .plugins.install import install_plugins, plugins_commands, print_available_plugins, uninstall_plugins
23+
from .plugins.install import (
24+
install_plugins,
25+
plugins_commands,
26+
print_available_plugins,
27+
uninstall_plugins,
28+
)
2329

24-
__all__ = [
25-
'main'
26-
]
30+
__all__ = ["main"]
2731

2832

29-
def get_resolved_script(filepath: Path) -> tuple[ResolvedScript, FileResolverPlugin | None] | int:
33+
def get_resolved_script(
34+
filepath: Path,
35+
) -> tuple[ResolvedScript, FileResolverPlugin | None] | int:
3036
for plugin in get_installed_plugins(FileResolverPlugin, False).values():
3137
if plugin.can_run_file(filepath):
3238
return plugin.resolve_path(filepath), plugin
3339

3440
if not filepath.exists():
35-
logging.error('Script or file path is invalid.')
41+
logging.error("Script or file path is invalid.")
3642
return 1
3743

3844
return ResolvedScript(filepath, str(filepath)), None
@@ -41,37 +47,53 @@ def get_resolved_script(filepath: Path) -> tuple[ResolvedScript, FileResolverPlu
4147
def main(_args: Sequence[str] | None = None, no_exit: bool = False) -> int:
4248
from .utils import exit_func
4349

44-
parser = ArgumentParser(prog='VSPreview')
50+
parser = ArgumentParser(prog="VSPreview")
4551
parser.add_argument(
46-
'script_path_or_command', type=str, nargs='?',
47-
help=f'Path to Vapoursynth script or plugins command {",".join(plugins_commands)}'
52+
"script_path_or_command",
53+
type=str,
54+
nargs="?",
55+
help=f'Path to Vapoursynth script, video file(s) or plugins command {", ".join(plugins_commands)}',
4856
)
4957
parser.add_argument(
50-
'plugins', type=str, nargs='*',
51-
help=f'Plugins to {"/".join(plugins_commands[:-1])} or arguments to pass to the script environment.'
58+
"plugins",
59+
type=str,
60+
nargs="*",
61+
help=f'Plugins to {"/".join(plugins_commands[:-1])} or arguments to pass to the script environment.',
5262
)
63+
parser.add_argument("--version", "-v", action="version", version="%(prog)s 0.2b")
5364
parser.add_argument(
54-
'--version', '-v', action='version', version='%(prog)s 0.2b'
65+
"--preserve-cwd",
66+
"-c",
67+
action="store_true",
68+
help="do not chdir to script parent directory",
5569
)
5670
parser.add_argument(
57-
'--preserve-cwd', '-c', action='store_true', help='do not chdir to script parent directory'
71+
"-f", "--frame", type=int, help="Frame to load initially (defaults to 0)"
5872
)
59-
parser.add_argument('-f', '--frame', type=int, help='Frame to load initially (defaults to 0)')
6073
parser.add_argument(
61-
'--vscode-setup', type=str, choices=['override', 'append', 'ignore'], nargs='?', const='append',
62-
help='Installs launch settings in cwd\'s .vscode'
74+
"--vscode-setup",
75+
type=str,
76+
choices=["override", "append", "ignore"],
77+
nargs="?",
78+
const="append",
79+
help="Installs launch settings in cwd's .vscode",
6380
)
6481
parser.add_argument(
6582
"--verbose", help="Set the logging to verbose.", action="store_true"
6683
)
6784
parser.add_argument(
68-
"--force", help="Force the install of a plugin even if it exists already.", action="store_true"
85+
"--force",
86+
help="Force the install of a plugin even if it exists already.",
87+
action="store_true",
6988
)
7089
parser.add_argument(
7190
"--no-deps", help="Ignore downloading dependencies.", action="store_true"
7291
)
7392
parser.add_argument(
74-
"--force-storage", help="Force override or local/global storage.", action="store_true", default=False
93+
"--force-storage",
94+
help="Force override or local/global storage.",
95+
action="store_true",
96+
default=False,
7597
)
7698

7799
args = parser.parse_args(_args)
@@ -80,6 +102,7 @@ def main(_args: Sequence[str] | None = None, no_exit: bool = False) -> int:
80102

81103
if args.verbose:
82104
from vstools import VSDebug
105+
83106
set_log_level(logging.DEBUG, logging.DEBUG)
84107
VSDebug(use_logging=True)
85108
else:
@@ -94,32 +117,34 @@ def main(_args: Sequence[str] | None = None, no_exit: bool = False) -> int:
94117

95118
script_path_or_command = args.script_path_or_command
96119

97-
if not script_path_or_command and not (args.plugins and (script_path_or_command := next(iter(args.plugins)))):
98-
logging.error('Script path required.')
120+
if not script_path_or_command and not (
121+
args.plugins and (script_path_or_command := next(iter(args.plugins)))
122+
):
123+
logging.error("Script/Video path required.")
99124
return exit_func(1, no_exit)
100125

101-
if script_path_or_command.startswith('--') and args.plugins:
126+
if script_path_or_command.startswith("--") and args.plugins:
102127
script_path_or_command = args.plugins.pop()
103128
args.plugins = [args.script_path_or_command, *args.plugins]
104129

105130
if (command := script_path_or_command) in plugins_commands:
106-
if command == 'available':
131+
if command == "available":
107132
print_available_plugins()
108133
return exit_func(0, no_exit)
109134

110135
if not args.plugins:
111-
logging.error('You must provide at least one plugin!')
136+
logging.error("You must provide at least one plugin!")
112137
return exit_func(1, no_exit)
113138

114139
set_log_level(logging.INFO)
115140

116141
plugins = list(args.plugins)
117142

118-
if command == 'install':
143+
if command == "install":
119144
install_plugins(plugins, args.force, args.no_deps)
120-
elif command == 'uninstall':
145+
elif command == "uninstall":
121146
uninstall_plugins(plugins)
122-
elif command == 'update':
147+
elif command == "update":
123148
uninstall_plugins(plugins, True)
124149
install_plugins(plugins, True, args.no_deps)
125150

@@ -132,16 +157,24 @@ def main(_args: Sequence[str] | None = None, no_exit: bool = False) -> int:
132157

133158
script, file_resolve_plugin = script_or_err
134159

160+
if (
161+
file_resolve_plugin
162+
and hasattr(file_resolve_plugin, "_config")
163+
and file_resolve_plugin._config.namespace == "dev.setsugen.vssource_load"
164+
):
165+
setattr(args, "preserve_cwd", True)
166+
135167
if not args.preserve_cwd:
136168
os.chdir(script.path.parent)
137169

138-
first_run = not hasattr(main, 'app')
170+
first_run = not hasattr(main, "app")
139171

140172
if first_run:
141173
main.app = QApplication(sys.argv)
142174
set_vsengine_loop()
143175
else:
144176
from .core.vsenv import get_current_environment, make_environment
177+
145178
make_environment()
146179
get_current_environment().use()
147180

@@ -151,7 +184,7 @@ def main(_args: Sequence[str] | None = None, no_exit: bool = False) -> int:
151184

152185
def _parse_arg(kv: str) -> tuple[str, str | int | float]:
153186
v: str | int | float
154-
k, v = kv.split('=', maxsplit=1)
187+
k, v = kv.split("=", maxsplit=1)
155188

156189
try:
157190
v = int(v)
@@ -161,16 +194,30 @@ def _parse_arg(kv: str) -> tuple[str, str | int | float]:
161194
except ValueError:
162195
...
163196

164-
return k.strip('--'), v
197+
return k.strip("--"), v
165198

166199
if args.plugins:
167-
arguments |= {k: v for k, v in map(_parse_arg, args.plugins)}
200+
if file_resolve_plugin._config.namespace == "dev.setsugen.vssource_load":
201+
additional_files = list[Path](
202+
Path(filepath).resolve() for filepath in args.plugins
203+
)
204+
arguments.update(additional_files=additional_files)
205+
else:
206+
arguments |= {k: v for k, v in map(_parse_arg, args.plugins)}
168207

169208
main.main_window = MainWindow(
170-
Path(os.getcwd()) if args.preserve_cwd else script.path.parent, no_exit, script.reload_enabled, args.force_storage
209+
Path(os.getcwd()) if args.preserve_cwd else script.path.parent,
210+
no_exit,
211+
script.reload_enabled,
212+
args.force_storage,
171213
)
172214
main.main_window.load_script(
173-
script.path, list(arguments.items()), False, args.frame or None, script.display_name, file_resolve_plugin
215+
script.path,
216+
list(arguments.items()),
217+
False,
218+
args.frame or None,
219+
script.display_name,
220+
file_resolve_plugin,
174221
)
175222

176223
ret_code = main.app.exec()
@@ -185,5 +232,5 @@ def _parse_arg(kv: str) -> tuple[str, str | int | float]:
185232
return exit_func(ret_code, no_exit)
186233

187234

188-
if __name__ == '__main__':
235+
if __name__ == "__main__":
189236
main()

vspreview/plugins/builtins/vssource_load.ppy

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ from __future__ import annotations
33
from pathlib import Path
44
from typing import TYPE_CHECKING
55

6-
if __name__ != '__vspreview__':
7-
from vspreview.plugins import FileResolvePluginConfig, FileResolverPlugin, ResolvedScript
6+
if __name__ != "__vspreview__":
7+
from vspreview.plugins import (
8+
FileResolvePluginConfig,
9+
FileResolverPlugin,
10+
ResolvedScript,
11+
)
812

9-
__all__ = [
10-
'FileResolveWithVSSource'
11-
]
13+
__all__ = ["FileResolveWithVSSource"]
1214

1315
class FileResolveWithVSSource(FileResolverPlugin):
14-
_config = FileResolvePluginConfig('dev.setsugen.vssource_load', 'VSSource Loader')
16+
_config = FileResolvePluginConfig(
17+
"dev.setsugen.vssource_load", "VSSource Loader"
18+
)
1519

1620
def can_run_file(self, filepath: Path) -> bool:
1721
if filepath.is_dir():
@@ -30,17 +34,20 @@ if __name__ != '__vspreview__':
3034
return False
3135

3236
def resolve_path(self, filepath: Path) -> ResolvedScript:
33-
return ResolvedScript(Path(__file__), str(filepath), dict(filepath=filepath), False)
37+
return ResolvedScript(
38+
Path(__file__), str(filepath), dict(filepath=filepath), False
39+
)
3440
else:
3541
from vssource import parse_video_filepath, source
3642
from vstools import set_output
3743

3844
if TYPE_CHECKING:
3945
filepath: Path = Path()
40-
pattern: str = ''
46+
pattern: str = ""
47+
additional_files: list[Path] | None = None
4148
else:
42-
if 'pattern' not in locals():
43-
pattern = '*'
49+
if "pattern" not in locals():
50+
pattern = "*"
4451

4552
if filepath.is_dir():
4653
for file in filepath.glob(pattern):
@@ -51,3 +58,7 @@ else:
5158
...
5259
else:
5360
set_output(source(filepath), filepath.name)
61+
62+
if "additional_files" in locals():
63+
for file in additional_files:
64+
set_output(source(file), file.name)

0 commit comments

Comments
 (0)