Merge branch 'misc'
This commit is contained in:
@@ -34,7 +34,7 @@ matrix:
|
|||||||
|
|
||||||
install: pip install -U tox-travis
|
install: pip install -U tox-travis
|
||||||
|
|
||||||
script: tox
|
script: tox -- -v
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- pip install codecov
|
- pip install codecov
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,5 +1,5 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
Copyright (c) 2009-2018 - Simon Conseil
|
Copyright (c) 2009-2020 - Simon Conseil
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ A total of %d pull requests were merged for this release.
|
|||||||
|
|
||||||
|
|
||||||
def get_authors(revision_range):
|
def get_authors(revision_range):
|
||||||
pat = u'^.*\\t(.*)$'
|
pat = '^.*\\t(.*)$'
|
||||||
lst_release, cur_release = [r.strip() for r in revision_range.split('..')]
|
lst_release, cur_release = [r.strip() for r in revision_range.split('..')]
|
||||||
|
|
||||||
# authors, in current release and previous to current release.
|
# authors, in current release and previous to current release.
|
||||||
@@ -61,7 +61,7 @@ def get_authors(revision_range):
|
|||||||
re.M))
|
re.M))
|
||||||
|
|
||||||
# Append '+' to new authors.
|
# Append '+' to new authors.
|
||||||
authors = [s + u' +' for s in cur - pre] + [s for s in cur & pre]
|
authors = [s + ' +' for s in cur - pre] + [s for s in cur & pre]
|
||||||
authors.sort()
|
authors.sort()
|
||||||
return authors
|
return authors
|
||||||
|
|
||||||
@@ -72,17 +72,17 @@ def get_pull_requests(repo, revision_range):
|
|||||||
# From regular merges
|
# From regular merges
|
||||||
merges = this_repo.git.log(
|
merges = this_repo.git.log(
|
||||||
'--oneline', '--merges', revision_range)
|
'--oneline', '--merges', revision_range)
|
||||||
issues = re.findall(u"Merge pull request \\#(\\d*)", merges)
|
issues = re.findall("Merge pull request \\#(\\d*)", merges)
|
||||||
prnums.extend(int(s) for s in issues)
|
prnums.extend(int(s) for s in issues)
|
||||||
|
|
||||||
# From Homu merges (Auto merges)
|
# From Homu merges (Auto merges)
|
||||||
issues = re. findall(u"Auto merge of \\#(\\d*)", merges)
|
issues = re. findall("Auto merge of \\#(\\d*)", merges)
|
||||||
prnums.extend(int(s) for s in issues)
|
prnums.extend(int(s) for s in issues)
|
||||||
|
|
||||||
# From fast forward squash-merges
|
# From fast forward squash-merges
|
||||||
commits = this_repo.git.log(
|
commits = this_repo.git.log(
|
||||||
'--oneline', '--no-merges', '--first-parent', revision_range)
|
'--oneline', '--no-merges', '--first-parent', revision_range)
|
||||||
issues = re.findall(u'^.*\\(\\#(\\d+)\\)$', commits, re.M)
|
issues = re.findall('^.*\\(\\#(\\d+)\\)$', commits, re.M)
|
||||||
prnums.extend(int(s) for s in issues)
|
prnums.extend(int(s) for s in issues)
|
||||||
|
|
||||||
# get PR data from github repo
|
# get PR data from github repo
|
||||||
@@ -99,19 +99,19 @@ def main(token, revision_range):
|
|||||||
|
|
||||||
# document authors
|
# document authors
|
||||||
authors = get_authors(revision_range)
|
authors = get_authors(revision_range)
|
||||||
heading = u"Contributors"
|
heading = "Contributors"
|
||||||
print()
|
print()
|
||||||
print(heading)
|
print(heading)
|
||||||
print("=" * len(heading))
|
print("=" * len(heading))
|
||||||
print(author_msg % len(authors))
|
print(author_msg % len(authors))
|
||||||
|
|
||||||
for s in authors:
|
for s in authors:
|
||||||
print(u'* ' + s)
|
print('* ' + s)
|
||||||
|
|
||||||
# document pull requests
|
# document pull requests
|
||||||
pull_requests = get_pull_requests(github_repo, revision_range)
|
pull_requests = get_pull_requests(github_repo, revision_range)
|
||||||
heading = u"Pull requests merged"
|
heading = "Pull requests merged"
|
||||||
pull_msg = u"* `#{0} <{1}>`__: {2}"
|
pull_msg = "* `#{0} <{1}>`__: {2}"
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print(heading)
|
print(heading)
|
||||||
@@ -119,11 +119,11 @@ def main(token, revision_range):
|
|||||||
print(pull_request_msg % len(pull_requests))
|
print(pull_request_msg % len(pull_requests))
|
||||||
|
|
||||||
for pull in pull_requests:
|
for pull in pull_requests:
|
||||||
title = re.sub(u"\\s+", u" ", pull.title.strip())
|
title = re.sub("\\s+", " ", pull.title.strip())
|
||||||
if len(title) > 60:
|
if len(title) > 60:
|
||||||
remainder = re.sub(u"\\s.*$", u"...", title[60:])
|
remainder = re.sub("\\s.*$", "...", title[60:])
|
||||||
if len(remainder) > 20:
|
if len(remainder) > 20:
|
||||||
remainder = title[:80] + u"..."
|
remainder = title[:80] + "..."
|
||||||
else:
|
else:
|
||||||
title = title[:60] + remainder
|
title = title[:60] + remainder
|
||||||
print(pull_msg.format(pull.number, pull.html_url, title))
|
print(pull_msg.format(pull.number, pull.html_url, title))
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'Sigal'
|
project = 'Sigal'
|
||||||
copyright = '2012-2019, Simon Conseil'
|
copyright = '2012-2020, Simon Conseil'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Install sigal in development mode::
|
|||||||
Install additional dependencies for development (Sphinx, pytest), and optional
|
Install additional dependencies for development (Sphinx, pytest), and optional
|
||||||
dependencies::
|
dependencies::
|
||||||
|
|
||||||
pip install -r requirements.txt
|
pip install -e .\[all,tests\]
|
||||||
|
|
||||||
Building the docs
|
Building the docs
|
||||||
-----------------
|
-----------------
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ With pip::
|
|||||||
|
|
||||||
Or to install with optional dependencies (listed below)::
|
Or to install with optional dependencies (listed below)::
|
||||||
|
|
||||||
$ pip install sigal\[all\]
|
$ pip install sigal\[all,tests\]
|
||||||
|
|
||||||
To install the development version, see the :doc:`contribute`.
|
To install the development version, see the :doc:`contribute`.
|
||||||
|
|
||||||
@@ -29,8 +29,8 @@ The mandatory dependencies are:
|
|||||||
- Pillow
|
- Pillow
|
||||||
- Python Markdown
|
- Python Markdown
|
||||||
|
|
||||||
There are also a number of optional dependencies for the :doc:`plugins`, listed
|
There are also a number of optional dependencies for the :doc:`plugins`,
|
||||||
in the ``requirements.txt`` file:
|
installable with the ``[all]`` marker:
|
||||||
|
|
||||||
- Brotli, zopfli (compress assets plugin)
|
- Brotli, zopfli (compress assets plugin)
|
||||||
- Boto (upload to S3 plugin)
|
- Boto (upload to S3 plugin)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
|
build:
|
||||||
|
image: latest
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3.7
|
version: 3.7
|
||||||
install:
|
install:
|
||||||
- method: pip
|
- method: pip
|
||||||
path: .
|
path: .
|
||||||
- requirements: requirements-doc.txt
|
extra_requirements:
|
||||||
|
- docs
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
-r requirements.txt
|
|
||||||
alabaster
|
|
||||||
Sphinx
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
blinker
|
|
||||||
boto
|
|
||||||
brotli
|
|
||||||
click
|
|
||||||
coverage
|
|
||||||
feedgenerator
|
|
||||||
Jinja2
|
|
||||||
Markdown
|
|
||||||
Pillow
|
|
||||||
pilkit
|
|
||||||
pytest
|
|
||||||
pytest-cov
|
|
||||||
zopfli
|
|
||||||
@@ -38,6 +38,8 @@ install_requires =
|
|||||||
|
|
||||||
[options.extras_require]
|
[options.extras_require]
|
||||||
all = boto; brotli; feedgenerator; zopfli
|
all = boto; brotli; feedgenerator; zopfli
|
||||||
|
tests = pytest; pytest-cov
|
||||||
|
docs = Sphinx; alabaster
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
exclude =
|
exclude =
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
@@ -74,7 +74,7 @@ def init(path):
|
|||||||
|
|
||||||
with open(path, 'w', encoding='utf-8') as f:
|
with open(path, 'w', encoding='utf-8') as f:
|
||||||
f.write(conf.decode('utf8'))
|
f.write(conf.decode('utf8'))
|
||||||
print("Sample config file created: {}".format(path))
|
print(f"Sample config file created: {path}")
|
||||||
|
|
||||||
|
|
||||||
@main.command()
|
@main.command()
|
||||||
@@ -224,11 +224,11 @@ def serve(destination, port, config):
|
|||||||
.format(destination=destination, config=config))
|
.format(destination=destination, config=config))
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
print('DESTINATION : {}'.format(destination))
|
print(f'DESTINATION : {destination}')
|
||||||
os.chdir(destination)
|
os.chdir(destination)
|
||||||
Handler = server.SimpleHTTPRequestHandler
|
Handler = server.SimpleHTTPRequestHandler
|
||||||
httpd = socketserver.TCPServer(("", port), Handler, False)
|
httpd = socketserver.TCPServer(("", port), Handler, False)
|
||||||
print(" * Running on http://127.0.0.1:{}/".format(port))
|
print(f" * Running on http://127.0.0.1:{port}/")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
httpd.allow_reuse_address = True
|
httpd.allow_reuse_address = True
|
||||||
@@ -255,7 +255,7 @@ def set_meta(target, keys, overwrite=False):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if not os.path.exists(target):
|
if not os.path.exists(target):
|
||||||
sys.stderr.write("The target {} does not exist.\n".format(target))
|
sys.stderr.write(f"The target {target} does not exist.\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if len(keys) < 2 or len(keys) % 2 > 0:
|
if len(keys) < 2 or len(keys) % 2 > 0:
|
||||||
sys.stderr.write("Need an even number of arguments.\n")
|
sys.stderr.write("Need an even number of arguments.\n")
|
||||||
@@ -273,5 +273,5 @@ def set_meta(target, keys, overwrite=False):
|
|||||||
with open(descfile, "w") as fp:
|
with open(descfile, "w") as fp:
|
||||||
for i in range(len(keys) // 2):
|
for i in range(len(keys) // 2):
|
||||||
k, v = keys[i * 2:(i + 1) * 2]
|
k, v = keys[i * 2:(i + 1) * 2]
|
||||||
fp.write("{}: {}\n".format(k.capitalize(), v))
|
fp.write(f"{k.capitalize()}: {v}\n")
|
||||||
print("{} metadata key(s) written to {}".format(len(keys) // 2, descfile))
|
print("{} metadata key(s) written to {}".format(len(keys) // 2, descfile))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
||||||
# Copyright (c) 2014 - Jonas Kaufmann
|
# Copyright (c) 2014 - Jonas Kaufmann
|
||||||
# Copyright (c) 2015 - François D.
|
# Copyright (c) 2015 - François D.
|
||||||
@@ -91,7 +91,7 @@ class Media:
|
|||||||
signals.media_initialized.send(self)
|
signals.media_initialized.send(self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s>(%r)" % (self.__class__.__name__, str(self))
|
return "<{}>({!r})".format(self.__class__.__name__, str(self))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return join(self.path, self.filename)
|
return join(self.path, self.filename)
|
||||||
@@ -195,7 +195,7 @@ class Image(Media):
|
|||||||
if self.raw_exif and self.ext in ('.jpg', '.jpeg') else None)
|
if self.raw_exif and self.ext in ('.jpg', '.jpeg') else None)
|
||||||
|
|
||||||
def _get_metadata(self):
|
def _get_metadata(self):
|
||||||
super(Image, self)._get_metadata()
|
super()._get_metadata()
|
||||||
# If a title or description hasn't been obtained by other means, look
|
# If a title or description hasn't been obtained by other means, look
|
||||||
# for the information in IPTC fields
|
# for the information in IPTC fields
|
||||||
if self.title and self.description:
|
if self.title and self.description:
|
||||||
@@ -244,7 +244,7 @@ class Video(Media):
|
|||||||
type = 'video'
|
type = 'video'
|
||||||
|
|
||||||
def __init__(self, filename, path, settings):
|
def __init__(self, filename, path, settings):
|
||||||
super(Video, self).__init__(filename, path, settings)
|
super().__init__(filename, path, settings)
|
||||||
base, ext = splitext(filename)
|
base, ext = splitext(filename)
|
||||||
self.src_filename = filename
|
self.src_filename = filename
|
||||||
self.date = self._get_file_date()
|
self.date = self._get_file_date()
|
||||||
@@ -322,12 +322,12 @@ class Album:
|
|||||||
signals.album_initialized.send(self)
|
signals.album_initialized.send(self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s>(path=%r, title=%r)" % (self.__class__.__name__, self.path,
|
return "<{}>(path={!r}, title={!r})".format(
|
||||||
self.title)
|
self.__class__.__name__, self.path, self.title)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return ('{} : '.format(self.path) +
|
return (f'{self.path} : ' +
|
||||||
', '.join('{} {}s'.format(count, _type)
|
', '.join(f'{count} {_type}s'
|
||||||
for _type, count in self.medias_count.items()))
|
for _type, count in self.medias_count.items()))
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
@@ -544,7 +544,7 @@ class Album:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Gallery(object):
|
class Gallery:
|
||||||
|
|
||||||
def __init__(self, settings, ncpu=None, quiet=False):
|
def __init__(self, settings, ncpu=None, quiet=False):
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
# Copyright (c) 2015 - François D.
|
# Copyright (c) 2015 - François D.
|
||||||
# Copyright (c) 2018 - Edwin Steele
|
# Copyright (c) 2018 - Edwin Steele
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ def generate_image(source, outname, settings, options=None):
|
|||||||
if settings['autorotate_images']:
|
if settings['autorotate_images']:
|
||||||
try:
|
try:
|
||||||
img = Transpose().process(img)
|
img = Transpose().process(img)
|
||||||
except (IOError, IndexError):
|
except (OSError, IndexError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Resize the image
|
# Resize the image
|
||||||
@@ -195,7 +195,7 @@ def get_size(file_path):
|
|||||||
"""Return image size (width and height)."""
|
"""Return image size (width and height)."""
|
||||||
try:
|
try:
|
||||||
im = _read_image(file_path)
|
im = _read_image(file_path)
|
||||||
except (IOError, IndexError, TypeError, AttributeError) as e:
|
except (OSError, IndexError, TypeError, AttributeError) as e:
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.error("Could not read size of %s due to %r", file_path, e)
|
logger.error("Could not read size of %s due to %r", file_path, e)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2013-2018 - Simon Conseil
|
# Copyright (c) 2013-2020 - Simon Conseil
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class BaseCompressor:
|
|||||||
|
|
||||||
file_stats = None
|
file_stats = None
|
||||||
compressed_stats = None
|
compressed_stats = None
|
||||||
compressed_filename = '{}.{}'.format(filename, self.suffix)
|
compressed_filename = f'{filename}.{self.suffix}'
|
||||||
try:
|
try:
|
||||||
file_stats = os.stat(filename)
|
file_stats = os.stat(filename)
|
||||||
compressed_stats = os.stat(compressed_filename)
|
compressed_stats = os.stat(compressed_filename)
|
||||||
@@ -146,7 +146,7 @@ def get_compressor(settings):
|
|||||||
logger.error('Unable to import brotli module')
|
logger.error('Unable to import brotli module')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.error('No such compressor {}'.format(name))
|
logger.error(f'No such compressor {name}')
|
||||||
|
|
||||||
|
|
||||||
def compress_gallery(gallery):
|
def compress_gallery(gallery):
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ def generate_feed(gallery, medias, feed_type=None, feed_url='', nb_items=0):
|
|||||||
|
|
||||||
for item in medias[:nb_items]:
|
for item in medias[:nb_items]:
|
||||||
if theme == 'galleria':
|
if theme == 'galleria':
|
||||||
link = '%s/%s/#%s' % (base_url, item.path, item.url)
|
link = f'{base_url}/{item.path}/#{item.url}'
|
||||||
else:
|
else:
|
||||||
link = '%s/%s/' % (base_url, item.path)
|
link = f'{base_url}/{item.path}/'
|
||||||
|
|
||||||
feed.add_item(
|
feed.add_item(
|
||||||
title=Markup.escape(item.title or item.url),
|
title=Markup.escape(item.title or item.url),
|
||||||
@@ -68,7 +68,7 @@ def generate_feed(gallery, medias, feed_type=None, feed_url='', nb_items=0):
|
|||||||
# unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,
|
# unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,
|
||||||
# item.date.date(),
|
# item.date.date(),
|
||||||
# urlparse(link).path.lstrip('/')),
|
# urlparse(link).path.lstrip('/')),
|
||||||
description='<img src="%s/%s/%s" />' % (base_url, item.path,
|
description='<img src="{}/{}/{}" />'.format(base_url, item.path,
|
||||||
item.thumbnail),
|
item.thumbnail),
|
||||||
# categories=item.tags if hasattr(item, 'tags') else None,
|
# categories=item.tags if hasattr(item, 'tags') else None,
|
||||||
author_name=getattr(item, 'author', ''),
|
author_name=getattr(item, 'author', ''),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
# Copyright (c) 2014 - Jamie Starke
|
# Copyright (c) 2014 - Jamie Starke
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ def filter_nomedia(album, settings=None):
|
|||||||
album.medias = []
|
album.medias = []
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with open(nomediapath, "r") as nomediaFile:
|
with open(nomediapath) as nomediaFile:
|
||||||
logger.info("Found a .nomedia file in %s, ignoring its "
|
logger.info("Found a .nomedia file in %s, ignoring its "
|
||||||
"entries", album.name)
|
"entries", album.name)
|
||||||
ignored = nomediaFile.read().split("\n")
|
ignored = nomediaFile.read().split("\n")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
||||||
# Copyright (c) 2017 - Mate Lakat
|
# Copyright (c) 2017 - Mate Lakat
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ _DEFAULT_CONFIG = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Status(object):
|
class Status:
|
||||||
SUCCESS = 0
|
SUCCESS = 0
|
||||||
FAILURE = 1
|
FAILURE = 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2011-2018 - Simon Conseil
|
# Copyright (c) 2011-2020 - Simon Conseil
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
@@ -32,7 +32,7 @@ VIDEO_MIMES = {'.mp4': 'video/mp4',
|
|||||||
MD = None
|
MD = None
|
||||||
|
|
||||||
|
|
||||||
class Devnull(object):
|
class Devnull:
|
||||||
"""'Black hole' for output that should not be printed"""
|
"""'Black hole' for output that should not be printed"""
|
||||||
|
|
||||||
def write(self, *_):
|
def write(self, *_):
|
||||||
@@ -82,7 +82,7 @@ def read_markdown(filename):
|
|||||||
# Use utf-8-sig codec to remove BOM if it is present. This is only possible
|
# Use utf-8-sig codec to remove BOM if it is present. This is only possible
|
||||||
# this way prior to feeding the text to the markdown parser (which would
|
# this way prior to feeding the text to the markdown parser (which would
|
||||||
# also default to pure utf-8)
|
# also default to pure utf-8)
|
||||||
with open(filename, 'r', encoding='utf-8-sig') as f:
|
with open(filename, encoding='utf-8-sig') as f:
|
||||||
text = f.read()
|
text = f.read()
|
||||||
|
|
||||||
if MD is None:
|
if MD is None:
|
||||||
@@ -122,7 +122,7 @@ def get_mime(ext):
|
|||||||
return VIDEO_MIMES[ext]
|
return VIDEO_MIMES[ext]
|
||||||
|
|
||||||
|
|
||||||
class cached_property(object):
|
class cached_property:
|
||||||
""" A property that is only computed once per instance and then replaces
|
""" A property that is only computed once per instance and then replaces
|
||||||
itself with an ordinary attribute. Deleting the attribute resets the
|
itself with an ordinary attribute. Deleting the attribute resets the
|
||||||
property.
|
property.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
||||||
# Copyright (c) 2013-2018 - Simon Conseil
|
# Copyright (c) 2013-2020 - Simon Conseil
|
||||||
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2009-2018 - Simon Conseil
|
# Copyright (c) 2009-2020 - Simon Conseil
|
||||||
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
||||||
# Copyright (c) 2018 - Edwin Steele
|
# Copyright (c) 2018 - Edwin Steele
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ THEMES_PATH = os.path.normpath(os.path.join(
|
|||||||
os.path.abspath(os.path.dirname(__file__)), 'themes'))
|
os.path.abspath(os.path.dirname(__file__)), 'themes'))
|
||||||
|
|
||||||
|
|
||||||
class AbstractWriter(object):
|
class AbstractWriter:
|
||||||
template_file = None
|
template_file = None
|
||||||
|
|
||||||
def __init__(self, settings, index_title=''):
|
def __init__(self, settings, index_title=''):
|
||||||
|
|||||||
@@ -39,4 +39,4 @@ def disconnect_signals():
|
|||||||
|
|
||||||
|
|
||||||
def pytest_report_header(config):
|
def pytest_report_header(config):
|
||||||
return "project deps: Pillow-{}".format(PIL.__version__)
|
return f"project deps: Pillow-{PIL.__version__}"
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def test_media(settings):
|
|||||||
assert m.title == "Foo Bar"
|
assert m.title == "Foo Bar"
|
||||||
assert m.description == "<p>This is a funny description of this image</p>"
|
assert m.description == "<p>This is a funny description of this image</p>"
|
||||||
|
|
||||||
assert repr(m) == "<Media>('{}')".format(file_path)
|
assert repr(m) == f"<Media>('{file_path}')"
|
||||||
assert str(m) == file_path
|
assert str(m) == file_path
|
||||||
|
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ def test_gallery(settings, tmpdir):
|
|||||||
out_html = os.path.join(settings['destination'], 'index.html')
|
out_html = os.path.join(settings['destination'], 'index.html')
|
||||||
assert os.path.isfile(out_html)
|
assert os.path.isfile(out_html)
|
||||||
|
|
||||||
with open(out_html, 'r') as f:
|
with open(out_html) as f:
|
||||||
html = f.read()
|
html = f.read()
|
||||||
|
|
||||||
assert '<title>Sigal test gallery</title>' in html
|
assert '<title>Sigal test gallery</title>' in html
|
||||||
|
|||||||
8
tox.ini
8
tox.ini
@@ -9,8 +9,9 @@ python =
|
|||||||
3.8: py38
|
3.8: py38
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps =
|
extras =
|
||||||
-r {toxinidir}/requirements.txt
|
all
|
||||||
|
tests
|
||||||
commands = pytest --cov sigal --cov-report term-missing tests/
|
commands = pytest --cov sigal --cov-report term-missing tests/
|
||||||
|
|
||||||
[testenv:check]
|
[testenv:check]
|
||||||
@@ -28,8 +29,7 @@ commands =
|
|||||||
|
|
||||||
[testenv:doc]
|
[testenv:doc]
|
||||||
whitelist_externals = make
|
whitelist_externals = make
|
||||||
deps =
|
extras = docs
|
||||||
-r {toxinidir}/requirements-doc.txt
|
|
||||||
usedevelop = true
|
usedevelop = true
|
||||||
commands =
|
commands =
|
||||||
make -C docs html
|
make -C docs html
|
||||||
|
|||||||
Reference in New Issue
Block a user