sigal 2.3__py3-none-any.whl → 2.5__py3-none-any.whl

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.
Files changed (66) hide show
  1. sigal/__init__.py +2 -285
  2. sigal/__main__.py +312 -0
  3. sigal/gallery.py +188 -158
  4. sigal/image.py +113 -115
  5. sigal/log.py +11 -11
  6. sigal/plugins/adjust.py +4 -4
  7. sigal/plugins/compress_assets.py +26 -25
  8. sigal/plugins/copyright.py +8 -8
  9. sigal/plugins/encrypt/encrypt.py +7 -7
  10. sigal/plugins/encrypt/endec.py +2 -2
  11. sigal/plugins/extended_caching.py +26 -22
  12. sigal/plugins/feeds.py +19 -21
  13. sigal/plugins/media_page.py +1 -1
  14. sigal/plugins/nomedia.py +1 -1
  15. sigal/plugins/nonmedia_files.py +59 -93
  16. sigal/plugins/titleregexp.py +98 -0
  17. sigal/plugins/watermark.py +13 -13
  18. sigal/plugins/zip_gallery.py +17 -8
  19. sigal/settings.py +92 -78
  20. sigal/signals.py +10 -10
  21. sigal/templates/sigal.conf.py +18 -14
  22. sigal/themes/default/templates/decrypt.html +1 -0
  23. sigal/themes/default/templates/description.html +29 -0
  24. sigal/themes/default/templates/footer.html +3 -0
  25. sigal/themes/galleria/templates/album_items.html +4 -23
  26. sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.js +414 -0
  27. sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.min.js +5 -0
  28. sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.js +129 -0
  29. sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.min.js +8 -0
  30. sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js +1960 -0
  31. sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js.map +1 -0
  32. sigal/themes/photoswipe/static/photoswipe-lightbox.esm.min.js +5 -0
  33. sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.js +257 -0
  34. sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.min.js +1 -0
  35. sigal/themes/photoswipe/static/photoswipe.css +385 -140
  36. sigal/themes/photoswipe/static/photoswipe.esm.js +7081 -0
  37. sigal/themes/photoswipe/static/photoswipe.esm.js.map +1 -0
  38. sigal/themes/photoswipe/static/photoswipe.esm.min.js +5 -0
  39. sigal/themes/photoswipe/static/styles.css +53 -0
  40. sigal/themes/photoswipe/templates/album.html +69 -74
  41. sigal/utils.py +80 -12
  42. sigal/version.py +20 -4
  43. sigal/video.py +43 -24
  44. sigal/writer.py +26 -8
  45. {sigal-2.3.dist-info → sigal-2.5.dist-info}/LICENSE +1 -1
  46. {sigal-2.3.dist-info → sigal-2.5.dist-info}/METADATA +23 -30
  47. {sigal-2.3.dist-info → sigal-2.5.dist-info}/RECORD +50 -50
  48. {sigal-2.3.dist-info → sigal-2.5.dist-info}/WHEEL +1 -1
  49. sigal-2.5.dist-info/entry_points.txt +2 -0
  50. sigal/plugins/upload_s3.py +0 -106
  51. sigal/themes/photoswipe/static/app.js +0 -214
  52. sigal/themes/photoswipe/static/default-skin/default-skin.css +0 -485
  53. sigal/themes/photoswipe/static/default-skin/default-skin.css.map +0 -10
  54. sigal/themes/photoswipe/static/default-skin/default-skin.png +0 -0
  55. sigal/themes/photoswipe/static/default-skin/default-skin.svg +0 -36
  56. sigal/themes/photoswipe/static/default-skin/preloader.gif +0 -0
  57. sigal/themes/photoswipe/static/echo/blank.gif +0 -0
  58. sigal/themes/photoswipe/static/echo/echo.js +0 -135
  59. sigal/themes/photoswipe/static/echo/echo.min.js +0 -2
  60. sigal/themes/photoswipe/static/photoswipe-ui-default.js +0 -871
  61. sigal/themes/photoswipe/static/photoswipe-ui-default.min.js +0 -1
  62. sigal/themes/photoswipe/static/photoswipe.css.map +0 -10
  63. sigal/themes/photoswipe/static/photoswipe.js +0 -3592
  64. sigal/themes/photoswipe/static/photoswipe.min.js +0 -1
  65. sigal-2.3.dist-info/entry_points.txt +0 -2
  66. {sigal-2.3.dist-info → sigal-2.5.dist-info}/top_level.txt +0 -0
sigal/video.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2013 - Christophe-Marie Duquesne
2
- # Copyright (c) 2013-2020 - Simon Conseil
2
+ # Copyright (c) 2013-2023 - Simon Conseil
3
3
  # Copyright (c) 2021 - Keith Feldman
4
4
 
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,8 +27,9 @@ import shutil
27
27
  import subprocess
28
28
  from os.path import splitext
29
29
 
30
+ from PIL import Image as PILImage
31
+
30
32
  from . import image, utils
31
- from .settings import Status
32
33
  from .utils import is_valid_html5_video
33
34
 
34
35
 
@@ -97,10 +98,10 @@ def get_resize_options(source, converter, output_size):
97
98
  # + I made a drawing on paper to figure this out
98
99
  if h_dst * w_src < h_src * w_dst:
99
100
  # biggest fitting dimension is height
100
- resize_opt = ["-vf", "scale=trunc(oh*a/2)*2:%i" % h_dst]
101
+ resize_opt = ["-vf", f"scale=trunc(oh*a/2)*2:{h_dst:d}"]
101
102
  else:
