sigal 2.5__tar.gz → 2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sigal-2.5 → sigal-2.6}/.github/workflows/publish.yml +2 -2
- {sigal-2.5 → sigal-2.6}/.github/workflows/python-tests.yml +7 -5
- {sigal-2.5 → sigal-2.6}/.pre-commit-config.yaml +3 -3
- {sigal-2.5 → sigal-2.6}/.readthedocs.yml +2 -2
- {sigal-2.5 → sigal-2.6}/LICENSE +1 -1
- {sigal-2.5 → sigal-2.6}/PKG-INFO +10 -9
- {sigal-2.5 → sigal-2.6}/README.rst +2 -2
- {sigal-2.5 → sigal-2.6}/docs/changelog.rst +17 -0
- {sigal-2.5 → sigal-2.6}/docs/conf.py +1 -1
- {sigal-2.5 → sigal-2.6}/pyproject.toml +6 -7
- {sigal-2.5 → sigal-2.6}/src/sigal/__init__.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/__main__.py +12 -9
- {sigal-2.5 → sigal-2.6}/src/sigal/gallery.py +66 -79
- {sigal-2.5 → sigal-2.6}/src/sigal/image.py +5 -3
- {sigal-2.5 → sigal-2.6}/src/sigal/log.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/feeds.py +1 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/media_page.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/nonmedia_files.py +26 -15
- {sigal-2.5 → sigal-2.6}/src/sigal/settings.py +23 -2
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/templates/album.html +30 -28
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/templates/album_items.html +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/styles.css +4 -5
- sigal-2.6/src/sigal/themes/photoswipe/templates/album.html +9 -0
- sigal-2.6/src/sigal/themes/photoswipe/templates/album_items.html +31 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/templates/album_list.html +5 -0
- sigal-2.6/src/sigal/themes/photoswipe/templates/base.html +92 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/utils.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/version.py +16 -3
- {sigal-2.5 → sigal-2.6}/src/sigal/video.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal/writer.py +1 -1
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/PKG-INFO +10 -9
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/SOURCES.txt +3 -0
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/requires.txt +2 -1
- sigal-2.6/tests/sample/pictures/exifTest/22.jpg +0 -0
- sigal-2.6/tests/sample/pictures/nonmedia_files/dummy.txt +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/sigal.conf.py +1 -1
- {sigal-2.5 → sigal-2.6}/tests/test_gallery.py +29 -4
- {sigal-2.5 → sigal-2.6}/tests/test_settings.py +3 -2
- {sigal-2.5 → sigal-2.6}/tox.ini +10 -12
- sigal-2.5/src/sigal/themes/photoswipe/templates/album.html +0 -93
- sigal-2.5/src/sigal/themes/photoswipe/templates/base.html +0 -43
- {sigal-2.5 → sigal-2.6}/.git-blame-ignore-revs +0 -0
- {sigal-2.5 → sigal-2.6}/.github/dependabot.yml +0 -0
- {sigal-2.5 → sigal-2.6}/.gitignore +0 -0
- {sigal-2.5 → sigal-2.6}/AUTHORS +0 -0
- {sigal-2.5 → sigal-2.6}/CONTRIBUTING.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/Makefile +0 -0
- {sigal-2.5 → sigal-2.6}/docs/album_information.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/changelog.py +0 -0
- {sigal-2.5 → sigal-2.6}/docs/configuration.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/contribute.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/faq.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/getting_started.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/image_information.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/index.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/installation.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/license.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/make.bat +0 -0
- {sigal-2.5 → sigal-2.6}/docs/plugins.rst +0 -0
- {sigal-2.5 → sigal-2.6}/docs/themes.rst +0 -0
- {sigal-2.5 → sigal-2.6}/setup.cfg +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/__init__.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/adjust.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/compress_assets.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/copyright.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/__init__.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/encrypt.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/endec.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/static/decrypt.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/static/keycheck.txt +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/encrypt/static/sw.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/extended_caching.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/nomedia.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/titleregexp.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/watermark.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/plugins/zip_gallery.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/signals.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/templates/sigal.conf.py +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/css/colorbox.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/css/skeleton.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/css/style.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/images/controls.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/images/loading.gif +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/app-with-media-page.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/app.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery-2.2.1.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery-2.2.1.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery.colorbox-min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery.colorbox.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery.touchSwipe.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/static/js/jquery.touchSwipe.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/templates/album_list.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/templates/base.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/colorbox/templates/media.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/Control.FullScreen.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/Control.FullScreen.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/Leaflet.Photo.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/Leaflet.Photo.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/MarkerCluster.Default.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/MarkerCluster.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/README +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/icon-fullscreen-2x.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/icon-fullscreen.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/images/layers-2x.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/images/layers.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/images/marker-icon-2x.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/images/marker-icon.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/images/marker-shadow.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet-providers.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet-src.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet.markercluster-src.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/static/leaflet/leaflet.markercluster.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/analytics.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/breadcrumb.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/decrypt.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/default_head.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/description.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/download_zip.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/footer.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/gtm.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/links.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/map.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/default/templates/piwik.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/README +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/css/normalize.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/css/style.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/galleria.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/galleria.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/img/empty.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/img/fullscreen.png +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/jquery-3.3.1.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/jquery-3.3.1.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/plugins/history/galleria.history.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/plugins/history/galleria.history.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/azur/galleria.azur.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/azur/galleria.azur.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/azur/galleria.azur.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/azur/galleria.azur.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/classic/galleria.classic.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/classic/galleria.classic.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/classic/galleria.classic.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/classic/galleria.classic.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/folio/galleria.folio.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/folio/galleria.folio.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/folio/galleria.folio.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/folio/galleria.folio.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/fullscreen/galleria.fullscreen.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/fullscreen/galleria.fullscreen.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/fullscreen/galleria.fullscreen.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/fullscreen/galleria.fullscreen.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/fullscreen/index.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/miniml/galleria.miniml.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/miniml/galleria.miniml.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/miniml/galleria.miniml.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/miniml/galleria.miniml.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/twelve/galleria.twelve.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/twelve/galleria.twelve.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/twelve/galleria.twelve.min.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/static/themes/twelve/galleria.twelve.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/templates/album.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/templates/album_list.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/galleria/templates/base.html +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js.map +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-lightbox.esm.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe.css +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe.esm.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe.esm.js.map +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal/themes/photoswipe/static/photoswipe.esm.min.js +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/dependency_links.txt +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/entry_points.txt +0 -0
- {sigal-2.5 → sigal-2.6}/src/sigal.egg-info/top_level.txt +0 -0
- {sigal-2.5 → sigal-2.6}/tests/conftest.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/.venv/lib64/fake.png +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/accentu/303/251/11.jpg" +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/accentu/303/251/h/303/251lico/303/257de.jpg" +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/accentu/303/251/test?<special> chars#.jpg" +0 -0
- {sigal-2.5/tests/sample/pictures/dir1/test2 → sigal-2.6/tests/sample/pictures/dir1}/22.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/empty/fake.txt +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/11.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/11.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/CMB_Timeline300_no_WMAP.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/example.gif +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/flickr_jerquiaga_2394751088_cc-by-nc.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/flickr_jerquiaga_2394751088_cc-by-nc.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test1/outdoor.heic +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/21.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/21.tiff +0 -0
- {sigal-2.5/tests/sample/pictures/encryptTest → sigal-2.6/tests/sample/pictures/dir1/test2}/22.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/22.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/CMB_Timeline300_no_WMAP.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/CMB_Timeline300_no_WMAP.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test2/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test3/3.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir1/test3/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/.nozip_gallery +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/Hubble Interacting Galaxy NGC 5257.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/Hubble ultra deep field.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/KeckObservatory20071020.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/dir2/m57_the_ring_nebula-587px.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/empty/fake.txt +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/encryptTest/21.jpg +0 -0
- {sigal-2.5/tests/sample/pictures/exifTest → sigal-2.6/tests/sample/pictures/encryptTest}/22.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/exifTest/21.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/exifTest/noexif.png +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/iptcTest/1.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/iptcTest/2.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/iptcTest/2.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/iptcTest/3.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/iptcTest/index.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/created/.nomedia +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/created/ignored/should_be_ignored2.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/created/should_be_created.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/created/should_be_ignored3.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/ignored/.nomedia +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/ignored/recursively_ignored/should_be_ignored.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nomedia/ignored/should_be_ignored_1.jpg +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/nonmedia_files/dummy.pdf +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/video/example video.md +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/video/example video.ogv +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/webp/_MG_7805_lossy80.webp +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/pictures/webp/_MG_7808_lossy80.webp +0 -0
- {sigal-2.5 → sigal-2.6}/tests/sample/watermark.png +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_cli.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_compress_assets_plugin.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_encrypt.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_extended_caching.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_image.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_plugins.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_utils.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_video.py +0 -0
- {sigal-2.5 → sigal-2.6}/tests/test_zip.py +0 -0
|
@@ -16,10 +16,10 @@ jobs:
|
|
|
16
16
|
if: ((github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || contains(github.event.pull_request.labels.*.name, 'Build wheels'))
|
|
17
17
|
|
|
18
18
|
steps:
|
|
19
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@v6
|
|
20
20
|
with:
|
|
21
21
|
fetch-depth: 0
|
|
22
|
-
- uses: actions/setup-python@
|
|
22
|
+
- uses: actions/setup-python@v6
|
|
23
23
|
with:
|
|
24
24
|
python-version: "3.13"
|
|
25
25
|
|
|
@@ -16,20 +16,22 @@ jobs:
|
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
strategy:
|
|
18
18
|
matrix:
|
|
19
|
-
python-version: [
|
|
19
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
23
|
with:
|
|
24
24
|
fetch-depth: 0
|
|
25
25
|
- name: Set up Python ${{ matrix.python-version }}
|
|
26
|
-
uses: actions/setup-python@
|
|
26
|
+
uses: actions/setup-python@v6
|
|
27
27
|
with:
|
|
28
28
|
python-version: ${{ matrix.python-version }}
|
|
29
|
-
|
|
29
|
+
cache: 'pip'
|
|
30
|
+
cache-dependency-path: pyproject.toml
|
|
31
|
+
- name: Install FFmpeg & Poppler
|
|
30
32
|
run: |
|
|
31
33
|
sudo apt update
|
|
32
|
-
sudo apt install ffmpeg
|
|
34
|
+
sudo apt install ffmpeg poppler-utils
|
|
33
35
|
ffmpeg -version
|
|
34
36
|
- name: Install Tox
|
|
35
37
|
run: python -m pip install tox tox-gh-actions coverage
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
repos:
|
|
2
2
|
|
|
3
3
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
4
|
-
rev:
|
|
4
|
+
rev: v6.0.0
|
|
5
5
|
hooks:
|
|
6
6
|
- id: check-added-large-files
|
|
7
7
|
- id: check-merge-conflict
|
|
@@ -12,8 +12,8 @@ repos:
|
|
|
12
12
|
exclude: ".*(galleria|photoswipe|jquery|leaflet).*$"
|
|
13
13
|
|
|
14
14
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
15
|
-
rev: v0.
|
|
15
|
+
rev: v0.15.0
|
|
16
16
|
hooks:
|
|
17
|
-
- id: ruff
|
|
17
|
+
- id: ruff-check
|
|
18
18
|
args: [ --fix, --show-fixes, --exit-non-zero-on-fix ]
|
|
19
19
|
- id: ruff-format
|
{sigal-2.5 → sigal-2.6}/LICENSE
RENAMED
{sigal-2.5 → sigal-2.6}/PKG-INFO
RENAMED
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sigal
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6
|
|
4
4
|
Summary: Simple static gallery generator
|
|
5
5
|
Author-email: Simon Conseil <contact@saimon.org>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: repository, https://github.com/saimn/sigal
|
|
8
|
-
Project-URL: documentation,
|
|
8
|
+
Project-URL: documentation, https://sigal.readthedocs.io/en/latest/
|
|
9
9
|
Keywords: gallery,static,generator,image,video,galleria
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Environment :: Console
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
12
|
Classifier: Operating System :: OS Independent
|
|
14
13
|
Classifier: Programming Language :: Python :: 3
|
|
15
14
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
16
15
|
Classifier: Topic :: Multimedia :: Graphics :: Viewers
|
|
17
16
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
-
Requires-Python: >=3.
|
|
17
|
+
Requires-Python: >=3.11
|
|
19
18
|
Description-Content-Type: text/x-rst
|
|
20
19
|
License-File: LICENSE
|
|
21
20
|
Requires-Dist: blinker
|
|
22
21
|
Requires-Dist: click
|
|
23
22
|
Requires-Dist: Jinja2>=2.7
|
|
24
23
|
Requires-Dist: Markdown
|
|
25
|
-
Requires-Dist: Pillow>=
|
|
24
|
+
Requires-Dist: Pillow>=10.0.0
|
|
26
25
|
Requires-Dist: pilkit
|
|
27
26
|
Requires-Dist: natsort
|
|
28
27
|
Provides-Extra: all
|
|
@@ -31,6 +30,7 @@ Requires-Dist: feedgenerator; extra == "all"
|
|
|
31
30
|
Requires-Dist: zopfli; extra == "all"
|
|
32
31
|
Requires-Dist: cryptography; extra == "all"
|
|
33
32
|
Requires-Dist: pillow-heif; extra == "all"
|
|
33
|
+
Requires-Dist: pdf2image; extra == "all"
|
|
34
34
|
Provides-Extra: tests
|
|
35
35
|
Requires-Dist: pytest; extra == "tests"
|
|
36
36
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
@@ -38,6 +38,7 @@ Provides-Extra: docs
|
|
|
38
38
|
Requires-Dist: Sphinx>=4.1.0; extra == "docs"
|
|
39
39
|
Requires-Dist: furo; extra == "docs"
|
|
40
40
|
Requires-Dist: cryptography; extra == "docs"
|
|
41
|
+
Dynamic: license-file
|
|
41
42
|
|
|
42
43
|
Sigal - Simple Static Gallery Generator
|
|
43
44
|
=======================================
|
|
@@ -64,7 +65,7 @@ The idea behind Sigal is to ease the use of the javascript libraries like
|
|
|
64
65
|
galleria_. These libraries do a great job to display the images, Sigal does
|
|
65
66
|
what is missing: resize images, create thumbnails, generate HTML pages.
|
|
66
67
|
|
|
67
|
-
Sigal requires Python 3.
|
|
68
|
+
Sigal requires Python 3.11+.
|
|
68
69
|
|
|
69
70
|
Links
|
|
70
71
|
-----
|
|
@@ -83,7 +84,7 @@ Javascript libraries:
|
|
|
83
84
|
- `galleria demo`_
|
|
84
85
|
- `photoswipe demo`_
|
|
85
86
|
|
|
86
|
-
.. _website:
|
|
87
|
+
.. _website: https://sigal.readthedocs.io/en/latest/
|
|
87
88
|
.. _GitHub: https://github.com/saimn/sigal/
|
|
88
89
|
.. _PyPI: https://pypi.org/project/sigal/
|
|
89
90
|
.. _galleria: https://github.com/GalleriaJS/galleria
|
|
@@ -23,7 +23,7 @@ The idea behind Sigal is to ease the use of the javascript libraries like
|
|
|
23
23
|
galleria_. These libraries do a great job to display the images, Sigal does
|
|
24
24
|
what is missing: resize images, create thumbnails, generate HTML pages.
|
|
25
25
|
|
|
26
|
-
Sigal requires Python 3.
|
|
26
|
+
Sigal requires Python 3.11+.
|
|
27
27
|
|
|
28
28
|
Links
|
|
29
29
|
-----
|
|
@@ -42,7 +42,7 @@ Javascript libraries:
|
|
|
42
42
|
- `galleria demo`_
|
|
43
43
|
- `photoswipe demo`_
|
|
44
44
|
|
|
45
|
-
.. _website:
|
|
45
|
+
.. _website: https://sigal.readthedocs.io/en/latest/
|
|
46
46
|
.. _GitHub: https://github.com/saimn/sigal/
|
|
47
47
|
.. _PyPI: https://pypi.org/project/sigal/
|
|
48
48
|
.. _galleria: https://github.com/GalleriaJS/galleria
|
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
===========
|
|
4
4
|
|
|
5
|
+
Version 2.6
|
|
6
|
+
~~~~~~~~~~~~~~
|
|
7
|
+
|
|
8
|
+
Released on 2026-02-06.
|
|
9
|
+
|
|
10
|
+
Sigal now requires Python 3.11+.
|
|
11
|
+
|
|
12
|
+
- With the photoswipe theme, albums can contain both images and sub-albums
|
|
13
|
+
[:issue:`535`].
|
|
14
|
+
- Fix issue with latest version of feedgenerator.
|
|
15
|
+
- Fix compat with click 8.2.0.
|
|
16
|
+
- Fix theme URL for photoswipe.
|
|
17
|
+
- Thumbnail can now be set in ``index.md`` either with the original filename or
|
|
18
|
+
with the thumbnail name after format conversion [:issue:`476`].
|
|
19
|
+
- Allow portrait orientation for thumbnails [:issue:`531`].
|
|
20
|
+
- nonmedia_files plugin: adding support for PDF thumbnails [:issue:`536`].
|
|
21
|
+
|
|
5
22
|
Version 2.5
|
|
6
23
|
~~~~~~~~~~~
|
|
7
24
|
|
|
@@ -27,7 +27,7 @@ master_doc = "index"
|
|
|
27
27
|
|
|
28
28
|
# General information about the project.
|
|
29
29
|
project = "Sigal"
|
|
30
|
-
copyright = "2012-
|
|
30
|
+
copyright = "2012-2026, Simon Conseil"
|
|
31
31
|
|
|
32
32
|
# The version info for the project you're documenting, acts as replacement for
|
|
33
33
|
# |version| and |release|, also used in various other places throughout the
|
|
@@ -8,31 +8,31 @@ description = "Simple static gallery generator"
|
|
|
8
8
|
readme = "README.rst"
|
|
9
9
|
authors = [{name = "Simon Conseil", email = "contact@saimon.org"}]
|
|
10
10
|
keywords = ["gallery", "static", "generator", "image", "video", "galleria"]
|
|
11
|
-
license =
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
12
13
|
classifiers = [
|
|
13
14
|
"Development Status :: 5 - Production/Stable",
|
|
14
15
|
"Environment :: Console",
|
|
15
|
-
"License :: OSI Approved :: MIT License",
|
|
16
16
|
"Operating System :: OS Independent",
|
|
17
17
|
"Programming Language :: Python :: 3",
|
|
18
18
|
"Topic :: Internet :: WWW/HTTP",
|
|
19
19
|
"Topic :: Multimedia :: Graphics :: Viewers",
|
|
20
20
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
21
21
|
]
|
|
22
|
-
requires-python = ">=3.
|
|
22
|
+
requires-python = ">=3.11"
|
|
23
23
|
dependencies = [
|
|
24
24
|
"blinker",
|
|
25
25
|
"click",
|
|
26
26
|
"Jinja2>=2.7",
|
|
27
27
|
"Markdown",
|
|
28
|
-
"Pillow>=
|
|
28
|
+
"Pillow>=10.0.0",
|
|
29
29
|
"pilkit",
|
|
30
30
|
"natsort",
|
|
31
31
|
]
|
|
32
32
|
dynamic = ["version"]
|
|
33
33
|
|
|
34
34
|
[project.optional-dependencies]
|
|
35
|
-
all = ["brotli", "feedgenerator", "zopfli", "cryptography", "pillow-heif"]
|
|
35
|
+
all = ["brotli", "feedgenerator", "zopfli", "cryptography", "pillow-heif", "pdf2image"]
|
|
36
36
|
tests = ["pytest", "pytest-cov"]
|
|
37
37
|
docs = ["Sphinx>=4.1.0", "furo", "cryptography"]
|
|
38
38
|
|
|
@@ -41,11 +41,10 @@ sigal = "sigal.__main__:main"
|
|
|
41
41
|
|
|
42
42
|
[project.urls]
|
|
43
43
|
repository = "https://github.com/saimn/sigal"
|
|
44
|
-
documentation = "
|
|
44
|
+
documentation = "https://sigal.readthedocs.io/en/latest/"
|
|
45
45
|
|
|
46
46
|
[tool.setuptools]
|
|
47
47
|
include-package-data = true
|
|
48
|
-
license-files = ["LICENSE"]
|
|
49
48
|
|
|
50
49
|
[tool.setuptools.packages.find]
|
|
51
50
|
where = ["src"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2009-
|
|
1
|
+
# Copyright (c) 2009-2026 - Simon Conseil
|
|
2
2
|
|
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
4
|
# of this software and associated documentation files (the "Software"), to
|
|
@@ -237,15 +237,17 @@ def serve(destination, port, config, browser):
|
|
|
237
237
|
settings = read_settings(config)
|
|
238
238
|
destination = settings.get("destination")
|
|
239
239
|
if not os.path.exists(destination):
|
|
240
|
-
|
|
240
|
+
click.echo(
|
|
241
241
|
f"The '{destination}' directory doesn't exist, maybe try building"
|
|
242
|
-
" first
|
|
242
|
+
" first?",
|
|
243
|
+
err=True,
|
|
243
244
|
)
|
|
244
245
|
sys.exit(1)
|
|
245
246
|
else:
|
|
246
|
-
|
|
247
|
+
click.echo(
|
|
247
248
|
f"The {destination} directory doesn't exist "
|
|
248
|
-
f"and the config file ({config}) could not be read
|
|
249
|
+
f"and the config file ({config}) could not be read.",
|
|
250
|
+
err=True,
|
|
249
251
|
)
|
|
250
252
|
sys.exit(2)
|
|
251
253
|
|
|
@@ -284,10 +286,10 @@ def set_meta(target, keys, overwrite=False):
|
|
|
284
286
|
"""
|
|
285
287
|
|
|
286
288
|
if not os.path.exists(target):
|
|
287
|
-
|
|
289
|
+
click.echo(f"The target {target} does not exist.", err=True)
|
|
288
290
|
sys.exit(1)
|
|
289
291
|
if len(keys) < 2 or len(keys) % 2 > 0:
|
|
290
|
-
|
|
292
|
+
click.echo("Need an even number of arguments.", err=True)
|
|
291
293
|
sys.exit(1)
|
|
292
294
|
|
|
293
295
|
if os.path.isdir(target):
|
|
@@ -295,9 +297,10 @@ def set_meta(target, keys, overwrite=False):
|
|
|
295
297
|
else:
|
|
296
298
|
descfile = os.path.splitext(target)[0] + ".md"
|
|
297
299
|
if os.path.exists(descfile) and not overwrite:
|
|
298
|
-
|
|
300
|
+
click.echo(
|
|
299
301
|
f"Description file '{descfile}' already exists. "
|
|
300
|
-
"Use --overwrite to overwrite it
|
|
302
|
+
"Use --overwrite to overwrite it.",
|
|
303
|
+
err=True,
|
|
301
304
|
)
|
|
302
305
|
sys.exit(2)
|
|
303
306
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2009-
|
|
1
|
+
# Copyright (c) 2009-2026 - Simon Conseil
|
|
2
2
|
# Copyright (c) 2013 - Christophe-Marie Duquesne
|
|
3
3
|
# Copyright (c) 2014 - Jonas Kaufmann
|
|
4
4
|
# Copyright (c) 2015 - François D.
|
|
@@ -52,7 +52,7 @@ from .image import (
|
|
|
52
52
|
get_size,
|
|
53
53
|
process_image,
|
|
54
54
|
)
|
|
55
|
-
from .settings import Status, get_thumb
|
|
55
|
+
from .settings import IMG_EXTENSIONS, Status, get_thumb
|
|
56
56
|
from .utils import (
|
|
57
57
|
Devnull,
|
|
58
58
|
check_or_create_dir,
|
|
@@ -246,15 +246,10 @@ class Image(Media):
|
|
|
246
246
|
super().__init__(filename, path, settings)
|
|
247
247
|
imgformat = settings.get("img_format")
|
|
248
248
|
|
|
249
|
-
|
|
250
|
-
PILImage.init()
|
|
251
|
-
|
|
252
|
-
if imgformat and PILImage.EXTENSION[self.src_ext] != imgformat.upper():
|
|
249
|
+
if imgformat and IMG_EXTENSIONS.ext2format[self.src_ext] != imgformat.upper():
|
|
253
250
|
# Find the extension that should match img_format
|
|
254
|
-
|
|
255
|
-
ext = extensions[imgformat.upper()]
|
|
251
|
+
ext = IMG_EXTENSIONS.format2ext[imgformat.upper()]
|
|
256
252
|
self.dst_filename = self.basename + ext
|
|
257
|
-
self.thumb_name = get_thumb(self.settings, self.dst_filename)
|
|
258
253
|
|
|
259
254
|
@cached_property
|
|
260
255
|
def date(self):
|
|
@@ -593,76 +588,76 @@ class Album:
|
|
|
593
588
|
# Test the thumbnail from the Markdown file.
|
|
594
589
|
thumbnail = self.meta.get("thumbnail", [""])[0]
|
|
595
590
|
|
|
596
|
-
if thumbnail
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
)
|
|
591
|
+
if thumbnail:
|
|
592
|
+
# if thumbnail is set in the markdown, it can be either the
|
|
593
|
+
# original filename or the generated name after format conversion
|
|
594
|
+
if isfile(join(self.src_path, thumbnail)):
|
|
595
|
+
thumbnail = get_thumb(self.settings, thumbnail)
|
|
596
|
+
self._thumbnail = url_from_path(join(self.name, thumbnail))
|
|
600
597
|
self.logger.debug("Thumbnail for %r : %s", self, self._thumbnail)
|
|
601
598
|
return self._thumbnail
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
599
|
+
|
|
600
|
+
# find and return the first landscape image
|
|
601
|
+
for f in self.medias:
|
|
602
|
+
ext = splitext(f.dst_filename)[1]
|
|
603
|
+
if ext.lower() not in self.settings["img_extensions"]:
|
|
604
|
+
continue
|
|
605
|
+
|
|
606
|
+
# Use f.size if available as it is quicker (in cache), but
|
|
607
|
+
# fallback to the size of src_path if dst_path is missing
|
|
608
|
+
size = f.input_size
|
|
609
|
+
if size is None:
|
|
610
|
+
size = f.file_metadata["size"]
|
|
611
|
+
|
|
612
|
+
if size["width"] > size["height"]:
|
|
613
|
+
try:
|
|
614
|
+
self._thumbnail = url_quote(self.name) + "/" + f.thumbnail
|
|
615
|
+
except Exception as e:
|
|
616
|
+
self.logger.info(
|
|
617
|
+
"Failed to get thumbnail for %s: %s", f.dst_filename, e
|
|
618
|
+
)
|
|
619
|
+
else:
|
|
620
|
+
self.logger.debug(
|
|
621
|
+
"Use 1st landscape image as thumbnail for %r : %s",
|
|
622
|
+
self,
|
|
623
|
+
self._thumbnail,
|
|
624
|
+
)
|
|
625
|
+
return self._thumbnail
|
|
626
|
+
|
|
627
|
+
# else simply return the 1st media file
|
|
628
|
+
if not self._thumbnail and self.medias:
|
|
629
|
+
for media in self.medias:
|
|
630
|
+
if media.thumbnail is not None:
|
|
616
631
|
try:
|
|
617
|
-
self._thumbnail = url_quote(self.name) + "/" +
|
|
632
|
+
self._thumbnail = url_quote(self.name) + "/" + media.thumbnail
|
|
618
633
|
except Exception as e:
|
|
619
634
|
self.logger.info(
|
|
620
|
-
"Failed to get thumbnail for %s: %s",
|
|
635
|
+
"Failed to get thumbnail for %s: %s",
|
|
636
|
+
media.dst_filename,
|
|
637
|
+
e,
|
|
621
638
|
)
|
|
622
639
|
else:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
)
|
|
628
|
-
return self._thumbnail
|
|
629
|
-
|
|
630
|
-
# else simply return the 1st media file
|
|
631
|
-
if not self._thumbnail and self.medias:
|
|
632
|
-
for media in self.medias:
|
|
633
|
-
if media.thumbnail is not None:
|
|
634
|
-
try:
|
|
635
|
-
self._thumbnail = (
|
|
636
|
-
url_quote(self.name) + "/" + media.thumbnail
|
|
637
|
-
)
|
|
638
|
-
except Exception as e:
|
|
639
|
-
self.logger.info(
|
|
640
|
-
"Failed to get thumbnail for %s: %s",
|
|
641
|
-
media.dst_filename,
|
|
642
|
-
e,
|
|
643
|
-
)
|
|
644
|
-
else:
|
|
645
|
-
break
|
|
646
|
-
else:
|
|
647
|
-
self.logger.warning("No thumbnail found for %r", self)
|
|
648
|
-
return
|
|
640
|
+
break
|
|
641
|
+
else:
|
|
642
|
+
self.logger.warning("No thumbnail found for %r", self)
|
|
643
|
+
return
|
|
649
644
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
645
|
+
self.logger.debug(
|
|
646
|
+
"Use the 1st image as thumbnail for %r : %s", self, self._thumbnail
|
|
647
|
+
)
|
|
648
|
+
return self._thumbnail
|
|
649
|
+
|
|
650
|
+
# use the thumbnail of their sub-directories
|
|
651
|
+
if not self._thumbnail:
|
|
652
|
+
for path, album in self.gallery.get_albums(self.path):
|
|
653
|
+
if album.thumbnail:
|
|
654
|
+
self._thumbnail = url_quote(self.name) + "/" + album.thumbnail
|
|
655
|
+
self.logger.debug(
|
|
656
|
+
"Using thumbnail from sub-directory for %r : %s",
|
|
657
|
+
self,
|
|
658
|
+
self._thumbnail,
|
|
659
|
+
)
|
|
660
|
+
return self._thumbnail
|
|
666
661
|
|
|
667
662
|
self.logger.error("Thumbnail not found for %r", self)
|
|
668
663
|
|
|
@@ -918,14 +913,6 @@ class Gallery:
|
|
|
918
913
|
) as albums:
|
|
919
914
|
for album in albums:
|
|
920
915
|
if album.albums:
|
|
921
|
-
if album.medias:
|
|
922
|
-
self.logger.warning(
|
|
923
|
-
"Album '%s' contains sub-albums and images. "
|
|
924
|
-
"Please move images to their own sub-album. "
|
|
925
|
-
"Images in album %s will not be visible.",
|
|
926
|
-
album.title,
|
|
927
|
-
album.title,
|
|
928
|
-
)
|
|
929
916
|
album_list_writer.write(album)
|
|
930
917
|
else:
|
|
931
918
|
album_writer.write(album)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2009-
|
|
1
|
+
# Copyright (c) 2009-2026 - Simon Conseil
|
|
2
2
|
# Copyright (c) 2015 - François D.
|
|
3
3
|
# Copyright (c) 2018 - Edwin Steele
|
|
4
4
|
|
|
@@ -99,6 +99,7 @@ def generate_image(source, outname, settings, options=None):
|
|
|
99
99
|
|
|
100
100
|
img = _read_image(source)
|
|
101
101
|
original_format = img.format
|
|
102
|
+
logger.debug("Read %s: %dx%d (%s)", source, *img.size, original_format)
|
|
102
103
|
|
|
103
104
|
if settings["copy_exif_data"] and settings["autorotate_images"]:
|
|
104
105
|
logger.warning(
|
|
@@ -149,7 +150,7 @@ def generate_image(source, outname, settings, options=None):
|
|
|
149
150
|
# format, or fall back to JPEG
|
|
150
151
|
outformat = settings.get("img_format") or img.format or original_format or "JPEG"
|
|
151
152
|
|
|
152
|
-
logger.debug("Save resized image
|
|
153
|
+
logger.debug("Save resized image: %s, %dx%d (%s)", outname, *img.size, outformat)
|
|
153
154
|
save_image(img, outname, outformat, options=options, autoconvert=True)
|
|
154
155
|
|
|
155
156
|
|
|
@@ -162,6 +163,7 @@ def generate_thumbnail(
|
|
|
162
163
|
img = _read_image(source)
|
|
163
164
|
img = Transpose().process(img)
|
|
164
165
|
original_format = img.format
|
|
166
|
+
logger.debug("Read %s: %dx%d (%s)", source, *img.size, original_format)
|
|
165
167
|
|
|
166
168
|
try:
|
|
167
169
|
method = PILImage.Resampling.LANCZOS
|
|
@@ -175,7 +177,7 @@ def generate_thumbnail(
|
|
|
175
177
|
img.thumbnail(box, method)
|
|
176
178
|
|
|
177
179
|
outformat = img.format or original_format or "JPEG"
|
|
178
|
-
logger.debug("Save
|
|
180
|
+
logger.debug("Save thumbnail image: %s, %dx%d (%s)", outname, *img.size, outformat)
|
|
179
181
|
save_image(img, outname, outformat, options=options, autoconvert=True)
|
|
180
182
|
|
|
181
183
|
|
|
@@ -70,6 +70,7 @@ def generate_feed(gallery, medias, feed_type=None, feed_url="", nb_items=0):
|
|
|
70
70
|
feed.add_item(
|
|
71
71
|
title=Markup.escape(item.title or item.url),
|
|
72
72
|
link=link,
|
|
73
|
+
content=None,
|
|
73
74
|
# unique_id='tag:%s,%s:%s' % (urlparse(link).netloc,
|
|
74
75
|
# item.date.date(),
|
|
75
76
|
# urlparse(link).path.lstrip('/')),
|
|
@@ -4,6 +4,9 @@ This plugin will copy the files into the build tree and generate generic
|
|
|
4
4
|
thumbnails for the files. In-browser previews will likely fail, and
|
|
5
5
|
it is up to the theme to provide correct support for downloads.
|
|
6
6
|
|
|
7
|
+
If the `pdf2image <https://pypi.org/project/pdf2image/>`_ optional dependency is installed,
|
|
8
|
+
it will be used to generate thumbnails for PDF files.
|
|
9
|
+
|
|
7
10
|
Settings available as dictionary in ``nonmedia_files_options``:
|
|
8
11
|
|
|
9
12
|
- ``ext_as_thumb``: Enable simple thumbnail showing ext. Default to ``True``
|
|
@@ -26,6 +29,10 @@ Settings available as dictionary in ``nonmedia_files_options``:
|
|
|
26
29
|
import logging
|
|
27
30
|
import os
|
|
28
31
|
|
|
32
|
+
try: # Optional dependency:
|
|
33
|
+
from pdf2image import convert_from_path as pdf2img
|
|
34
|
+
except ImportError:
|
|
35
|
+
pdf2img = None
|
|
29
36
|
from PIL import Image as PILImage
|
|
30
37
|
from PIL import ImageDraw, ImageFont
|
|
31
38
|
from pilkit.utils import save_image
|
|
@@ -102,9 +109,7 @@ def generate_thumbnail(
|
|
|
102
109
|
logger.info(f"kwargs: {kwargs}")
|
|
103
110
|
d.text(anchor, text, anchor="mm", **kwargs)
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
logger.info("Save thumnail image: %s (%s)", outname, outformat)
|
|
107
|
-
save_image(img, outname, outformat, options=options, autoconvert=True)
|
|
112
|
+
save_image(img, outname, "JPEG", options=options, autoconvert=True)
|
|
108
113
|
|
|
109
114
|
|
|
110
115
|
def process_thumb(media):
|
|
@@ -113,18 +118,24 @@ def process_thumb(media):
|
|
|
113
118
|
utils.copy(media.src_path, media.dst_path, symlink=settings["orig_link"])
|
|
114
119
|
|
|
115
120
|
if plugin_settings.get("ext_as_thumb", DEFAULT_CONFIG["ext_as_thumb"]):
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
if pdf2img and media.src_ext.lower() == ".pdf":
|
|
122
|
+
images = pdf2img(
|
|
123
|
+
media.src_path, single_file=True, size=settings["thumb_size"]
|
|
124
|
+
)
|
|
125
|
+
images[0].save(media.thumb_path)
|
|
126
|
+
else:
|
|
127
|
+
kwargs = {}
|
|
128
|
+
for key in ("bg_color", "font", "font_color", "font_size"):
|
|
129
|
+
if f"thumb_{key}" in plugin_settings:
|
|
130
|
+
kwargs[key] = plugin_settings[f"thumb_{key}"]
|
|
131
|
+
generate_thumbnail(
|
|
132
|
+
media.src_ext[1:].upper(),
|
|
133
|
+
media.thumb_path,
|
|
134
|
+
settings["thumb_size"],
|
|
135
|
+
options=settings["jpg_options"],
|
|
136
|
+
**kwargs,
|
|
137
|
+
)
|
|
138
|
+
logger.info("Saved thumbnail image: %s", media.thumb_path)
|
|
128
139
|
|
|
129
140
|
|
|
130
141
|
def process_nonmedia(media):
|