Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to output albums as branches #31

Open
wants to merge 51 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8f62499
Add option to output albums as branches
sebastiaan-lampo Feb 15, 2021
be88345
Add option to output albums as branches
sebastiaan-lampo Feb 15, 2021
128c2d4
Merge branch 'album_as_branch'
sebastiaan-lampo Feb 17, 2021
2acb76e
Implement minimal EXIF and IPTC tag support
sebastiaan-lampo Feb 17, 2021
5019c90
Make settings robust for missing parameters
sebastiaan-lampo Feb 17, 2021
16cf5b9
Clean imports, requirements and logging
sebastiaan-lampo Feb 19, 2021
f917a76
Merge branch 'photo_exif'
sebastiaan-lampo Feb 19, 2021
78dd59e
Improve Quality of Life
sebastiaan-lampo Feb 19, 2021
c861407
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
7664f8a
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
6526b1a
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
dbd90f3
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
2dd1d36
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
738d86a
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
3e04f9d
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
b9040b5
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
a4cec17
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
bab9e3d
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
5812f58
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 19, 2021
330132d
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 21, 2021
5fe653d
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 21, 2021
8a6d59f
Add exif and iptc to photo.md output
sebastiaan-lampo Feb 21, 2021
0603d61
Remove mandatory validation of valid image. Album.update() relies on
sebastiaan-lampo Mar 7, 2021
7003fc1
Remove mandatory validation of valid image. Album.update() relies on
sebastiaan-lampo Mar 7, 2021
b409c88
Fix bug in nested album file creation.
sebastiaan-lampo Mar 7, 2021
10a0255
Resolve bugs and complexities.
sebastiaan-lampo Mar 7, 2021
b520289
Merge branch 'auto_add_albums'
sebastiaan-lampo Mar 8, 2021
8518352
Escape shortcode output so we can handle " in the text
sebastiaan-lampo Mar 8, 2021
5db31d7
Encapsulate Image.open in with block in original_image to reduce
sebastiaan-lampo Mar 8, 2021
823b530
Merge branch 'auto_add_albums'
sebastiaan-lampo Mar 8, 2021
e393a61
Implement minimal EXIF and IPTC tag support
sebastiaan-lampo Feb 17, 2021
fc6b8e6
Merge upstream progress
sebastiaan-lampo Jun 13, 2022
472b25b
Merge pull request #9 from GjjvdBurg/master
sebastiaan-lampo Jun 13, 2022
3febea5
Implement minimal EXIF and IPTC tag support
sebastiaan-lampo Feb 17, 2021
d3698cf
Clarify exif|iptc tag format
sebastiaan-lampo Jun 19, 2022
25f5ce0
Simplify behaviour when exif orientation is not defined
sebastiaan-lampo Jun 19, 2022
06f44fd
Load iptc data like exif at the same stage
sebastiaan-lampo Jun 19, 2022
d3511e1
Use pythonic list comprehension for _load_iptc
sebastiaan-lampo Jun 19, 2022
98a2313
Improve error handling for improper tags
sebastiaan-lampo Jun 19, 2022
f4f2b42
Remove get_attribute overloader
sebastiaan-lampo Jun 19, 2022
f8059a7
Increase log level for iptcinfo to ERROR
sebastiaan-lampo Jun 19, 2022
366a6d8
Merge branch 'photo_exif'
sebastiaan-lampo Jun 19, 2022
b9f9ec4
Add option to output albums as branches
sebastiaan-lampo Feb 15, 2021
f21963b
Add unit tests for branch bundles
sebastiaan-lampo Jun 20, 2022
98309e6
Make cleanup question more flexible
sebastiaan-lampo Jun 20, 2022
fbeea57
Align branch_bundle output with default output
sebastiaan-lampo Jun 20, 2022
5c68156
Update unit tests for extra configuration option
sebastiaan-lampo Jun 20, 2022
a6d8b21
PEP8 compliance
sebastiaan-lampo Jun 20, 2022
6bcad51
Fix bug in image rotation code
sebastiaan-lampo Jun 20, 2022
30ce4c2
Merge branch 'photo_exif'
sebastiaan-lampo Jun 20, 2022
098bb6f
Fix error when markdown directory already exists
sebastiaan-lampo Jun 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 74 additions & 0 deletions docs/README.md
Expand Up @@ -24,6 +24,10 @@ The following options are available in the ``hugophotoswipe.yml`` file:
| jpeg_progressive | False | Output progressive JPEGs |
| jpeg_optimize | False | Optimize JPEG output |
| jpeg_quality | 75 | JPEG quality factor |
| tag_map | None | Dictionary map of exif/iptc tags to photo properties |
| exif | None | List of tags to be included or excluded |
| iptc | None | List of tags to be included or excluded |
| generate_branch_bundle | False | [Branch bundle](https://gohugo.io/content-management/page-bundles/#branch-bundles) output instead of single album file |

Naturally, the jpeg options are only applied when ``output_format`` is
``jpg``.
Expand All @@ -42,6 +46,70 @@ unchanged. When a single number is given, the *maximum* dimension of the photo
will be reduced to the given number, and the other dimension is chosen
according to the aspect ratio.

EXIF/IPTC Tags
--------------

You can use the metadata embedded in the photos as a starter to fill out captions
and copyright information. HugoPhotoSwipe will use this information when you run
`hps update` in the following manner:
1. Prefer the information already specified in the album file
2. Use the information in the metadata

Using metadata requires a mapping for each field you want to be populated. Currently
only caption and copyright are supported. In the configuration file, add the `tag_map`
setting as follows:

```yaml
tag_map:
caption: exif.ImageDescription
copyright: exif.Artist
```

Caption will be saved to the album yaml file with the photo information. You can then
edit it there if you wish. Because the album file is given priority, your changes will
not be overridden, even after an update. Copyright is not yet used as this is currently
an album-level property.

The format of the option is: `<property_name>: iptc.<tag_name>` or `<property_name>:exif.<tag_name>`
(for example: `copyright: exif.Artist`). Tag may include spaces. A full list of tags can be found here:
* [IPTC tags](https://github.com/jamesacampbell/iptcinfo3/blob/a9cea6cb1981e4ad29cf317d44419e4fd45c2170/iptcinfo3.py#L445)
* [EXIF tags](https://github.com/python-pillow/Pillow/blob/master/src/PIL/ExifTags.py)

The following two configuration file options allow you more granular control over what
metadata HugoPhotoSwipe loads from the file. The intended use is to reduce the number of
tags that are saved. If you want to use a tag in the `tag_map`, it must included or
not be excluded. Specifying `include: []` will result in no data being loaded.
Not specifying either option will result in all tags being loaded.

```yaml
iptc:
include: ['tag1', 'tag2', ...]
exclude: ['tag1', 'tag2', ...]
exif:
include: ['tag1', 'tag2', ...]
exclude: ['tag1', 'tag2', ...]
```

Branch Bundle Output
--------------------

This setting allows for two related goals:
* Create a content page for each photo while maintaining the PhotoSwipe gallery
at album level.
* Provide the basis for extracting additional properties such as EXIF tags
from the photos into front matter. This will allow you to use Hugo's taxonomy
capabilities to build albums based on tags, etc.

The branch bundle output setting is designed for advanced users only. In its
present state, it will require significant rework to ensure the shortcodes
are applied correctly. You will need a `list.html` template that includes the
`{{< wrap >}}` shortcode and iterates over the photos in the bundle. It will
become significantly more useful once HugoPhotoSwipe supports extracting EXIF
tags from the photos.

Note: Enabling this setting will result in default album markdown files *not*
being generated as these would conflict with the branch bundle.

Shortcodes
==========

Expand Down Expand Up @@ -71,6 +139,12 @@ And in ``layouts/shortcodes/wrap.html``::
The ``wrap`` shortcode is needed due to [this
issue](https://github.com/spf13/hugo/issues/1642) in Hugo.

If you enable `generate_branch_bundle`, add ``layouts/_default/list.html``::

{{ range .Pages }}
{{ .Content }}
{{ end }}

PhotoSwipe Javascript
=====================

Expand Down
95 changes: 85 additions & 10 deletions hugophotoswipe/album.py
Expand Up @@ -83,32 +83,39 @@ def output_dir(self):
pth = os.path.realpath(settings.output_dir)
return os.path.join(pth, self.name)

@property
def markdown_dir(self):
return os.path.join(os.path.realpath(settings.markdown_dir), self.name)

################
# #
# User methods #
# #
################

def clean(self, force=False):
"""Clean up the processed images and the markdown file
"""Clean up the processed images and the markdown file(s)

Ask the user for confirmation and only remove if it exists

If ``force = True``, don't ask for confirmation.
"""
output_dir = os.path.join(settings.output_dir, self.name)
have_md = os.path.exists(self.markdown_file)
have_md_dir = os.path.exists(self.markdown_dir)
have_out = os.path.exists(output_dir)
q = "Going to remove: "

q = ["Going to remove: "]
if have_md:
q += self.markdown_file
q.append(f"- (file) Markdown: {self.markdown_file}")
if have_md_dir:
q.append(f"- (dir) Markdown: {self.markdown_dir}")
if have_out:
q += " and " if have_md else ""
q += self.output_dir
q += ". Is this okay?"
if (not have_md) and (not have_out):
q.append(f"- (dir) Output: {self.output_dir}")
q.append("Is this okay?")
if (not have_md) and (not have_md_dir) and (not have_out):
return
if not force and not question_yes_no(q):
if not force and not question_yes_no("\n".join(q)):
return

if have_md:
Expand All @@ -117,11 +124,76 @@ def clean(self, force=False):
% (self.name, self.markdown_file)
)
os.unlink(self.markdown_file)
if have_md_dir:
logging.info(f"[{self.name}] Removing markdown directory: {self.markdown_dir}")
shutil.rmtree(self.markdown_dir)
if have_out:
logging.info(
"[%s] Removing images directory: %s" % (self.name, output_dir)
)
shutil.rmtree(output_dir)
shutil.rmtree(self.output_dir)

def create_markdown_bundle(self):
""" Create a branch bundle of markdown files, one per photo with an _index.md

Output is generated in a sub folder with the *album_name*. Each photo markdown file
will have the photo properties in front matter and the shortcode in content.
"""
album_md_template = ('+++',
'title = "{title}"',
'date = "{date}"',
'{album_properties}',
'cover = "{cover}"',
'+++',
)
album_md_template = '\n'.join(album_md_template)
photo_md_template = ('+++',
'{exif}',
'{photo_properties}',
'+++',
'',
'{shortcode}'
)
photo_md_template = '\n'.join(photo_md_template)

# Create the header for Hugo
coverpath = ""
if not self.coverimage is None:
coverpath = (
settings.url_prefix
+ self.cover_path[len(settings.output_dir) :]
)
# path should always be unix style for Hugo frontmatter
coverpath = coverpath.replace("\\", "/")

try:
album_properties = "\n".join(["{} = \"{}\"".format(k, v) for k, v in self.properties.items()])
except AttributeError:
album_properties = ""
logging.debug('album_properties text:\n\t'.format(album_properties))

album_dir = os.path.join(os.path.realpath(settings.markdown_dir), self.name)
os.makedirs(album_dir, exist_ok=True)

with open(os.path.join(album_dir, "_index.md"), "w") as f:
logging.debug('Writing album md file to {}'.format(os.path.join(album_dir, "_index.md")))
f.write(album_md_template.format(title=self.title,
cover=coverpath,
date=self.album_date or "",
album_properties=album_properties))
for photo in self.photos:
logging.debug('Writing photo md file to {}'.format(os.path.join(album_dir, photo.clean_name) + ".md"))
with open(os.path.join(album_dir, photo.clean_name) + ".md", "w") as f:
try:
photo_properties = "\n".join([f"{k}: \"{v}\"" for k, v in photo.properties.items()])
except AttributeError:
photo_properties = ""

f.write(photo_md_template.format(
exif="",
shortcode=photo.shortcode,
photo_properties=photo_properties,
))

def create_markdown(self):
""" Create the markdown file, always overwrite existing """
Expand Down Expand Up @@ -342,7 +414,10 @@ def update(self, modification_time=None):

# Overwrite the markdown file
logging.info("[%s] Writing markdown file." % self.name)
self.create_markdown()
if settings.generate_branch_bundle:
self.create_markdown_bundle()
else:
self.create_markdown()

# Overwrite the yaml file of the album
logging.info("[%s] Saving album yaml." % self.name)
Expand Down
4 changes: 4 additions & 0 deletions hugophotoswipe/config.py
Expand Up @@ -53,6 +53,10 @@
"jpeg_quality": 75,
"fast": False,
"verbose": False,
"exif": None,
"iptc": None,
"tag_map": None,
"generate_branch_bundle": False,
}

DONT_DUMP = ["verbose", "fast"]
Expand Down