Skip to content

Commit 7fd16c6

Browse files
GH-37: Implement a facade with a simple interface (GH-38)
* Refactor the structure of files * Implement the high-level Generator facade
1 parent a391002 commit 7fd16c6

File tree

11 files changed

+108
-87
lines changed

11 files changed

+108
-87
lines changed

thumbnails/__init__.py renamed to src/thumbnails/__init__.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,6 @@
2020
from .thumbnail import ThumbnailJSON
2121
from .thumbnail import ThumbnailVTT
2222
from .thumbnail import register_thumbnail
23-
from .video import Video
2423

25-
__version__ = "0.0.1"
26-
__all__ = (
27-
"Thumbnail",
28-
"ThumbnailExistsError",
29-
"ThumbnailFactory",
30-
"ThumbnailJSON",
31-
"ThumbnailVTT",
32-
"register_thumbnail",
33-
"Video",
34-
)
24+
__version__ = "0.1.1"
25+
__all__ = []

src/thumbnails/__main__.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from .cli import cli
2+
from .generator import Generator
3+
4+
5+
@cli
6+
def main(inputs=None, **options):
7+
"""This command delegates the functionality of the `thumbnails` Python package
8+
to the CLI. Read more at https://github.com/pysnippet/thumbnails#readme."""
9+
10+
generator = Generator(inputs)
11+
12+
for option, value in options.items():
13+
setattr(generator, option, value)
14+
15+
generator.generate()
16+
17+
18+
if __name__ == "__main__":
19+
main()

thumbnails/cli.py renamed to src/thumbnails/cli.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44

55
from . import ThumbnailFactory
66
from . import __version__
7-
8-
# Default values of the particular option of the CLI.
9-
DEFAULT_BASE = ""
10-
DEFAULT_SKIP = False
11-
DEFAULT_OUTPUT = None
12-
DEFAULT_FORMAT = "vtt"
13-
DEFAULT_COMPRESS = 1.0
14-
DEFAULT_INTERVAL = 1.0
7+
from .constants import DEFAULT_BASE
8+
from .constants import DEFAULT_COMPRESS
9+
from .constants import DEFAULT_FORMAT
10+
from .constants import DEFAULT_INTERVAL
11+
from .constants import DEFAULT_OUTPUT
12+
from .constants import DEFAULT_SKIP
1513

1614
# Help messages of the particular option of the CLI.
1715
HELP_BASE = "The prefix of the thumbnails path can be customized."

src/thumbnails/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
DEFAULT_BASE = ""
2+
DEFAULT_SKIP = False
3+
DEFAULT_OUTPUT = None
4+
DEFAULT_FORMAT = "vtt"
5+
DEFAULT_COMPRESS = 1.0
6+
DEFAULT_INTERVAL = 1.0
File renamed without changes.
File renamed without changes.

src/thumbnails/generator.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import concurrent.futures
2+
import functools
3+
import itertools
4+
import os
5+
6+
import click
7+
8+
from . import ThumbnailExistsError
9+
from . import ThumbnailFactory
10+
from .constants import DEFAULT_BASE
11+
from .constants import DEFAULT_COMPRESS
12+
from .constants import DEFAULT_FORMAT
13+
from .constants import DEFAULT_INTERVAL
14+
from .constants import DEFAULT_OUTPUT
15+
from .constants import DEFAULT_SKIP
16+
from .pathtools import listdir
17+
from .pathtools import metadata_path
18+
from .video import Video
19+
20+
21+
class Generator:
22+
"""High-level class for generating thumbnails."""
23+
24+
def __init__(self, inputs):
25+
if all(map(os.path.isfile, inputs)):
26+
self.inputs = set(map(os.path.abspath, inputs))
27+
elif all(map(os.path.isdir, inputs)):
28+
self.inputs = set(itertools.chain(*map(listdir, inputs)))
29+
else:
30+
exit("Inputs must be all files or all directories.")
31+
32+
self.base = DEFAULT_BASE
33+
self.skip = DEFAULT_SKIP
34+
self.output = DEFAULT_OUTPUT
35+
self.format = DEFAULT_FORMAT
36+
self.compress = DEFAULT_COMPRESS
37+
self.interval = DEFAULT_INTERVAL
38+
39+
@staticmethod
40+
def worker(video, fmt, base, skip, output):
41+
"""Executes the required workflows for generating a thumbnail."""
42+
try:
43+
thumbnail = ThumbnailFactory.create_thumbnail(fmt, video, base, skip, output)
44+
except ThumbnailExistsError:
45+
return print("Skipping '%s'" % os.path.relpath(video.filepath))
46+
thumbnail.prepare_frames()
47+
thumbnail.generate()
48+
49+
def generate(self):
50+
self.inputs = dict(zip(map(lambda i: metadata_path(i, self.output, self.format), self.inputs), self.inputs))
51+
52+
if not self.skip and any(map(os.path.exists, self.inputs.keys())):
53+
self.skip = not click.confirm("Do you want to overwrite already existing files?")
54+
55+
with concurrent.futures.ThreadPoolExecutor() as executor:
56+
videos = executor.map(
57+
functools.partial(
58+
Video,
59+
compress=self.compress,
60+
interval=self.interval,
61+
),
62+
self.inputs.values(),
63+
)
64+
65+
with concurrent.futures.ProcessPoolExecutor() as executor:
66+
executor.map(
67+
functools.partial(
68+
self.worker,
69+
fmt=self.format,
70+
base=self.base,
71+
skip=self.skip,
72+
output=self.output,
73+
),
74+
videos,
75+
)
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)