102
103
  # biggest fitting dimension is width
103
- resize_opt = ["-vf", "scale=%i:trunc(ow/a/2)*2" % w_dst]
104
+ resize_opt = ["-vf", f"scale={w_dst:d}:trunc(ow/a/2)*2"]
104
105
 
105
106
  return resize_opt
106
107
 
@@ -173,17 +174,43 @@ def generate_video(source, outname, settings):
173
174
 
174
175
 
175
176
  def generate_thumbnail(
176
- source, outname, box, delay, fit=True, options=None, converter="ffmpeg"
177
+ source,
178
+ outname,
179
+ box,
180
+ delay,
181
+ fit=True,
182
+ options=None,
183
+ converter="ffmpeg",
184
+ black_retries=0,
185
+ black_offset=1,
186
+ black_max_colors=4,
177
187
  ):
178
188
  """Create a thumbnail image for the video source, based on ffmpeg."""
179
189
  logger = logging.getLogger(__name__)
180
190
  tmpfile = outname + ".tmp.jpg"
181
191
 
182
- # dump an image of the video
183
- cmd = [converter, "-i", source, "-an", "-r", "1"]
184
- cmd += ["-ss", str(delay), "-vframes", "1", "-y", tmpfile]
185
- logger.debug("Create thumbnail for video: %s", " ".join(cmd))
186
- check_subprocess(cmd, source, outname)
192
+ currentTry = 0
193
+ iDelay = int(delay)
194
+ while currentTry <= abs(black_retries):
195
+ # dump an image of the video
196
+ cmd = [converter, "-i", source, "-an", "-r", "1"]
197
+ cmd += ["-ss", str(iDelay), "-vframes", "1", "-y", tmpfile]
198
+ logger.debug("Create thumbnail for video: %s", " ".join(cmd))
199
+ check_subprocess(cmd, source, outname)
200
+ if os.path.isfile(tmpfile) and black_retries > 0:
201
+ with PILImage.open(tmpfile) as img:
202
+ colors = img.getcolors(maxcolors=black_max_colors)
203
+ if colors is None:
204
+ # There were more colors than maxcolors in the image, it
205
+ # looks suitable for a valid thumbnail
206
+ break
207
+ else:
208
+ # Only found 'maxcolors' unique colors, looks like a solid
209
+ # color, try again with another seek delay
210
+ currentTry += 1
211
+ iDelay += abs(black_offset)
212
+ else:
213
+ break
187
214
 
188
215
  # Sometimes ffmpeg fails with returncode zero but without producing an
189
216
  # output file Thus, we need to check if an output file was created. If
@@ -206,7 +233,7 @@ def process_video(media):
206
233
  logger = logging.getLogger(__name__)
207
234
  settings = media.settings
208
235
 
209
- try:
236
+ with utils.raise_if_debug() as status:
210
237
  if settings["use_orig"] and is_valid_html5_video(media.src_ext):
211
238
  utils.copy(media.src_path, media.dst_path, symlink=settings["orig_link"])
212
239
  else:
@@ -219,14 +246,8 @@ def process_video(media):
219
246
  )
220
247
  raise ValueError
221
248
  generate_video(media.src_path, media.dst_path, settings)
222
- except Exception:
223
- if logger.getEffectiveLevel() == logging.DEBUG:
224
- raise
225
- else:
226
- return Status.FAILURE
227
249
 
228
- if settings["make_thumbs"]:
229
- try:
250
+ if settings["make_thumbs"]:
230
251
  generate_thumbnail(
231
252
  media.dst_path,
232
253
  media.thumb_path,
@@ -235,11 +256,9 @@ def process_video(media):
235
256
  fit=settings["thumb_fit"],
236
257
  options=settings["jpg_options"],
237
258
  converter=settings["video_converter"],
259
+ black_retries=settings["thumb_video_black_retries"],
260
+ black_offset=settings["thumb_video_black_retry_offset"],
261
+ black_max_colors=settings["thumb_video_black_max_colors"],
238
262
  )
239
- except Exception:
240
- if logger.getEffectiveLevel() == logging.DEBUG:
241
- raise
242
- else:
243
- return Status.FAILURE
244
263
 
245
- return Status.SUCCESS
264
+ return status.value
sigal/writer.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2020 - Simon Conseil
1
+ # Copyright (c) 2009-2023 - Simon Conseil
2
2
  # Copyright (c) 2013 - Christophe-Marie Duquesne
3
3
  # Copyright (c) 2018 - Edwin Steele
4
4
 
@@ -24,8 +24,10 @@ import importlib
24
24
  import logging
25
25
  import os
26
26
  import shutil
27
+ import stat
27
28
  import sys
28
29
  import types
30
+ from datetime import datetime
29
31
 
30
32
  from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PrefixLoader
31
33
  from jinja2.exceptions import TemplateNotFound
@@ -54,7 +56,7 @@ class AbstractWriter:
54
56
  ):
55
57
  self.theme = os.path.join(THEMES_PATH, self.theme)
56
58
  if not os.path.exists(self.theme):
57
- raise Exception("Impossible to find the theme %s" % self.theme)
59
+ raise Exception(f"Impossible to find the theme {self.theme}")
58
60
 
59
61
  self.logger.info("Theme : %s", self.theme)
60
62
  theme_relpath = os.path.join(self.theme, "templates")
@@ -75,10 +77,10 @@ class AbstractWriter:
75
77
  # handle optional filters.py
76
78
  filters_py = os.path.join(self.theme, "filters.py")
77
79
  if os.path.exists(filters_py):
