Build the immich description block and tags from a sidecar
Immich has no copyright or source fields, so the photographer, licence, flickr page and every wiki page using the photo go into a marked block in the description. The marker lets a later run find and replace only that block, leaving anything written by hand alone. Tags mirror licence and photographer for filtering. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+259
No files matched your search
@@ -601,3 +601,138 @@ class Sidecars(TestCase):
|
||||
|
||||
def test_utcnow_shape(self):
|
||||
self.assertRegex(rb.utcnow(), r"^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$")
|
||||
|
||||
|
||||
class Licences(TestCase):
|
||||
def test_label_from_url(self):
|
||||
self.assertEqual(rb.licencelabel("https://creativecommons.org/licenses/by-nc-sa/2.0/deed.en_GB"), "CC BY-NC-SA 2.0")
|
||||
self.assertEqual(rb.licencelabel("https://creativecommons.org/licenses/by/2.0/"), "CC BY 2.0")
|
||||
self.assertEqual(rb.licencelabel("http://creativecommons.org/publicdomain/zero/1.0/"), "CC0 1.0")
|
||||
self.assertIsNone(rb.licencelabel(""))
|
||||
self.assertIsNone(rb.licencelabel("https://example.com/terms"))
|
||||
|
||||
def test_slug(self):
|
||||
self.assertEqual(rb.licenceslug("CC BY-NC-SA 2.0"), "cc-by-nc-sa-2.0")
|
||||
self.assertEqual(rb.licenceslug("All rights reserved"), "all-rights-reserved")
|
||||
|
||||
def test_rgl_licence_wins(self):
|
||||
side = sidecar()
|
||||
self.assertEqual(rb.licencefor(side),
|
||||
("CC BY-SA 2.0", "https://creativecommons.org/licenses/by-sa/2.0/", "rgl"))
|
||||
|
||||
def test_flickr_fills_a_gap(self):
|
||||
side = sidecar(licence="")
|
||||
label, url, origin = rb.licencefor(side)
|
||||
self.assertEqual((label, origin), ("CC BY-SA 2.0", "flickr"))
|
||||
self.assertIn("by-sa/2.0", url)
|
||||
|
||||
def test_a_licence_url_we_cannot_name_beats_flickr(self):
|
||||
side = sidecar(licence="https://example.com/our-own-terms")
|
||||
self.assertEqual(rb.licencefor(side),
|
||||
(None, "https://example.com/our-own-terms", "wiki"))
|
||||
self.assertIn("Licence: https://example.com/our-own-terms (from the wiki)",
|
||||
rb.describeblock(side))
|
||||
self.assertNotIn("from Flickr", rb.describeblock(side))
|
||||
self.assertIn("rgl/licence/unknown", rb.tagsfor(side))
|
||||
|
||||
def test_unknown_when_neither(self):
|
||||
side = sidecar(licence="")
|
||||
side["flickr"]["licence_id"] = None
|
||||
self.assertEqual(rb.licencefor(side), (None, None, None))
|
||||
|
||||
def test_flickr_table_covers_published_ids(self):
|
||||
self.assertEqual(rb.FLICKR_LICENCES[0][0], "All rights reserved")
|
||||
self.assertEqual(rb.FLICKR_LICENCES[4][0], "CC BY 2.0")
|
||||
self.assertEqual(rb.FLICKR_LICENCES[9][0], "CC0 1.0")
|
||||
self.assertEqual(rb.FLICKR_LICENCES[10][0], "Public Domain Mark 1.0")
|
||||
|
||||
|
||||
class Describing(TestCase):
|
||||
def test_block_shape(self):
|
||||
block = rb.describeblock(sidecar())
|
||||
self.assertEqual(block.splitlines(), [
|
||||
rb.MARKER,
|
||||
"Photo: A title",
|
||||
"Source: https://www.flickr.com/photos/12345678@N00/111/",
|
||||
"Photographer: P",
|
||||
"Licence: CC BY-SA 2.0 https://creativecommons.org/licenses/by-sa/2.0/",
|
||||
"Used on:",
|
||||
" A, E1 https://london.randomness.org.uk/wiki.cgi?A%2C_E1",
|
||||
])
|
||||
|
||||
def test_photographer_falls_back_to_flickr(self):
|
||||
side = sidecar(copyright="")
|
||||
self.assertEqual(rb.photographer(side), "Real Name")
|
||||
side["flickr"]["owner_realname"] = ""
|
||||
self.assertEqual(rb.photographer(side), "handle")
|
||||
|
||||
def test_licence_from_flickr_is_marked_and_disagreement_noted(self):
|
||||
side = sidecar(licence="")
|
||||
self.assertIn("Licence: CC BY-SA 2.0 https://creativecommons.org/licenses/by-sa/2.0/ (from Flickr)",
|
||||
rb.describeblock(side))
|
||||
side = sidecar(licence="https://creativecommons.org/licenses/by-nc-sa/2.0/")
|
||||
block = rb.describeblock(side)
|
||||
self.assertIn("Licence: CC BY-NC-SA 2.0 https://creativecommons.org/licenses/by-nc-sa/2.0/", block)
|
||||
self.assertIn("Note: Flickr lists this photo as CC BY-SA 2.0", block)
|
||||
|
||||
def test_no_licence_says_unknown(self):
|
||||
side = sidecar(licence="")
|
||||
side["flickr"]["licence_id"] = None
|
||||
self.assertIn("Licence: unknown", rb.describeblock(side))
|
||||
|
||||
def test_non_flickr_photo(self):
|
||||
side = sidecar(flickr=False)
|
||||
block = rb.describeblock(side)
|
||||
self.assertNotIn("Photo:", block)
|
||||
self.assertIn("Source: https://www.geograph.org.uk/photos/1.jpg", block)
|
||||
|
||||
def test_several_pages(self):
|
||||
side = sidecar(nodes=[
|
||||
{"param": "A", "name": "A", "url": "https://x/A", "lat": "", "long": ""},
|
||||
{"param": "B", "name": "B", "url": "https://x/B", "lat": "", "long": ""}])
|
||||
self.assertTrue(rb.describeblock(side).endswith("Used on:\n A https://x/A\n B https://x/B"))
|
||||
|
||||
|
||||
class Merging(TestCase):
|
||||
block = "%s\nPhoto: x\nUsed on:\n A https://x/A" % rb.MARKER
|
||||
|
||||
def test_empty_or_boilerplate_is_written(self):
|
||||
self.assertEqual(rb.mergedescription("", self.block), (self.block, "write"))
|
||||
self.assertEqual(rb.mergedescription("OLYMPUS DIGITAL CAMERA", self.block), (self.block, "write"))
|
||||
|
||||
def test_existing_text_is_kept_above(self):
|
||||
text, action = rb.mergedescription("My caption", self.block)
|
||||
self.assertEqual(action, "append")
|
||||
self.assertEqual(text, "My caption\n\n" + self.block)
|
||||
|
||||
def test_same_block_is_quiet(self):
|
||||
held = "My caption\n\n" + self.block
|
||||
self.assertEqual(rb.mergedescription(held, self.block), (held, "same"))
|
||||
|
||||
def test_changed_block_is_replaced_in_place(self):
|
||||
held = "My caption\n\n" + self.block + "\n\nTrailing note"
|
||||
newblock = self.block + "\n B https://x/B"
|
||||
text, action = rb.mergedescription(held, newblock)
|
||||
self.assertEqual(action, "replace")
|
||||
self.assertEqual(text, "My caption\n\n" + newblock + "\n\nTrailing note")
|
||||
|
||||
def test_isboilerplate(self):
|
||||
self.assertTrue(rb.isboilerplate("SONY DSC"))
|
||||
self.assertFalse(rb.isboilerplate("The 100 Club"))
|
||||
|
||||
|
||||
class Tags(TestCase):
|
||||
def test_tags(self):
|
||||
self.assertEqual(rb.tagsfor(sidecar()),
|
||||
["rgl", "rgl/licence/cc-by-sa-2.0", "rgl/photographer/P"])
|
||||
|
||||
def test_unknown_licence_and_blank_photographer(self):
|
||||
side = sidecar(licence="", copyright="")
|
||||
side["flickr"]["licence_id"] = None
|
||||
side["flickr"]["owner_realname"] = ""
|
||||
side["flickr"]["owner_name"] = ""
|
||||
self.assertEqual(rb.tagsfor(side), ["rgl", "rgl/licence/unknown"])
|
||||
|
||||
def test_photographer_whitespace_and_slashes(self):
|
||||
side = sidecar(copyright=" Some / One ")
|
||||
self.assertIn("rgl/photographer/Some - One", rb.tagsfor(side))
|
||||
Reference in new issue
Block a user