Browse Source

Move cli handling to __main__

pull/498/head
Simon Conseil 3 years ago
parent
commit
df525a1743
  1. 1
      docs/conf.py
  2. 2
      pyproject.toml
  3. 281
      src/sigal/__init__.py
  4. 305
      src/sigal/__main__.py
  5. 16
      src/sigal/gallery.py
  6. 32
      src/sigal/utils.py
  7. 13
      tests/test_cli.py
  8. 2
      tests/test_compress_assets_plugin.py
  9. 2
      tests/test_encrypt.py
  10. 2
      tests/test_image.py
  11. 2
      tests/test_plugins.py
  12. 45
      tests/test_utils.py
  13. 2
      tests/test_zip.py

1
docs/conf.py

@ -2,6 +2,7 @@ import os
import sys
import alabaster
from sigal import __version__
# If extensions (or modules to document with autodoc) are in another directory,

2
pyproject.toml

@ -41,7 +41,7 @@ tests = ["pytest", "pytest-cov"]
docs = ["Sphinx>=4.1.0", "alabaster", "cryptography"]
[project.scripts]
sigal = "sigal:main"
sigal = "sigal.__main__:main"
[project.urls]
repository = "https://github.com/saimn/sigal"

281
src/sigal/__init__.py

@ -18,23 +18,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import importlib
import locale
import logging
import os
import pathlib
import socketserver
import sys
import time
from http import server
import click
from click import argument, option
from .gallery import Gallery
from .log import init_logging
from .settings import read_settings
from .utils import copy
try:
from .version import __version__
@ -43,267 +26,3 @@ except ImportError:
__version__ = None
__url__ = "https://github.com/saimn/sigal"
_DEFAULT_CONFIG_FILE = "sigal.conf.py"
@click.group()
@click.version_option(version=__version__)
def main():
"""Sigal - Simple Static Gallery Generator.
Sigal is yet another python script to prepare a static gallery of images:
resize images, create thumbnails with some options, generate html pages.
"""
@main.command()
@argument("path", default=_DEFAULT_CONFIG_FILE)
def init(path):
"""Copy a sample config file in the current directory (default to
'sigal.conf.py'), or use the provided 'path'."""
path = pathlib.Path(path)
if path.exists():
print("Found an existing config file, will abort to keep it safe.")
sys.exit(1)
conf = pathlib.Path(__file__).parent / "templates" / "sigal.conf.py"
path.write_text(conf.read_text())
print(f"Sample config file created: {path}")
@main.command()
@argument("source", required=False)
@argument("destination", required=False)
@option("-f", "--force", is_flag=True, help="Force the reprocessing of existing images")
@option("-a", "--force-album", multiple=True, help="Force reprocessing of any album that matches the given pattern. Patterns containing no wildcards will be matched against only the album name. (-a 'My Pictures/* Pics' -a 'Festival')")
@option("-v", "--verbose", is_flag=True, help="Show all messages")
@option(
"-d",
"--debug",
is_flag=True,
help=(
"Show all messages, including debug messages. Also raise "
"exception if an error happen when processing files."
),
)
@option("-q", "--quiet", is_flag=True, help="Show only error messages")
@option(
"-c",
"--config",
default=_DEFAULT_CONFIG_FILE,
show_default=True,
help="Configuration file",
)
@option(
"-t",
"--theme",
help=(
"Specify a theme directory, or a theme name for the themes included with Sigal"
),
)
@option("--title", help="Title of the gallery (overrides the title setting.")
@option("-n", "--ncpu", help="Number of cpu to use (default: all)")
def build(
source, destination, debug, verbose, quiet, force, force_album, config, theme, title, ncpu
):
"""Run sigal to process a directory.
If provided, 'source', 'destination' and 'theme' will override the
corresponding values from the settings file.
"""
if sum([debug, verbose, quiet]) > 1:
sys.exit("Only one option of debug, verbose and quiet should be used")
if debug:
level = logging.DEBUG
elif verbose:
level = logging.INFO
elif quiet:
level = logging.ERROR
else:
level = logging.WARNING
init_logging(__name__, level=level)
logger = logging.getLogger(__name__)
if not os.path.isfile(config):
logger.error("Settings file not found: %s", config)
sys.exit(1)
start_time = time.time()
settings = read_settings(config)
for key in ("source", "destination", "theme"):
arg = locals()[key]
if arg is not None:
settings[key] = os.path.abspath(arg)
logger.info("%12s : %s", key.capitalize(), settings[key])
if not settings["source"] or not os.path.isdir(settings["source"]):
logger.error("Input directory not found: %s", settings["source"])
sys.exit(1)
# on windows os.path.relpath raises a ValueError if the two paths are on
# different drives, in that case we just ignore the exception as the two
# paths are anyway not relative
relative_check = True
try:
relative_check = os.path.relpath(
settings["destination"], settings["source"]
).startswith("..")
except ValueError:
pass
if not relative_check:
logger.error("Output directory should be outside of the input directory.")
sys.exit(1)
if title:
settings["title"] = title
locale.setlocale(locale.LC_ALL, settings["locale"])
init_plugins(settings)
gal = Gallery(settings, ncpu=ncpu, quiet=quiet)
gal.build(force=force_album if len(force_album) else force)
# copy extra files
for src, dst in settings["files_to_copy"]:
src = os.path.join(settings["source"], src)
dst = os.path.join(settings["destination"], dst)
logger.debug("Copy %s to %s", src, dst)
copy(src, dst, symlink=settings["orig_link"], rellink=settings["rel_link"])
stats = gal.stats
def format_stats(_type):
opt = [
"{} {}".format(stats[_type + "_" + subtype], subtype)
for subtype in ("skipped", "failed")
if stats[_type + "_" + subtype] > 0
]
opt = " ({})".format(", ".join(opt)) if opt else ""
return f"{stats[_type]} {_type}s{opt}"
if not quiet:
stats_str = ""
types = sorted({t.rsplit("_", 1)[0] for t in stats})
for t in types[:-1]:
stats_str += f"{format_stats(t)} and "
stats_str += f"{format_stats(types[-1])}"
end_time = time.time() - start_time
print(f"Done, processed {stats_str} in {end_time:.2f} seconds.")
def init_plugins(settings):
"""Load plugins and call register()."""
logger = logging.getLogger(__name__)
logger.debug("Plugin paths: %s", settings["plugin_paths"])
for path in settings["plugin_paths"]:
sys.path.insert(0, path)
for plugin in settings["plugins"]:
try:
if isinstance(plugin, str):
mod = importlib.import_module(plugin)
mod.register(settings)
else:
plugin.register(settings)
logger.debug("Registered plugin %s", plugin)
except Exception as e:
logger.error("Failed to load plugin %s: %r", plugin, e)
for path in settings["plugin_paths"]:
sys.path.remove(path)
@main.command()
@argument("destination", default="_build")
@option("-p", "--port", help="Port to use", default=8000)
@option(
"-c",
"--config",
default=_DEFAULT_CONFIG_FILE,
show_default=True,
help="Configuration file",
)
def serve(destination, port, config):
"""Run a simple web server."""
if os.path.exists(destination):
pass
elif os.path.exists(config):
settings = read_settings(config)
destination = settings.get("destination")
if not os.path.exists(destination):
sys.stderr.write(
f"The '{destination}' directory doesn't exist, maybe try building"
" first?\n"
)
sys.exit(1)
else:
sys.stderr.write(
f"The {destination} directory doesn't exist "
f"and the config file ({config}) could not be read.\n"
)
sys.exit(2)
print(f"DESTINATION : {destination}")
os.chdir(destination)
Handler = server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), Handler, False)
print(f" * Running on http://127.0.0.1:{port}/")
try:
httpd.allow_reuse_address = True
httpd.server_bind()
httpd.server_activate()
httpd.serve_forever()
except KeyboardInterrupt:
print("\nAll done!")
@main.command()
@argument("target")
@argument("keys", nargs=-1)
@option(
"-o", "--overwrite", default=False, is_flag=True, help="Overwrite existing .md file"
)
def set_meta(target, keys, overwrite=False):
"""Write metadata keys to .md file.
TARGET can be a media file or an album directory. KEYS are key/value pairs.
Ex, to set the title of test.jpg to "My test image":
sigal set_meta test.jpg title "My test image"
"""
if not os.path.exists(target):
sys.stderr.write(f"The target {target} does not exist.\n")
sys.exit(1)
if len(keys) < 2 or len(keys) % 2 > 0:
sys.stderr.write("Need an even number of arguments.\n")
sys.exit(1)
if os.path.isdir(target):
descfile = os.path.join(target, "index.md")
else:
descfile = os.path.splitext(target)[0] + ".md"
if os.path.exists(descfile) and not overwrite:
sys.stderr.write(
f"Description file '{descfile}' already exists. "
"Use --overwrite to overwrite it.\n"
)
sys.exit(2)
with open(descfile, "w") as fp:
for i in range(len(keys) // 2):
k, v = keys[i * 2 : (i + 1) * 2]
fp.write(f"{k.capitalize()}: {v}\n")
print(f"{len(keys) // 2} metadata key(s) written to {descfile}")

305
src/sigal/__main__.py

@ -0,0 +1,305 @@
# Copyright (c) 2009-2023 - Simon Conseil
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import locale
import logging
import os
import pathlib
import socketserver
import sys
import time
from http import server
import click
from click import argument, option
from .gallery import Gallery
from .log import init_logging
from .settings import read_settings
from .utils import copy, init_plugins
try:
from .version import __version__
except ImportError:
# package is not installed
__version__ = None
_DEFAULT_CONFIG_FILE = "sigal.conf.py"
@click.group()
@click.version_option(version=__version__)
def main():
"""Sigal - Simple Static Gallery Generator.
Sigal is yet another python script to prepare a static gallery of images:
resize images, create thumbnails with some options, generate html pages.
"""
@main.command()
@argument("path", default=_DEFAULT_CONFIG_FILE)
def init(path):
"""Copy a sample config file in the current directory (default to
'sigal.conf.py'), or use the provided 'path'."""
path = pathlib.Path(path)
if path.exists():
print("Found an existing config file, will abort to keep it safe.")
sys.exit(1)
conf = pathlib.Path(__file__).parent / "templates" / "sigal.conf.py"
path.write_text(conf.read_text())
print(f"Sample config file created: {path}")
@main.command()
@argument("source", required=False)
@argument("destination", required=False)
@option("-f", "--force", is_flag=True, help="Force the reprocessing of existing images")
@option(
"-a",
"--force-album",
multiple=True,
help=(
"Force reprocessing of any album that matches the given pattern. "
"Patterns containing no wildcards will be matched against only "
"the album name. (-a 'My Pictures/* Pics' -a 'Festival')"
),
)
@option("-v", "--verbose", is_flag=True, help="Show all messages")
@option(
"-d",
"--debug",
is_flag=True,
help=(
"Show all messages, including debug messages. Also raise "
"exception if an error happen when processing files."
),
)
@option("-q", "--quiet", is_flag=True, help="Show only error messages")
@option(
"-c",
"--config",
default=_DEFAULT_CONFIG_FILE,
show_default=True,
help="Configuration file",
)
@option(
"-t",
"--theme",
help=(
"Specify a theme directory, or a theme name for the themes included with Sigal"
),
)
@option("--title", help="Title of the gallery (overrides the title setting.")
@option("-n", "--ncpu", help="Number of cpu to use (default: all)")
def build(
source,
destination,
debug,
verbose,
quiet,
force,
force_album,
config,
theme,
title,
ncpu,
):
"""Run sigal to process a directory.
If provided, 'source', 'destination' and 'theme' will override the
corresponding values from the settings file.
"""
if sum([debug, verbose, quiet]) > 1:
sys.exit("Only one option of debug, verbose and quiet should be used")
if debug:
level = logging.DEBUG
elif verbose:
level = logging.INFO
elif quiet:
level = logging.ERROR
else:
level = logging.WARNING
init_logging(__name__, level=level)
logger = logging.getLogger(__name__)
if not os.path.isfile(config):
logger.error("Settings file not found: %s", config)
sys.exit(1)
start_time = time.time()
settings = read_settings(config)
for key in ("source", "destination", "theme"):
arg = locals()[key]
if arg is not None:
settings[key] = os.path.abspath(arg)
logger.info("%12s : %s", key.capitalize(), settings[key])
if not settings["source"] or not os.path.isdir(settings["source"]):
logger.error("Input directory not found: %s", settings["source"])
sys.exit(1)
# on windows os.path.relpath raises a ValueError if the two paths are on
# different drives, in that case we just ignore the exception as the two
# paths are anyway not relative
relative_check = True
try:
relative_check = os.path.relpath(
settings["destination"], settings["source"]
).startswith("..")
except ValueError:
pass
if not relative_check:
logger.error("Output directory should be outside of the input directory.")
sys.exit(1)
if title:
settings["title"] = title
locale.setlocale(locale.LC_ALL, settings["locale"])
init_plugins(settings)
gal = Gallery(settings, ncpu=ncpu, quiet=quiet)
gal.build(force=force_album if len(force_album) else force)
# copy extra files
for src, dst in settings["files_to_copy"]:
src = os.path.join(settings["source"], src)
dst = os.path.join(settings["destination"], dst)
logger.debug("Copy %s to %s", src, dst)
copy(src, dst, symlink=settings["orig_link"], rellink=settings["rel_link"])
stats = gal.stats
def format_stats(_type):
opt = [
"{} {}".format(stats[_type + "_" + subtype], subtype)
for subtype in ("skipped", "failed")
if stats[_type + "_" + subtype] > 0
]
opt = " ({})".format(", ".join(opt)) if opt else ""
return f"{stats[_type]} {_type}s{opt}"
if not quiet:
stats_str = ""
types = sorted({t.rsplit("_", 1)[0] for t in stats})
for t in types[:-1]:
stats_str += f"{format_stats(t)} and "
stats_str += f"{format_stats(types[-1])}"
end_time = time.time() - start_time
print(f"Done, processed {stats_str} in {end_time:.2f} seconds.")
@main.command()
@argument("destination", default="_build")
@option("-p", "--port", help="Port to use", default=8000)
@option(
"-c",
"--config",
default=_DEFAULT_CONFIG_FILE,
show_default=True,
help="Configuration file",
)
def serve(destination, port, config):
"""Run a simple web server."""
if os.path.exists(destination):
pass
elif os.path.exists(config):
settings = read_settings(config)
destination = settings.get("destination")
if not os.path.exists(destination):
sys.stderr.write(
f"The '{destination}' directory doesn't exist, maybe try building"
" first?\n"
)
sys.exit(1)
else:
sys.stderr.write(
f"The {destination} directory doesn't exist "
f"and the config file ({config}) could not be read.\n"
)
sys.exit(2)
print(f"DESTINATION : {destination}")
os.chdir(destination)
Handler = server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", port), Handler, False)
print(f" * Running on http://127.0.0.1:{port}/")
try:
httpd.allow_reuse_address = True
httpd.server_bind()
httpd.server_activate()
httpd.serve_forever()
except KeyboardInterrupt:
print("\nAll done!")
@main.command()
@argument("target")
@argument("keys", nargs=-1)
@option(
"-o", "--overwrite", default=False, is_flag=True, help="Overwrite existing .md file"
)
def set_meta(target, keys, overwrite=False):
"""Write metadata keys to .md file.
TARGET can be a media file or an album directory. KEYS are key/value pairs.
Ex, to set the title of test.jpg to "My test image":
sigal set_meta test.jpg title "My test image"
"""
if not os.path.exists(target):
sys.stderr.write(f"The target {target} does not exist.\n")
sys.exit(1)
if len(keys) < 2 or len(keys) % 2 > 0:
sys.stderr.write("Need an even number of arguments.\n")
sys.exit(1)
if os.path.isdir(target):
descfile = os.path.join(target, "index.md")
else:
descfile = os.path.splitext(target)[0] + ".md"
if os.path.exists(descfile) and not overwrite:
sys.stderr.write(
f"Description file '{descfile}' already exists. "
"Use --overwrite to overwrite it.\n"
)
sys.exit(2)
with open(descfile, "w") as fp:
for i in range(len(keys) // 2):
k, v = keys[i * 2 : (i + 1) * 2]
fp.write(f"{k.capitalize()}: {v}\n")
print(f"{len(keys) // 2} metadata key(s) written to {descfile}")
if __name__ == "__main__":
main()

16
src/sigal/gallery.py

@ -25,6 +25,7 @@
# IN THE SOFTWARE.
import fnmatch
import io
import logging
import multiprocessing
import os
@ -54,8 +55,8 @@ from .utils import (
get_mod_date,
is_valid_html5_video,
read_markdown,
url_from_path,
should_reprocess_album,
url_from_path,
)
from .video import process_video
from .writer import AlbumListPageWriter, AlbumPageWriter
@ -718,10 +719,13 @@ class Gallery:
ignore_files = settings["ignore_files"]
progressChars = cycle(["/", "-", "\\", "|"])
try:
isatty = os.isatty(sys.stdout.fileno())
except io.UnsupportedOperation:
isatty = False
show_progress = (
not quiet
and self.logger.getEffectiveLevel() >= logging.WARNING
and os.isatty(sys.stdout.fileno())
not quiet and self.logger.getEffectiveLevel() >= logging.WARNING and isatty
)
self.progressbar_target = None if show_progress else Devnull()
@ -937,7 +941,9 @@ class Gallery:
def process_dir(self, album, force=False):
"""Process a list of images in a directory."""
for f in album:
if isfile(f.dst_path) and not should_reprocess_album(album.path, album.name, force):
if isfile(f.dst_path) and not should_reprocess_album(
album.path, album.name, force
):
self.logger.info("%s exists - skipping", f.dst_filename)
self.stats[f.type + "_skipped"] += 1
else:

32
src/sigal/utils.py

@ -18,12 +18,14 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import importlib
import logging
import os
import shutil
import sys
from fnmatch import fnmatch
from functools import lru_cache
from urllib.parse import quote
from fnmatch import fnmatch
from markdown import Markdown
from markupsafe import Markup
@ -82,18 +84,20 @@ def url_from_path(path):
path = "/".join(path.split(os.sep))
return quote(path)
def should_reprocess_album(path, name, force=False):
if isinstance(force, bool):
return force
else:
for f in force:
if '*' in f or '?' in f:
if "*" in f or "?" in f:
if fnmatch(path, f):
return True
elif name == f:
return True
return False
def read_markdown(filename):
"""Reads markdown file, converts output and fetches title and meta-data for
further processing.
@ -147,6 +151,30 @@ def get_mime(ext):
return VIDEO_MIMES[ext]
def init_plugins(settings):
"""Load plugins and call register()."""
logger = logging.getLogger(__name__)
logger.debug("Plugin paths: %s", settings["plugin_paths"])
for path in settings["plugin_paths"]:
sys.path.insert(0, path)
for plugin in settings["plugins"]:
try:
if isinstance(plugin, str):
mod = importlib.import_module(plugin)
mod.register(settings)
else:
plugin.register(settings)
logger.debug("Registered plugin %s", plugin)
except Exception as e:
logger.error("Failed to load plugin %s: %r", plugin, e)
for path in settings["plugin_paths"]:
sys.path.remove(path)
class raise_if_debug:
def __init__(self):
self.value = None

13
tests/test_cli.py

@ -4,7 +4,7 @@ from os.path import join
from click.testing import CliRunner
from sigal import build, init, serve, set_meta
from sigal.__main__ import build, init, serve, set_meta
TESTGAL = join(os.path.abspath(os.path.dirname(__file__)), "sample")
@ -41,15 +41,20 @@ def test_build(tmpdir, disconnect_signals):
)
result = runner.invoke(build, ["-n", 1, "--debug"])
assert result.output == "Settings file not found: sigal.conf.py\n"
assert result.exit_code == 1
os.chdir(tmpdir)
result = runner.invoke(build, ["foo", "-n", 1, "--debug"])
assert result.exit_code == 1
assert "Input directory not found" in result.output
result = runner.invoke(build, ["pictures", "pictures/out", "-n", 1, "--debug"])
assert result.exit_code == 1
assert (
"Output directory should be outside of the input directory" in result.output
)
with open(config_file) as f:
text = f.read()
@ -59,7 +64,7 @@ theme = 'colorbox'
files_to_copy = (('../watermark.png', 'watermark.png'),)
plugins = ['sigal.plugins.adjust', 'sigal.plugins.copyright',
'sigal.plugins.watermark', 'sigal.plugins.feeds',
'sigal.plugins.media_page' 'sigal.plugins.nomedia',
'sigal.plugins.media_page', 'sigal.plugins.nomedia',
'sigal.plugins.extended_caching']
copyright = "An example copyright message"
copyright_text_font = "foobar"
@ -74,7 +79,9 @@ atom_feed = {'feed_url': 'http://example.org/feed.atom', 'nb_items': 10}
f.write(text)
result = runner.invoke(
build, ["pictures", "build", "--title", "Testing build", "-n", 1, "--debug"]
build,
["pictures", "build", "--title", "Testing build", "-n", 1, "--debug"],
catch_exceptions=False,
)
assert result.exit_code == 0
assert os.path.isfile(

2
tests/test_compress_assets_plugin.py

@ -4,9 +4,9 @@ from unittest import mock
import pytest
from sigal import init_plugins
from sigal.gallery import Gallery
from sigal.plugins import compress_assets
from sigal.utils import init_plugins
CURRENT_DIR = os.path.dirname(__file__)

2
tests/test_encrypt.py

@ -4,10 +4,10 @@ from io import BytesIO
import pytest
from sigal import init_plugins
from sigal.gallery import Gallery
from sigal.plugins.encrypt import endec
from sigal.plugins.encrypt.encrypt import cache_key
from sigal.utils import init_plugins
CURRENT_DIR = os.path.dirname(__file__)

2
tests/test_image.py

@ -4,7 +4,6 @@ from unittest.mock import patch
import pytest
from PIL import Image as PILImage
from sigal import init_logging
from sigal.gallery import Image
from sigal.image import (
generate_image,
@ -16,6 +15,7 @@ from sigal.image import (
get_size,
process_image,
)
from sigal.log import init_logging
from sigal.settings import Status, create_settings
CURRENT_DIR = os.path.dirname(__file__)

2
tests/test_plugins.py

@ -1,7 +1,7 @@
import os
from sigal import init_plugins
from sigal.gallery import Gallery
from sigal.utils import init_plugins
CURRENT_DIR = os.path.dirname(__file__)

45
tests/test_utils.py

@ -43,16 +43,43 @@ def test_copy(tmpdir):
utils.copy(src, dst)
utils.copy(src, dst)
def test_force(tmpdir):
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', False) is False
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', True) is True
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Gallery/*']) is True
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Gallery/*Pics']) is True
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Pictures/*']) is False
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['New Pics']) is True
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Pictures']) is False
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Pictures', 'Something']) is False
assert utils.should_reprocess_album('Gallery/New Pics', 'New Pics', ['Pictures', 'Gallery', '*Pics']) is True
assert utils.should_reprocess_album("Gallery/New Pics", "New Pics", False) is False
assert utils.should_reprocess_album("Gallery/New Pics", "New Pics", True) is True
assert (
utils.should_reprocess_album("Gallery/New Pics", "New Pics", ["Gallery/*"])
is True
)
assert (
utils.should_reprocess_album("Gallery/New Pics", "New Pics", ["Gallery/*Pics"])
is True
)
assert (
utils.should_reprocess_album("Gallery/New Pics", "New Pics", ["Pictures/*"])
is False
)
assert (
utils.should_reprocess_album("Gallery/New Pics", "New Pics", ["New Pics"])
is True
)
assert (
utils.should_reprocess_album("Gallery/New Pics", "New Pics", ["Pictures"])
is False
)
assert (
utils.should_reprocess_album(
"Gallery/New Pics", "New Pics", ["Pictures", "Something"]
)
is False
)
assert (
utils.should_reprocess_album(
"Gallery/New Pics", "New Pics", ["Pictures", "Gallery", "*Pics"]
)
is True
)
def test_check_or_create_dir(tmpdir):
path = str(tmpdir.join("new_directory"))

2
tests/test_zip.py

@ -1,9 +1,9 @@
import os
import zipfile
from sigal import init_plugins
from sigal.gallery import Gallery
from sigal.settings import read_settings
from sigal.utils import init_plugins
CURRENT_DIR = os.path.dirname(__file__)
SAMPLE_DIR = os.path.join(CURRENT_DIR, "sample")

Loading…
Cancel
Save