78
- self.logger.info('Loading filters file: %s', filters_py)
79
- module_spec = importlib.util.spec_from_file_location('filters', filters_py)
80
+ self.logger.info("Loading filters file: %s", filters_py)
81
+ module_spec = importlib.util.spec_from_file_location("filters", filters_py)
80
82
  mod = importlib.util.module_from_spec(module_spec)
81
- sys.modules['filters'] = mod
83
+ sys.modules["filters"] = mod
82
84
  module_spec.loader.exec_module(mod)
83
85
  for name in dir(mod):
84
86
  if isinstance(getattr(mod, name), types.FunctionType):
@@ -94,17 +96,30 @@ class AbstractWriter:
94
96
  )
95
97
  sys.exit(1)
96
98
 
97
- # Copy the theme files in the output dir
98
99
  self.theme_path = os.path.join(self.output_dir, "static")
100
+
101
+ def copy_theme_files(self):
102
+ """Copy the theme files to the destination"""
103
+ self.logger.info("Copying the theme files to the output dir")
104
+
99
105
  if os.path.isdir(self.theme_path):
100
106
  shutil.rmtree(self.theme_path)
101
107
 
102
108
  for static_path in (
103
- os.path.join(THEMES_PATH, 'default', 'static'),
104
- os.path.join(self.theme, 'static'),
109
+ os.path.join(THEMES_PATH, "default", "static"),
110
+ os.path.join(self.theme, "static"),
105
111
  ):
106
112
  shutil.copytree(static_path, self.theme_path, dirs_exist_ok=True)
107
113
 
114
+ # Ensure that the theme dir is writeable
115
+ for root, _, files in os.walk(self.theme_path):
116
+ st = os.stat(root)
117
+ os.chmod(root, st.st_mode | stat.S_IWUSR)
118
+ for name in files:
119
+ path = os.path.join(root, name)
120
+ st = os.stat(path)
121
+ os.chmod(path, st.st_mode | stat.S_IWUSR)
122
+
108
123
  if self.settings["user_css"]:
109
124
  if not os.path.exists(self.settings["user_css"]):
