Merge photo highlights by name and capture year

This commit is contained in:
2026-09-26 19:38:15 +01:00
parent 41c637eca9
commit d15ba78579
47 changed files with 221 additions and 9 deletions
@@ -3,7 +3,9 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017"
date: "2026-01-16T20:02:00.721000+03:30" date: "2026-01-16T20:02:00.721000+03:30"
categories: art categories: art
anchor: "Iran" highlight_name: "Iran"
--- ---
<div id="photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017"></div>
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/00.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/00.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-01" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-01"
date: "2026-01-19T14:54:34.806000+03:30" date: "2026-01-19T14:54:34.806000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/01.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/01.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-02" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-02"
date: "2026-01-21T16:33:29.339000+03:30" date: "2026-01-21T16:33:29.339000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/02.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/02.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-03" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-03"
date: "2026-01-24T14:04:39.306000+03:30" date: "2026-01-24T14:04:39.306000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/03.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/03.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-04" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-04"
date: "2026-01-24T15:18:34.557000+03:30" date: "2026-01-24T15:18:34.557000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/04.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/04.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-05" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-05"
date: "2026-01-28T17:07:06.982000+03:30" date: "2026-01-28T17:07:06.982000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/05.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/05.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-06" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-06"
date: "2026-02-02T08:03:58.683000+03:30" date: "2026-02-02T08:03:58.683000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/06.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/06.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-07" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-07"
date: "2026-02-06T15:56:02.032000+03:30" date: "2026-02-06T15:56:02.032000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/07.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/07.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-08" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-08"
date: "2026-02-06T19:01:35.759000+03:30" date: "2026-02-06T19:01:35.759000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/08.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/08.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-09" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-09"
date: "2026-02-06T19:04:14.947000+03:30" date: "2026-02-06T19:04:14.947000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/09.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/09.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-10" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-10"
date: "2026-02-07T20:49:41.304000+03:30" date: "2026-02-07T20:49:41.304000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/10.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/10.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-11" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-11"
date: "2026-02-14T15:15:35.920000+03:30" date: "2026-02-14T15:15:35.920000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/11.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/11.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-12" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-12"
date: "2026-02-20T14:58:05.265000+03:30" date: "2026-02-20T14:58:05.265000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/12.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/12.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-13" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-13"
date: "2026-02-26T11:56:39.486000+03:30" date: "2026-02-26T11:56:39.486000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/13.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/13.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-01" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-01"
date: "2026-03-06T13:31:34.372000+03:30" date: "2026-03-06T13:31:34.372000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/01.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/01.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-02" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-02"
date: "2026-03-06T14:48:51.818000+03:30" date: "2026-03-06T14:48:51.818000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/02.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/02.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-14" title: "photo-a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017-14"
date: "2026-03-06T15:11:26.932000+03:30" date: "2026-03-06T15:11:26.932000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/14.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017/14.jpg" alt="" loading="lazy"></p>
@@ -3,7 +3,9 @@ layout: post
title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace" title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace"
date: "2026-03-07T11:58:57.224000+04:00" date: "2026-03-07T11:58:57.224000+04:00"
categories: art categories: art
anchor: "Armenia" highlight_name: "Armenia"
--- ---
<div id="photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace"></div>
<p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/00.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/00.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace-01" title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace-01"
date: "2026-03-07T12:34:32.793000+04:00" date: "2026-03-07T12:34:32.793000+04:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/01.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/01.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace-02" title: "photo-bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace-02"
date: "2026-03-07T15:33:07.690000+04:00" date: "2026-03-07T15:33:07.690000+04:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/02.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace/02.jpg" alt="" loading="lazy"></p>
@@ -3,7 +3,9 @@ layout: post
title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278" title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278"
date: "2026-06-26T16:53:49.633000+04:00" date: "2026-06-26T16:53:49.633000+04:00"
categories: art categories: art
anchor: "Armenia" highlight_name: "Armenia"
--- ---
<div id="photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278"></div>
<p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/00.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/00.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-01" title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-01"
date: "2026-06-26T17:15:56.830000+04:00" date: "2026-06-26T17:15:56.830000+04:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/01.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/01.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-02" title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-02"
date: "2026-06-26T17:17:37.263000+04:00" date: "2026-06-26T17:17:37.263000+04:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/02.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/02.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-03" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-03"
date: "2026-08-25T11:29:18.840000+03:30" date: "2026-08-25T11:29:18.840000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/03.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/03.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-04" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-04"
date: "2026-08-28T18:42:14.080000+03:30" date: "2026-08-28T18:42:14.080000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/04.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/04.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-05" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-05"
date: "2026-08-28T21:03:02.299000+03:30" date: "2026-08-28T21:03:02.299000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/05.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/05.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-06" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-06"
date: "2026-08-28T21:35:02.917000+03:30" date: "2026-08-28T21:35:02.917000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/06.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/06.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-07" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-07"
date: "2026-08-30T18:27:21.073000+03:30" date: "2026-08-30T18:27:21.073000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/07.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/07.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-08" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-08"
date: "2026-08-30T18:30:02.249000+03:30" date: "2026-08-30T18:30:02.249000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/08.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/08.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-09" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-09"
date: "2026-09-01T14:21:37.968000+03:30" date: "2026-09-01T14:21:37.968000+03:30"
categories: art categories: art
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/09.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/09.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,8 @@ layout: post
title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-10" title: "photo-0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172-10"
date: "2026-09-19T20:21:02.987000+03:30" date: "2026-09-19T20:21:02.987000+03:30"
categories: art categories: art
anchor: "Iran"
highlight_name: "Iran"
--- ---
<p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/10.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172/10.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c" title: "photo-474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c"
date: "2026-09-19T12:40:18+00:00" date: "2026-09-19T12:40:18+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<div id="photo-474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c"></div> <div id="photo-474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c"></div>
@@ -3,7 +3,8 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d"
date: "2026-09-19T12:40:33+00:00" date: "2026-09-19T12:40:33+00:00"
categories: art categories: art
anchor: "Romania"
--- ---
<div id="photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d"></div>
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/00.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/00.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-04" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-04"
date: "2026-09-19T12:40:19+00:00" date: "2026-09-19T12:40:19+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/04.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/04.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-05" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-05"
date: "2026-09-19T12:40:20+00:00" date: "2026-09-19T12:40:20+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/05.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/05.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-06" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-06"
date: "2026-09-19T12:40:21+00:00" date: "2026-09-19T12:40:21+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/06.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/06.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-07" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-07"
date: "2026-09-19T12:40:22+00:00" date: "2026-09-19T12:40:22+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/07.jpg" alt="Transmission of Flesh by Erfan Ashourioun" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/07.jpg" alt="Transmission of Flesh by Erfan Ashourioun" loading="lazy"></p>
@@ -3,6 +3,7 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-08" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-08"
date: "2026-09-19T12:40:23+00:00" date: "2026-09-19T12:40:23+00:00"
categories: art categories: art
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/08.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/08.jpg" alt="" loading="lazy"></p>
@@ -3,7 +3,9 @@ layout: post
title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-09" title: "photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-09"
date: "2026-09-19T12:40:24+00:00" date: "2026-09-19T12:40:24+00:00"
categories: art categories: art
anchor: "Armenia" highlight_name: "Armenia"
--- ---
<div id="photo-7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d-09"></div>
<p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/09.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d/09.jpg" alt="" loading="lazy"></p>
@@ -3,6 +3,8 @@ layout: post
title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-03" title: "photo-3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278-03"
date: "2026-09-26T18:27:11.763827+00:00" date: "2026-09-26T18:27:11.763827+00:00"
categories: art categories: art
anchor: "Armenia"
highlight_name: "Armenia"
--- ---
<p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/03.jpg" alt="" loading="lazy"></p> <p><img src="/img/arts/uploads/3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278/03.jpg" alt="" loading="lazy"></p>
+5 -2
View File
@@ -179,8 +179,11 @@ photos. When none of these date sources is available, the service uses the uploa
date. Re-sharing the same images, caption, and date. Re-sharing the same images, caption, and
highlight with dates replaces the earlier undated upload. Captions are plain highlight with dates replaces the earlier undated upload. Captions are plain
text and optional. text and optional.
An optional highlight name (up to 200 characters) adds one link to **Highlights**, An optional highlight name (up to 200 characters) adds a link to **Highlights**.
pointing to the first photo in the batch. Leave it blank for an ordinary upload. If that name already exists in the same capture year, publishing merges the new
photos into that highlight and keeps one link at its newest photo. A batch spanning
years gets one link per year. Photo dates and gallery order stay unchanged. Leave
the name blank for an ordinary upload.
Gallery images are progressive JPEGs with a maximum edge of 1600 pixels and a Gallery images are progressive JPEGs with a maximum edge of 1600 pixels and a
300 KiB size limit. The uploader tries moderate JPEG quality levels, then reduces 300 KiB size limit. The uploader tries moderate JPEG quality levels, then reduces
+2
View File
@@ -177,6 +177,8 @@ def photo_entry(job, date, index, caption, highlight):
f'date: "{item_date.isoformat()}"', "categories: art"] f'date: "{item_date.isoformat()}"', "categories: art"]
if index == 0 and highlight: if index == 0 and highlight:
content.append(f"anchor: {json.dumps(highlight)}") content.append(f"anchor: {json.dumps(highlight)}")
if highlight:
content.append(f"highlight_name: {json.dumps(highlight)}")
content.extend(["---", ""]) content.extend(["---", ""])
if index == 0 and not highlight: if index == 0 and not highlight:
content.extend([f'<div id="photo-{job}"></div>', ""]) content.extend([f'<div id="photo-{job}"></div>', ""])
+56
View File
@@ -0,0 +1,56 @@
"""Keep one gallery highlight link per name and capture year."""
from datetime import datetime, timezone
import json
from pathlib import Path
import re
def field(content, name):
match = re.search(rf"^{re.escape(name)}: (.+)$", content.split("---", 2)[1], re.MULTILINE)
if not match:
return None
value = match.group(1).strip()
return json.loads(value) if value.startswith('"') else value
def normalize_highlights(art):
"""Place each link on the newest photo in its named, dated group."""
groups = {}
for path in Path(art).glob("*.md"):
content = path.read_text()
name = field(content, "highlight_name") or field(content, "anchor")
date = field(content, "date")
if not name or not date:
continue
taken = datetime.fromisoformat(str(date))
if taken.tzinfo is None:
taken = taken.replace(tzinfo=timezone.utc)
groups.setdefault((name, taken.year), []).append((taken, path, content))
changed = []
for (name, _), entries in groups.items():
# An old single anchor is already the only link; a newer named photo
# moves the link without changing any photo's capture date or position.
newest = max(entries, key=lambda entry: (entry[0], entry[1].name))[1]
if len(entries) == 1 and field(entries[0][2], "anchor") == name:
continue
for _, path, content in entries:
old = content
had_anchor = field(content, "anchor") is not None
if (path == newest and had_anchor and
all(field(other[2], "anchor") is None for other in entries if other[1] != path)):
continue
if had_anchor:
content = re.sub(r"^anchor: .+\n", "", content, count=1, flags=re.MULTILINE)
if path == newest:
content = content.replace("categories: art\n", "categories: art\n" +
f"anchor: {json.dumps(name, ensure_ascii=False)}\n", 1)
elif had_anchor:
title = field(content, "title")
if title and title.startswith("photo-") and f'id="{title}"' not in content:
content = content.replace("---\n\n", f'---\n\n<div id="{title}"></div>\n\n', 1)
if content != old:
path.write_text(content)
changed.append(path)
return changed
+3
View File
@@ -11,6 +11,7 @@ import sys
import time import time
from app import atomic_json from app import atomic_json
from highlights import normalize_highlights
from posts import publish_post from posts import publish_post
log = logging.getLogger("publisher") log = logging.getLogger("publisher")
@@ -117,6 +118,8 @@ class Publisher:
self.git("add", "--", str(entry)) self.git("add", "--", str(entry))
shutil.copytree(submission / "images", self.repo / images, dirs_exist_ok=True) shutil.copytree(submission / "images", self.repo / images, dirs_exist_ok=True)
self.git("add", "--", str(images)) self.git("add", "--", str(images))
for path in normalize_highlights(self.repo / "_art"):
self.git("add", "--", str(path.relative_to(self.repo)))
if self.git("diff", "--cached", "--name-only"): if self.git("diff", "--cached", "--name-only"):
self.git("commit", "-m", f"Publish {len(jobs)} submission(s)") self.git("commit", "-m", f"Publish {len(jobs)} submission(s)")
self.git("push", "origin", f"HEAD:refs/heads/{self.branch}") self.git("push", "origin", f"HEAD:refs/heads/{self.branch}")
+50
View File
@@ -379,6 +379,56 @@ def test_publisher_names_photo_entry_from_capture_date(publisher, service):
assert f'_art/2025-04-18-photo-{response.json["id"]}-00.md' in paths assert f'_art/2025-04-18-photo-{response.json["id"]}-00.md' in paths
def test_publisher_merges_highlights_by_name_and_capture_year(publisher):
run, remote, client = publisher
first = client.post("/api/photos", headers=AUTH, data={
"photos": [(io.BytesIO(photo("red")), "first.jpg")],
"highlight": "Trip", "photo_dates": "2026-03-01T12:00:00+00:00",
}).json["id"]
assert run().returncode == 0
second = client.post("/api/photos", headers=AUTH, data={
"photos": [(io.BytesIO(photo("blue")), "second.jpg")],
"highlight": "Trip", "photo_dates": "2026-06-01T12:00:00+00:00",
}).json["id"]
assert run().returncode == 0
files = git(remote, "ls-tree", "-r", "--name-only", "master").splitlines()
entries = [git(remote, "show", f"master:{path}") for path in files if path.startswith("_art/")]
assert sum('anchor: "Trip"' in entry for entry in entries) == 1
assert f'anchor: "Trip"' in next(entry for entry in entries if f"photo-{second}" in entry)
assert f'<div id="photo-{first}"></div>' in next(
entry for entry in entries if f'title: "photo-{first}"' in entry)
old_year = client.post("/api/photos", headers=AUTH, data={
"photos": [(io.BytesIO(photo("green")), "old-year.jpg")],
"highlight": "Trip", "photo_dates": "2025-12-31T12:00:00+00:00",
}).json["id"]
assert run().returncode == 0
files = git(remote, "ls-tree", "-r", "--name-only", "master").splitlines()
entries = [git(remote, "show", f"master:{path}") for path in files if path.startswith("_art/")]
assert sum('anchor: "Trip"' in entry for entry in entries) == 2
assert 'anchor: "Trip"' in next(entry for entry in entries if f"photo-{old_year}" in entry)
commit = git(remote, "rev-parse", "master")
assert run().returncode == 0
assert git(remote, "rev-parse", "master") == commit
def test_publisher_splits_a_highlight_across_capture_years(publisher):
run, remote, client = publisher
response = client.post("/api/photos", headers=AUTH, data={
"photos": [(io.BytesIO(photo("red")), "old.jpg"),
(io.BytesIO(photo("blue")), "new.jpg")],
"highlight": "Trip",
"photo_dates": "2025-12-31T12:00:00+00:00\n2026-01-01T12:00:00+00:00",
})
assert response.status_code == 202
result = run()
assert result.returncode == 0, result.stderr
job = response.json["id"]
files = git(remote, "ls-tree", "-r", "--name-only", "master").splitlines()
entries = [git(remote, "show", f"master:{path}") for path in files if f"photo-{job}" in path]
assert len(entries) == 2
assert all('anchor: "Trip"' in entry for entry in entries)
def test_publisher_replaces_an_undated_version_of_the_same_photos(publisher, service): def test_publisher_replaces_an_undated_version_of_the_same_photos(publisher, service):
run, remote, client = publisher run, remote, client = publisher
raw = photo() raw = photo()
+38
View File
@@ -0,0 +1,38 @@
"""One-time migration of existing Iran and Armenia photo groups."""
import json
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "photo-upload"))
from highlights import normalize_highlights
ART = ROOT / "_art"
IRAN = (
"0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172",
"a85137ab7990cb095c8043cf21c034663795194e5510f26a7175edf5a5489017",
)
ARMENIA = (
"bcf8d1409da4d748b2ba060fc090bbe5a518f033f3e971e95f89a8add5c74ace",
"3c708b27ab8e8af18bd3ad8ce25876be653b366551f065f31800d8c640b56278",
"474ab3283ce8801ac6e59b67b65b4169167053873a5a8db4a15b840a3448266c",
)
for path in ART.glob("*photo-*.md"):
if not path.name.startswith("2026-"):
continue
job = path.name.split("-photo-", 1)[1][:64]
name = "Iran" if job in IRAN else "Armenia" if job in ARMENIA else None
if job == "7c832afa1b73023d8f2391ff40c221be9ffd468a1a96a6bf4900cbf95595d31d":
index = int(path.stem[-2:])
name = "Armenia" if index >= 4 else None
if not name:
continue
content = path.read_text()
if "highlight_name:" not in content:
content = content.replace("categories: art\n", "categories: art\n" +
f"highlight_name: {json.dumps(name)}\n", 1)
path.write_text(content)
normalize_highlights(ART)
+16 -2
View File
@@ -83,10 +83,24 @@ class PhotoHighlightTests(unittest.TestCase):
records.sort(reverse=True) records.sort(reverse=True)
grouped = [record for record in records if record[1] in ARMENIA + ROMANIA] grouped = [record for record in records if record[1] in ARMENIA + ROMANIA]
self.assertEqual([record[1] for record in grouped], ROMANIA + ARMENIA) self.assertEqual([record[1] for record in grouped], ROMANIA + ARMENIA)
self.assertEqual(grouped[0][2], "Romania") # Newer uploads now own the one link for each name/year.
self.assertEqual(grouped[9][2], "Armenia") self.assertIsNone(grouped[0][2])
self.assertIsNone(grouped[9][2])
self.assertIn("Transmission of Flesh by Erfan Ashourioun", grouped[11][3]) self.assertIn("Transmission of Flesh by Erfan Ashourioun", grouped[11][3])
def test_iran_and_armenia_have_one_link_each_in_2026(self):
for name in ("Iran", "Armenia"):
anchors = []
for path in ART.glob("2026-*.md"):
content = path.read_text()
if f'anchor: "{name}"' in content:
anchors.append(path)
self.assertEqual(len(anchors), 1, (name, anchors))
iran = next(path for path in ART.glob("2026-*.md")
if 'anchor: "Iran"' in path.read_text())
self.assertIn("0b1781e580e6d0852728b6aab4f45f0eded30394ea8ff74d9d7ce8ae326bd172",
iran.name)
def test_2026_highlights_follow_supplied_chronology(self): def test_2026_highlights_follow_supplied_chronology(self):
anchors = {} anchors = {}
for path in ART.glob("*photo-*.md"): for path in ART.glob("*photo-*.md"):