110
125
  self.logger.error(
@@ -124,6 +139,9 @@ class AbstractWriter:
124
139
  "index_title": self.index_title,
125
140
  "settings": self.settings,
126
141
  "sigal_link": sigal_link,
142
+ "generated_timestamp": datetime.now().strftime(
143
+ self.settings["datetime_format"]
144
+ ),
127
145
  "theme": {
128
146
  "name": os.path.basename(self.theme),
129
147
  "url": url_from_path(os.path.relpath(self.theme_path, album.dst_path)),
@@ -1,5 +1,5 @@
1
1
  The MIT License (MIT)
2
- Copyright (c) 2009-2022 - Simon Conseil
2
+ Copyright (c) 2009-2023 - Simon Conseil
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to
@@ -1,47 +1,43 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: sigal
3
- Version: 2.3
3
+ Version: 2.5
4
4
  Summary: Simple static gallery generator
5
- Home-page: https://github.com/saimn/sigal
6
- Author: Simon Conseil
7
- Author-email: contact@saimon.org
5
+ Author-email: Simon Conseil <contact@saimon.org>
8
6
  License: MIT License
7
+ Project-URL: repository, https://github.com/saimn/sigal
8
+ Project-URL: documentation, http://sigal.saimon.org/en/latest/
9
9
  Keywords: gallery,static,generator,image,video,galleria
10
- Platform: UNKNOWN
11
10
  Classifier: Development Status :: 5 - Production/Stable
12
11
  Classifier: Environment :: Console
13
12
  Classifier: License :: OSI Approved :: MIT License
14
13
  Classifier: Operating System :: OS Independent
15
14
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
15
  Classifier: Topic :: Internet :: WWW/HTTP
20
16
  Classifier: Topic :: Multimedia :: Graphics :: Viewers
21
17
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.9
23
19
  Description-Content-Type: text/x-rst
24
20
  License-File: LICENSE
25
21
  Requires-Dist: blinker
26
22
  Requires-Dist: click
27
- Requires-Dist: Jinja2 (>=2.7)
23
+ Requires-Dist: Jinja2>=2.7
28
24
  Requires-Dist: Markdown
29
- Requires-Dist: Pillow (>=4.0.0)
25
+ Requires-Dist: Pillow>=8.0.0
30
26
  Requires-Dist: pilkit
31
27
  Requires-Dist: natsort
32
28
  Provides-Extra: all
33
- Requires-Dist: boto ; extra == 'all'
34
- Requires-Dist: brotli ; extra == 'all'
35
- Requires-Dist: feedgenerator ; extra == 'all'
36
- Requires-Dist: zopfli ; extra == 'all'
37
- Requires-Dist: cryptography ; extra == 'all'
38
- Provides-Extra: docs
39
- Requires-Dist: Sphinx ; extra == 'docs'
40
- Requires-Dist: alabaster ; extra == 'docs'
41
- Requires-Dist: cryptography ; extra == 'docs'
29
+ Requires-Dist: brotli; extra == "all"
30
+ Requires-Dist: feedgenerator; extra == "all"
31
+ Requires-Dist: zopfli; extra == "all"
32
+ Requires-Dist: cryptography; extra == "all"
33
+ Requires-Dist: pillow-heif; extra == "all"
42
34
  Provides-Extra: tests
43
- Requires-Dist: pytest ; extra == 'tests'
44
- Requires-Dist: pytest-cov ; extra == 'tests'
35
+ Requires-Dist: pytest; extra == "tests"
36
+ Requires-Dist: pytest-cov; extra == "tests"
37
+ Provides-Extra: docs
38
+ Requires-Dist: Sphinx>=4.1.0; extra == "docs"
39
+ Requires-Dist: furo; extra == "docs"
40
+ Requires-Dist: cryptography; extra == "docs"
45
41
 
46
42
  Sigal - Simple Static Gallery Generator
47
43
  =======================================
@@ -68,14 +64,14 @@ The idea behind Sigal is to ease the use of the javascript libraries like
68
64
  galleria_. These libraries do a great job to display the images, Sigal does
69
65
  what is missing: resize images, create thumbnails, generate HTML pages.
70
66
 
71
- Sigal is compatible with Python 3.5+.
67
+ Sigal requires Python 3.9+.
72
68
 
73
- Links :
69
+ Links
70
+ -----
74
71
 
75
72
  * Latest documentation on the website_
76
73
  * Source, issues and pull requests on GitHub_
77
74
  * Releases on PyPI_
78
- * ``#sigal`` on Freenode, or with the webchat_ interface.
79
75
 
80
76
  Themes & Demo
81
77
  -------------
@@ -90,13 +86,10 @@ Javascript libraries:
90
86
  .. _website: http://sigal.saimon.org/
91
87
  .. _GitHub: https://github.com/saimn/sigal/
92
88
  .. _PyPI: https://pypi.org/project/sigal/
93
- .. _galleria: http://galleria.io/
89
+ .. _galleria: https://github.com/GalleriaJS/galleria
94
90
  .. _colorbox: http://www.jacklmoore.com/colorbox
95
91
  .. _photoswipe: http://photoswipe.com
96
92
  .. _galleria demo: http://saimon.org/sigal-demo/galleria/
97
93
  .. _colorbox demo: http://saimon.org/sigal-demo/colorbox/
98
94
  .. _photoswipe demo: http://saimon.org/sigal-demo/photoswipe/
99
- .. _webchat: http://webchat.freenode.net/?channels=sigal
100
95
  .. _Jinja2: https://palletsprojects.com/p/jinja/
101
-
102
-
@@ -1,32 +1,33 @@
1
- sigal/__init__.py,sha256=NNrFBHWThMBqXUtp-nJuLK49iH_V7mC-ZjH-raBTXv8,9754
2
- sigal/gallery.py,sha256=aQ4V0IJ6U1yIhtS54Zxp9-0K-109Dz5rxjciDzko0Ko,33631
3
- sigal/image.py,sha256=PKMgKiTHO5uU0BgoYPcvMRVEV9R_AtExqbANMQB9z8M,13788
4
- sigal/log.py,sha256=oyOktSQP833IqdpZ-qeOSkrRG4eKnX4i8fxjj-eCj5c,2588
5
- sigal/settings.py,sha256=HjOn2VEjnDJ9GByTOc0XLDjprAG2GFgaO97uUEd7L3E,6015
6
- sigal/signals.py,sha256=SBTN2YMtwQd66Y4nbNtxG68wuqaByvqRac__VhGNa28,445
7
- sigal/utils.py,sha256=SPDqdcWT-N_gQAN85OIIx0AYpOxcd6hWQf_pcRoDJgY,3964
8
- sigal/version.py,sha256=Vva_zTJp1mW_gWdtYOWM7aMDPNiynuUm9wff0HFwCyo,137
9
- sigal/video.py,sha256=aAHChSOZfGb47Zcb6rI2tSw-YHq_1UdDIUObcLLdhuw,8971
10
- sigal/writer.py,sha256=NgASMH5Y91F8KNavd54Arf9pxrf78ojodplxM-xemM8,5894
1
+ sigal/__init__.py,sha256=XmFtGi1i9IHJwfO6PSo2zcHVME2fCUHi8z7goxyF66Q,1258
2
+ sigal/__main__.py,sha256=YUJZmHYjp3r4yJFWA2AaAbEemskQpibqhs_6jtRHQ84,9587
3
+ sigal/gallery.py,sha256=JjQE_4GkNMy9IGNDRxKI6j28_7pPkuQvse_qRJIDDF0,34716
4
+ sigal/image.py,sha256=EnS8-ADcub3lKIex7ymWEjkjXPtZidqcCDDqWOfNq94,13425
5
+ sigal/log.py,sha256=aDCoUdXZmnyNntkGJng2rmTpWlOZgbCVhkDc0ZqpqPA,2588
6
+ sigal/settings.py,sha256=zojDBZnPF6ArYuzrl1u9cXYcKgBiat-ZZLKl_m2vgkQ,6272
7
+ sigal/signals.py,sha256=Q2qcr3DKnGxs_n-6SDKSA7aEVcX2ss-gZLgU6CO7uzY,445
8
+ sigal/utils.py,sha256=Tk0g0phzaW3KlbeOL0u-T6y46oBxMp7kPt5pbTLtGAo,5811
9
+ sigal/version.py,sha256=El14jpQdZIYub_dNYjZnU9XK_ijjLHH4ar3Gmj4wMAA,506
10
+ sigal/video.py,sha256=CwD7CyoD4Fv1eUDHVOW55TaDt_7gLqU7TLg0klup9tE,9721
11
+ sigal/writer.py,sha256=RFN1GxZpSsUrQvZyy7eSVGID7UD8NGsdhSEWoTiZIRE,6562
11
12
  sigal/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- sigal/plugins/adjust.py,sha256=KQOsiGqYjz8O4n8LVBZWrwxY7BrN4aWnj_vVAq_OOxs,761
13
- sigal/plugins/compress_assets.py,sha256=WL9ffLWRukWNmJbfN1WUuZpt562ei9SnzUv9E-fdRyI,5428
14
- sigal/plugins/copyright.py,sha256=_pciifSbgGpzQ-q2qAhG742mTm6QpgLZ3yiaug027hc,2018
15
- sigal/plugins/extended_caching.py,sha256=App3xncutlJByzRrX3zLrdF_xuDm9_cnA-SNvy-QhQ8,6035
16
- sigal/plugins/feeds.py,sha256=llWGt2iZxIsYfT8t5FMGZso-zk1dGg98k6brl0-zU1w,2863
17
- sigal/plugins/media_page.py,sha256=nmHu_Vh5Hinw1kHLUXC5zje75OpAew6WplWrqm2DbsE,3201
18
- sigal/plugins/nomedia.py,sha256=Jz1ewBcG40cE5lCpG-XeaGkrnHH_ognA3E8Qs9lRS90,4962
19
- sigal/plugins/nonmedia_files.py,sha256=Oc9rMTciEy9diHy5aLvvTPePoAspvOWLjy5LhlAQYCs,6462
20
- sigal/plugins/upload_s3.py,sha256=UyJYlNgDFce6ZEv8sq0_OlN8-_mp931NToe8o9oxaSo,3747
21
- sigal/plugins/watermark.py,sha256=1MOaADQIx7MQnu8WuYAGp4x-72_KHcx67uWfqkEku6g,3728
22
- sigal/plugins/zip_gallery.py,sha256=u1aMOTkY06emja0cf5jGh0-ynAiqslgiOJvP6MfvLeE,4340
13
+ sigal/plugins/adjust.py,sha256=CeWNWL4X2JkONSAVxKAYHuhfWwGICvhtVYqWIGNX2M0,761
14
+ sigal/plugins/compress_assets.py,sha256=PYMUa3w0euoBIfNlVaryzSlmRfpmNCBn58DO4LX163o,5443
15
+ sigal/plugins/copyright.py,sha256=TKzdFYBbBoAqGsPuVjjprXF6qIChUu6Tdi5P6v9dP28,2018
16
+ sigal/plugins/extended_caching.py,sha256=h3Z9h24wUMRcEoJ3-xTiiCwyodmjdHv-t8bLf9DialQ,6232
17
+ sigal/plugins/feeds.py,sha256=dl-c-OLS8DPGLVP-agaQ3WxFdmw4iLchfs8DsAd0rPI,2821
18
+ sigal/plugins/media_page.py,sha256=oe1lAlnze-VxVxlXHc3urcLNyIq5jvveElsh5JC5-Ls,3201
19
+ sigal/plugins/nomedia.py,sha256=ggZdkvRfFHwgv5u2-okWXdSHVq2oqQCRdtVIhj88wFM,4961
20
+ sigal/plugins/nonmedia_files.py,sha256=S7VCEvgSrKBnCJpJOf6Vzakv04UCZjkrJUyeo3EoRiI,5024
21
+ sigal/plugins/titleregexp.py,sha256=JbiPnlOQ6xB8M5cABuoCCMmWtxe6AvKh9nmcvZmEoH0,3737
22
+ sigal/plugins/watermark.py,sha256=EstbcrAwCtV9Iy1V9odUFK6qmUKL4wNVo_1QM5ONwdA,3739
23
+ sigal/plugins/zip_gallery.py,sha256=2BOAqXiMoWNrgW4LvGRwyIpH-GeGCUFXvGiruPDMR9Y,4651
23
24
  sigal/plugins/encrypt/__init__.py,sha256=gdL3hlNvFXbgkTK20KLdtDLrLVgAztOQT-iBJao18C0,1686
24
- sigal/plugins/encrypt/encrypt.py,sha256=wIZXd8xrIsoFdyv1Vte5hZaXj9kPRyahBtLF-bfbYmg,9390
25
- sigal/plugins/encrypt/endec.py,sha256=rO9H1wya-p2MM83kgsyjg8A69h_W46zMP07qKTHCJo4,4642
25
+ sigal/plugins/encrypt/encrypt.py,sha256=u0Px1m4avvY1xw0wpWeKm7tgO6ssMo3uIUQ5LOjhl5k,9399
26
+ sigal/plugins/encrypt/endec.py,sha256=2hRtSW1qCir233dM1RVqx2HD9LovI6N1-fEZVz0pxJQ,4638
26
27
  sigal/plugins/encrypt/static/decrypt.js,sha256=uJguVOcI17Rdw4OG64z616FsiG4aQ83HC7dhG7hTR6Y,23093
27
28
  sigal/plugins/encrypt/static/keycheck.txt,sha256=vD5A3zcFwQDQC8hpkuDS19vLDUd-QjdQXz_HDFJ1GXE,85
28
29
  sigal/plugins/encrypt/static/sw.js,sha256=oqjx7dvUOE0RPTobNW2SJt8MZMDHypi-u2EGIVSW374,252
29
- sigal/templates/sigal.conf.py,sha256=Lrvp6DSs0O7H1d55LvOZ7TMnhumFx0O1sAKU0Q44AHA,10855
30
+ sigal/templates/sigal.conf.py,sha256=E4GXY_4WedpSFAMWvSfWmBQGLVh54Yzy7AYs_sIn10Q,11148
30
31
  sigal/themes/colorbox/static/css/colorbox.css,sha256=sYXRMxCzzFJ_vYGFAWjUHwYb9tVbcErh5-P-NRvY3dU,3020
31
32
  sigal/themes/colorbox/static/css/skeleton.css,sha256=ECB9bbROLGm8wOoEbHcHRxlHgzGqYpDtNTgDTyDz0wg,11452
32
33
  sigal/themes/colorbox/static/css/style.css,sha256=XEV-fI68HLXzECvlNdaP9_RMzKPfnXFm6TyUOV3gcfo,1424
@@ -66,10 +67,11 @@ sigal/themes/default/static/leaflet/images/marker-icon.png,sha256=V0w6XMqF9BFAhb
66
67
  sigal/themes/default/static/leaflet/images/marker-shadow.png,sha256=Jk9cZAM58ELdcpBiz8BMF_jqDymIK1OOOEjtjxDttNo,618
67
68
  sigal/themes/default/templates/analytics.html,sha256=SR8pUjLmGpyv5ecFX0mpjNsk6FtRGMBFsuZ05eLBCJw,503
68
69
  sigal/themes/default/templates/breadcrumb.html,sha256=VM77dqfk4HZxIrxKf00Bf_3FNCk5XSHAKaIFoBitHpM,241
69
- sigal/themes/default/templates/decrypt.html,sha256=qri7-fgJcuLGgkmdsUFiAOir4LrrAjVesC2vYJko_tw,3508
70
+ sigal/themes/default/templates/decrypt.html,sha256=OBdmGTSaM7OKiL2geMeAUBVMJq6cAkz6Wfr6pw4QcTM,3531
70
71
  sigal/themes/default/templates/default_head.html,sha256=EExAZabgtIOVqOep2uy4dwPS1Dgn79vb7cZPc8DnHPU,711
72
+ sigal/themes/default/templates/description.html,sha256=U3NC_7AmgYk1Tq9xTscTnXNiXTDAUoYYrJOW23dy9s0,1497
71
73
  sigal/themes/default/templates/download_zip.html,sha256=fxGj6cRrqwQqfvLZ_gU4__Vvl9QgxncdAs6Ab32R3Jw,490
72
- sigal/themes/default/templates/footer.html,sha256=DLa20QsTaiOzwlbVuG11t6X6e8LyYur7Us7a-f0Z91U,512
74
+ sigal/themes/default/templates/footer.html,sha256=ggx_2EhqUpFkiCFV2Bwn742VxavcBolx0pCX92ifLg8,604
73
75
  sigal/themes/default/templates/gtm.html,sha256=392ZH-5jPZXMHDTQcDL10YGaKj2sM9cxkFH0IayY7gk,657
74
76
  sigal/themes/default/templates/links.html,sha256=MFSCeCtJTESoJAPI4hiEm-pwG3bJJ09XGV8v0HAQOmw,185
75
77
  sigal/themes/default/templates/map.html,sha256=7cQBkBsteLVIrAWuYZNFdQfdzniZY03oijA5lPBnoNM,1087
@@ -111,31 +113,29 @@ sigal/themes/galleria/static/themes/twelve/galleria.twelve.js,sha256=cEH3RivOPny
111
113
  sigal/themes/galleria/static/themes/twelve/galleria.twelve.min.css,sha256=BJ0sIDeTVuHynQmREmKcZoRDNLaxgh1zElt6_14E0VI,48127
112
114
  sigal/themes/galleria/static/themes/twelve/galleria.twelve.min.js,sha256=h5FDcg3UFnAMAMrel0li0XcPPYnPfoWZwX5P_Wzhpz0,4256
113
115
  sigal/themes/galleria/templates/album.html,sha256=qqEcZL-aaRjBznixrGSZcIC3Ene41LsaSf8i7QXdrD0,478
114
- sigal/themes/galleria/templates/album_items.html,sha256=D3cN7y3uf8gJbG7WTR7x1GRji4y3RoOBtgvJM9sCMLA,4019
116
+ sigal/themes/galleria/templates/album_items.html,sha256=Mx-HqEg9e_mfE06HbNpBEh5FFjFhwmfyoVzxKuEH70w,2580
115
117
  sigal/themes/galleria/templates/album_list.html,sha256=I3GkHil8wNa0K70kbS0Qnns5iGlvaZqwwtYLNKPZIwo,749
116
118
  sigal/themes/galleria/templates/base.html,sha256=FE7kBmWSR0wCQJBnHUYJ3ONGLA1Auo00jMYXMUVTxvE,1462
117
- sigal/themes/photoswipe/static/app.js,sha256=86G6TBHDpeKno-6ZirGJsZLtC3qf_YvdJnjnbadises,5655
118
- sigal/themes/photoswipe/static/photoswipe-ui-default.js,sha256=4Jz1EuME9M9pYTgvkaFE-TJ8BMyEk_jwBQknPjkyR_I,23731
119
- sigal/themes/photoswipe/static/photoswipe-ui-default.min.js,sha256=31SqlpZuZG1WK_TE-Vbmo_zpveXl5RbYYSeUl3gOfxg,10409
120
- sigal/themes/photoswipe/static/photoswipe.css,sha256=6ThO9JgMKOpGiuzw4i8y2foGXoMwkrNJF1yH3vTANh8,4080
121
- sigal/themes/photoswipe/static/photoswipe.css.map,sha256=mZ17iZ71fHKmcui2wgL5rdlkIIkiotZa6JMlfyBsnqM,3208
122
- sigal/themes/photoswipe/static/photoswipe.js,sha256=AqsNq0cfbAUIKL9TUoXWYoXJs57J38Q8z19_SawFUGw,96448
123
- sigal/themes/photoswipe/static/photoswipe.min.js,sha256=mkNLawnmMCuFWFDyQORtznUM7ep4sfy2v1M5s5hAa-g,32459
124
- sigal/themes/photoswipe/static/styles.css,sha256=F_SotLfkjbVcHJhBtyu1qM_I8Mt4vrdsdRjbR3Shyv4,3325
125
- sigal/themes/photoswipe/static/default-skin/default-skin.css,sha256=kfutkGpWaB5a5R4UCyZX07tl1CfyOegD9bxt2GNCcFE,11733
126
- sigal/themes/photoswipe/static/default-skin/default-skin.css.map,sha256=njh4Z0oTx3DkEMuLvr7Zoeg2B9O-MleRLisOXdRJTGA,8572
127
- sigal/themes/photoswipe/static/default-skin/default-skin.png,sha256=mIh_w5EQ1yETyYDl2PSEWnxmrCic-enxYNIEtc4tkys,794
128
- sigal/themes/photoswipe/static/default-skin/default-skin.svg,sha256=Qy51lMGsSJOXqTtAwi1mJo3lsbDdqW4x8LL4Z6KTNqM,2186
129
- sigal/themes/photoswipe/static/default-skin/preloader.gif,sha256=gNftPz9LUGKPIZd424FJVefSAHwFvohVZ3j5DuKQcVw,866
130
- sigal/themes/photoswipe/static/echo/blank.gif,sha256=7xlVrnV8i5ZsgySDUDMb06MPZYztEfOH-OvwWrM2hik,42
131
- sigal/themes/photoswipe/static/echo/echo.js,sha256=Za2KFH4V2CgbRyLNYPbT6R-NBPmRZn71OlZ2w2H-cOo,3776
132
- sigal/themes/photoswipe/static/echo/echo.min.js,sha256=5H1WCijld7K1hIz_V63eUiviDe7W5QmzWPW7EFXKujI,1915
133
- sigal/themes/photoswipe/templates/album.html,sha256=0z1468KOJp5z28mSGRcqB7vTtCo7y330EXf7Kkxmpa8,4672
119
+ sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.js,sha256=F6istdJw3AAK8N1lZ8IkfMO3m7DhjDGomHzdof2Vlrk,12651
120
+ sigal/themes/photoswipe/static/photoswipe-dynamic-caption-plugin.esm.min.js,sha256=ykzAYtehY7GEK8E965Yo215DCvfJ0J8JIUKRM2Hlykw,6772
121
+ sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.js,sha256=M3CpyZgsM24IkwM_4sfXExjmj8nrZwDBZKSlVrn7cUc,4684
122
+ sigal/themes/photoswipe/static/photoswipe-fullscreen.esm.min.js,sha256=xL1L_qHwICaCsqKyBLz1raOwi5me7CIcpn5ibijn07A,2701
123
+ sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js,sha256=DcCTKV8r_xFyIQglH9s-A5tgx4K_PKptzdY2sESe1t8,54556
124
+ sigal/themes/photoswipe/static/photoswipe-lightbox.esm.js.map,sha256=DMwIo61CgRYoBAcHL9nyI0InrTDNKaNQsQcc1Exbt6w,109478
125
+ sigal/themes/photoswipe/static/photoswipe-lightbox.esm.min.js,sha256=uCw4VgT5DMdwgtjhvU9e98nT2mLZXcw_8WkaTrDd3RI,14338
126
+ sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.js,sha256=UATlOn-Jz2bscl8d-JxrrHfi9HsQzwxcgR07jhX6xWw,7203
127
+ sigal/themes/photoswipe/static/photoswipe-video-plugin.esm.min.js,sha256=Ii-ZW2cjRwRtEIlEiWKgKmXt_8QmL9pPUIanNbHieRk,3446
128
+ sigal/themes/photoswipe/static/photoswipe.css,sha256=u16VaBKoE-G9W-XXZBzHjQXX59P3qxAYe8JyXXC1LJQ,7003
129
+ sigal/themes/photoswipe/static/photoswipe.esm.js,sha256=23YN69O4wN_-5QPeKjYeRfCp9-s8dqlz47vaVBErhBc,187718
130
+ sigal/themes/photoswipe/static/photoswipe.esm.js.map,sha256=kEmuw6JFgJmMY0ACMSSu1NuN0hO4_ZqKeTxjqDWVo2Q,379188
131
+ sigal/themes/photoswipe/static/photoswipe.esm.min.js,sha256=VCBpdxvrNNxGHNuTdNqK9kPFkev2XY7DYzHdmgaB69Q,54270
132
+ sigal/themes/photoswipe/static/styles.css,sha256=pr8tKKTPzUfquQNXXn4FvBlZFVemiY4gRU86Y1FeIpM,4211
133
+ sigal/themes/photoswipe/templates/album.html,sha256=3Q5aDVjHgDBZr7uIAg2iDvsUukAe-AbFxlegJcBG3ZU,3301
134
134
  sigal/themes/photoswipe/templates/album_list.html,sha256=lZh2TLFqKOSfWaqAaZyutCxPzxTcogRbibyc6-2YsgU,403
135
135
  sigal/themes/photoswipe/templates/base.html,sha256=S-lhAJfUkXJ9E6Q0FAzrbnv1kM1rW0PpAxKARDR1s8c,1284
136
- sigal-2.3.dist-info/LICENSE,sha256=dhXw6nG46OtW6x5ScKm9DRMIVJNFklvCT-_mRiJAEOc,1086
137
- sigal-2.3.dist-info/METADATA,sha256=tMq5EI-kXjGhCLh70ndPLMDdlkqDsYNIB9ZKTpeONBU,3482
138
- sigal-2.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
139
- sigal-2.3.dist-info/entry_points.txt,sha256=0d6G4mfwngP5--aFVxGpdUujO53smlmD-jygNSDCQ8o,37
140
- sigal-2.3.dist-info/top_level.txt,sha256=z6e1_OpCyg5rzqDmiAat3ytylvaz0K5F7VDdrbF8fQc,6
141
- sigal-2.3.dist-info/RECORD,,
136
+ sigal-2.5.dist-info/LICENSE,sha256=VFPg0QyH2MjVAWTOJrYce-Q6DJydrasigpGut33O7cY,1086
137
+ sigal-2.5.dist-info/METADATA,sha256=NpHfYREuF1l3eU1ANeuGMQ0sDn0OGaAVG_c8QWxWuos,3273
138
+ sigal-2.5.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
139
+ sigal-2.5.dist-info/entry_points.txt,sha256=9MBYGKDTQgjtKk7ebYjjdtXGI50AAaJ8q1TG9HsE2QM,46
140
+ sigal-2.5.dist-info/top_level.txt,sha256=z6e1_OpCyg5rzqDmiAat3ytylvaz0K5F7VDdrbF8fQc,6
141
+ sigal-2.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.37.1)
2
+ Generator: setuptools (75.8.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sigal = sigal.__main__:main
@@ -1,106 +0,0 @@
1
- """Plugin to upload generated files to Amazon S3.
2
-
3
- This plugin requires boto_. All generated files are uploaded to a specified S3
4
- bucket. When using this plugin you have to make sure that the bucket already
5
- exists and the you have access to the S3 bucket. The access credentials are
6
- managed by boto_ and can be given as environment variables, configuration files
7
- etc. More information can be found on the boto_ documentation.
8
-
9
- .. _boto: https://pypi.org/project/boto/
10
-
11
- Settings (all settings are wrapped in ``upload_s3_options`` dict):
12
-
13
- - ``bucket``: The to-be-used bucket for uploading.
14
- - ``policy``: Specifying access control to the uploaded files. Possible values:
15
- private, public-read, public-read-write, authenticated-read
16
- - ``overwrite``: Boolean indicating if all files should be uploaded and
17
- overwritten or if already uploaded files should be skipped.
18
- - ``max_age``: Optional, Integer indicating the number of seconds that the
19
- cache control should be set by default
20
- - ``media_max_age``: Optional, Integer indicates the number of seconds that
21
- cache control hould be set for media files
22
-
23
- """
24
-
25
- import logging
26
- import os
27
-
28
- from click import progressbar
29
-
30
- from sigal import signals
31
-
32
- logger = logging.getLogger(__name__)
33
-
34
-
35
- def upload_s3(gallery, settings=None):
36
- import boto
37
-
38
- upload_files = []
39
-
40
- # Get local files
41
- for root, dirs, files in os.walk(gallery.settings["destination"]):
42
- for f in files:
43
- path = os.path.join(root[len(gallery.settings["destination"]) + 1 :], f)
44
- size = os.path.getsize(os.path.join(root, f))
45
- upload_files += [(path, size)]
46
-
47
- # Connect to specified bucket
48
- conn = boto.connect_s3()
49
- bucket = conn.get_bucket(gallery.settings["upload_s3_options"]["bucket"])
50
-
51
- # Upload the files
52
- with progressbar(upload_files, label="Uploading files to S3") as bar:
53
- for (f, size) in bar:
54
- if gallery.settings["upload_s3_options"]["overwrite"] is False:
55
- # Check if file was uploaded before
56
- key = bucket.get_key(f)
57
- if key is not None and key.size == size:
58
- cache_metadata = generate_cache_metadata(gallery, f)
59
-
60
- if key.get_metadata("Cache-Control") != cache_metadata:
61
- key.set_remote_metadata(
62
- {"Cache-Control": cache_metadata}, {}, True
63
- )
64
- logger.debug("Skipping file %s", f)
65
- else:
66
- upload_file(gallery, bucket, f)
67
- else:
68
- # File is not available on S3 yet
69
- upload_file(gallery, bucket, f)
70
-
71
-
72
- def generate_cache_metadata(gallery, f):
73
- filename, ext = os.path.splitext(f)
74
- options = gallery.settings["upload_s3_options"]
75
-
76
- proposed_cache_control = None
77
- if "media_max_age" in options and ext in [".jpg", ".png", ".webm", ".mp4"]:
78
- proposed_cache_control = "max-age=%s" % options["media_max_age"]
79
- elif "max_age" in options:
80
- proposed_cache_control = "max-age=%s" % options["max_age"]
81
- return proposed_cache_control
82
-
83
-
84
- def upload_file(gallery, bucket, f):
85
- logger.debug("Uploading file %s", f)
86
-
87
- from boto.s3.key import Key
88
-
89
- key = Key(bucket)
90
- key.key = f
91
-
92
- cache_metadata = generate_cache_metadata(gallery, f)
93
- if cache_metadata:
94
- key.set_metadata("Cache-Control", cache_metadata)
95
-
96
- key.set_contents_from_filename(
97
- os.path.join(gallery.settings["destination"], f),
98
- policy=gallery.settings["upload_s3_options"]["policy"],
99
- )
100
-
101
-
102
- def register(settings):
103
- if settings.get("upload_s3_options"):
104
- signals.gallery_build.connect(upload_s3)
105
- else:
106
- logger.warning("Upload to S3 is not configured.")