<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Knowledge Base (Posts about gallery)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/gallery.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2023 &lt;a href="mailto:bgstack15@gmail.com"&gt;bgstack15&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-SA"
style="border-width:0; margin-bottom:12px;"
src="https://bgstack15.ddns.net/.images/l_by-sa_4.0_88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Sun, 27 Aug 2023 16:00:23 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>New image helper</title><link>https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;Because I love reinventing the wheel, here is my way-too-simple photo gallery web page generator.&lt;/p&gt;
&lt;div class="code"&gt;&lt;table class="codetable"&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-1"&gt;&lt;code data-line-number=" 1"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-2"&gt;&lt;code data-line-number=" 2"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Startdate: 2023-07-13-5 16:48&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-3"&gt;&lt;code data-line-number=" 3"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Purpose: make simple html gallery of images and directories&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-4"&gt;&lt;code data-line-number=" 4"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Reference: tapestry-helper.sh&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-5"&gt;&lt;code data-line-number=" 5"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Usage:&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-6"&gt;&lt;code data-line-number=" 6"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;#    Ensure no spaces in the filenames.&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-7"&gt;&lt;code data-line-number=" 7"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Improve:&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-8"&gt;&lt;code data-line-number=" 8"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;#    add ".." links to any child directories.&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-9"&gt;&lt;code data-line-number=" 9"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/mnt/public/www/gallery/2013-01-picasa-partial-dump
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-10"&gt;&lt;code data-line-number="10"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;HTML_HEAD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.header.html"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-11"&gt;&lt;code data-line-number="11"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;HTML_FOOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.footer.html"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-12"&gt;&lt;code data-line-number="12"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;DIRECTORY_ICON&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/gallery/2013-01-picasa-partial-dump/folder.svg"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-13"&gt;&lt;code data-line-number="13"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-14"&gt;&lt;code data-line-number="14"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;THUMBNAIL_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;300&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-15"&gt;&lt;code data-line-number="15"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nv"&gt;USE_THUMBNAILS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-16"&gt;&lt;code data-line-number="16"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -n &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-17"&gt;&lt;code data-line-number="17"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-18"&gt;&lt;code data-line-number="18"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   mkdir -p &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.thumbnails"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-19"&gt;&lt;code data-line-number="19"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-20"&gt;&lt;code data-line-number="20"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# use MAKE_THUMBNAILS=1 to actually run convert, which slows the process down. You disable MAKE_THUMBNAILS when just regenerating the html&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-21"&gt;&lt;code data-line-number="21"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nb"&gt;test&lt;/span&gt; -z &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MAKE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;MAKE_THUMBNAILS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-22"&gt;&lt;code data-line-number="22"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-23"&gt;&lt;code data-line-number="23"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-24"&gt;&lt;code data-line-number="24"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# now that there are no spaces we can just do this&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-25"&gt;&lt;code data-line-number="25"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="c1"&gt;# begin dir loop&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-26"&gt;&lt;code data-line-number="26"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; word &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;$(&lt;/span&gt; find &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; -mindepth &lt;span class="m"&gt;0&lt;/span&gt; -type d ! -name &lt;span class="s1"&gt;'.thumbnails'&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-27"&gt;&lt;code data-line-number="27"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-28"&gt;&lt;code data-line-number="28"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="o"&gt;(&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-29"&gt;&lt;code data-line-number="29"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-30"&gt;&lt;code data-line-number="30"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nv"&gt;shortword&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; basename &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-31"&gt;&lt;code data-line-number="31"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   mkdir -p ./.thumbnails
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-32"&gt;&lt;code data-line-number="32"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   rm -f ./index.html
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-33"&gt;&lt;code data-line-number="33"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-34"&gt;&lt;code data-line-number="34"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&amp;gt; ./index.html
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-35"&gt;&lt;code data-line-number="35"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"cat &amp;lt;&amp;lt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-36"&gt;&lt;code data-line-number="36"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;$(&lt;/span&gt; cat &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HTML_HEAD&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-37"&gt;&lt;code data-line-number="37"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="s2"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-38"&gt;&lt;code data-line-number="38"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-39"&gt;&lt;code data-line-number="39"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="c1"&gt;# make a .. link if not the parent directory&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-40"&gt;&lt;code data-line-number="40"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;if&lt;/span&gt; ! &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INDIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-41"&gt;&lt;code data-line-number="41"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;div class=\"item\"&amp;gt;&amp;lt;a href=\"..\"&amp;gt;&amp;lt;img src=\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIRECTORY_ICON&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\" class=\"thumb\"&amp;gt;..&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-42"&gt;&lt;code data-line-number="42"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-43"&gt;&lt;code data-line-number="43"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nv"&gt;tds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; find . -mindepth &lt;span class="m"&gt;1&lt;/span&gt; -maxdepth &lt;span class="m"&gt;1&lt;/span&gt; -type d ! -name &lt;span class="s1"&gt;'.thumbnails'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'.*'&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-44"&gt;&lt;code data-line-number="44"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;for&lt;/span&gt; td &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tds&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-45"&gt;&lt;code data-line-number="45"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nv"&gt;td_basename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; basename &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;td&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-46"&gt;&lt;code data-line-number="46"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="c1"&gt;#echo "&amp;lt;a href=\"${td}\"&amp;gt;&amp;lt;img src=\"${DIRECTORY_ICON}\" class=\"thumb\"&amp;gt;${td}&amp;lt;/a&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-47"&gt;&lt;code data-line-number="47"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;div class=\"item\"&amp;gt;&amp;lt;a href=\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;td&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\"&amp;gt;&amp;lt;img src=\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIRECTORY_ICON&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\" class=\"thumb\"&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;td_basename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-48"&gt;&lt;code data-line-number="48"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-49"&gt;&lt;code data-line-number="49"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nv"&gt;tfs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; find . -mindepth &lt;span class="m"&gt;1&lt;/span&gt; -maxdepth &lt;span class="m"&gt;1&lt;/span&gt; ! -type d ! -name &lt;span class="s1"&gt;'*.ini'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'.*.ini'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'.*.swp'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'*.sh'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'*.html'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'*.db'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'folder.svg'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'.*'&lt;/span&gt; ! -name &lt;span class="s1"&gt;'*.css'&lt;/span&gt; -printf &lt;span class="s1"&gt;'%T@ %P\n'&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sort -n &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-50"&gt;&lt;code data-line-number="50"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;for&lt;/span&gt; tf &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tfs&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-51"&gt;&lt;code data-line-number="51"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-52"&gt;&lt;code data-line-number="52"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nv"&gt;tf_in&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-53"&gt;&lt;code data-line-number="53"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nv"&gt;tf_thumb_web&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-54"&gt;&lt;code data-line-number="54"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -n &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-55"&gt;&lt;code data-line-number="55"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-56"&gt;&lt;code data-line-number="56"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;         &lt;span class="nv"&gt;tf_thumb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="p"&gt;%%/&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.thumbnails/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;%%.???&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jpg"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-57"&gt;&lt;code data-line-number="57"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;         &lt;span class="nv"&gt;tf_thumb_web&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;".thumbnails/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;%%.???&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jpg"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-58"&gt;&lt;code data-line-number="58"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;         &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MAKE_THUMBNAILS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; convert -filter Lanczos -resize &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;THUMBNAIL_SIZE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;x&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;THUMBNAIL_SIZE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf_thumb&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-59"&gt;&lt;code data-line-number="59"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-60"&gt;&lt;code data-line-number="60"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;a href=\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\"&amp;gt;&amp;lt;img src=\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tf_thumb_web&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\" class=\"thumb\"&amp;gt;&amp;lt;/a&amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-61"&gt;&lt;code data-line-number="61"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-62"&gt;&lt;code data-line-number="62"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   cat &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HTML_FOOT&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-63"&gt;&lt;code data-line-number="63"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-64"&gt;&lt;code data-line-number="64"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;   &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="linenos linenodiv"&gt;&lt;a href="https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/#-65"&gt;&lt;code data-line-number="65"&gt;&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;code&gt;&lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="c1"&gt;# end dir loop&lt;/span&gt;
&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;My .header.html and .footer.html files are very basic.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;!-- started 2023-07-13 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/gallery/2013-01-picasa-partial-dump/simple.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;shortword&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And footer just closes the html tags.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And the css.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="na"&gt;.thumb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;max-width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;300&lt;/span&gt;&lt;span class="nf"&gt;px&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;max-height:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;300&lt;/span&gt;&lt;span class="nf"&gt;px&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="nf"&gt;div.item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;vertical-align:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;top&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;display:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;inline-block&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;text-align:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;center&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;120&lt;/span&gt;&lt;span class="nf"&gt;px&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;img {&lt;/span&gt;
&lt;span class="cm"&gt;    width: 100px;&lt;/span&gt;
&lt;span class="cm"&gt;    height: 100px;&lt;/span&gt;
&lt;span class="cm"&gt;    background-color: grey;&lt;/span&gt;
&lt;span class="cm"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="nf"&gt;div.item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;img&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;max-width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;220&lt;/span&gt;&lt;span class="nf"&gt;px&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;max-height:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;220&lt;/span&gt;&lt;span class="nf"&gt;px&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="na"&gt;.caption&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;display:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I just grabbed a random folder.svg from one of the GNOME Icon themes.&lt;/p&gt;</description><category>gallery</category><category>photos</category><category>shell</category><category>web</category><guid>https://bgstack15.ddns.net/blog/posts/2023/08/27/new-image-helper/</guid><pubDate>Sun, 27 Aug 2023 15:58:45 GMT</pubDate></item><item><title>Web gallery solution</title><link>https://bgstack15.ddns.net/blog/posts/2021/02/02/web-gallery-solution/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;A while back, I was inspired by Thealaskalinuxuser's
&lt;a href="https://thealaskalinuxuser.wordpress.com/2019/07/23/home-photo-server-part-2-apache-phpalbum-and-piwigo/"&gt;article&lt;/a&gt; about how he set up his photo
sharing server at home. I experimented briefly with piwigo back when I read
that, but ended up stopping that project. When I returned to this topic, I
realized I just didn't want to deal with php. I applaud his stamina and
commitment, but I want something with fewer dependencies. Here is my solution.
So, here is my internal documentation that is my alternative to Google Photos.&lt;/p&gt;
&lt;h2&gt;Gallery solution for internal network&lt;/h2&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;As part of my goals to run self-hosted services for myself and my family, I
intend to maintain a web gallery of photos and videos. This solution consists
of several parts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tools that create symlink forests to the original image files, in a specific location&lt;/li&gt;
&lt;li&gt;Static site generator &lt;a href="http://sigal.saimon.org/"&gt;sigal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Customized theme for sigal&lt;/li&gt;
&lt;li&gt;Customized sigal config for that theme&lt;/li&gt;
&lt;li&gt;Gallery id table&lt;/li&gt;
&lt;li&gt;SELinux rules&lt;/li&gt;
&lt;li&gt;CGI scripts for Apache httpd&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Architecture&lt;/h3&gt;
&lt;p&gt;The solution runs on server1, the main file server for the internal network.&lt;/p&gt;
&lt;h4&gt;Tools that create symlink forests for the gallery source directories&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/generate.sh"&gt;Generate.sh&lt;/a&gt;
is what I used for the proof of concept. This needs to be rewritten in python,
and to handle files without exif data. My python implementation will show up
on this blog at a later date.&lt;/p&gt;
&lt;h4&gt;Static site generator&lt;/h4&gt;
&lt;p&gt;The &lt;a href="http://sigal.saimon.org/"&gt;sigal&lt;/a&gt; site generator is installed with pip3,
under local service account &lt;code&gt;sigal&lt;/code&gt; on server1. A special script,
&lt;strong&gt;/usr/local/bin/sigal.bin&lt;/strong&gt; will generate the static pages for a site. To use
this script, pass a parameter of the source directory where the sigal.conf.py
exists.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/usr/local/bin/sigal.bin /mnt/public/www/example/images/.gallery
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sigal depends on &lt;strong&gt;ffmpeg&lt;/strong&gt; for video thumbnailing and conversions. On CentOS
8, ffmpeg is in repository powertools. File
&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/sigal.bin"&gt;sigal.bin&lt;/a&gt;&lt;/p&gt;
&lt;table class="codehilitetable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;# File: /usr/local/bin/sigal.bin&lt;/span&gt;
&lt;span class="c1"&gt;# Author: bgstack15@gmail.com&lt;/span&gt;
&lt;span class="c1"&gt;# Startdate: 2021-01-24&lt;/span&gt;
&lt;span class="c1"&gt;# Title: Run sigal static site generator&lt;/span&gt;
&lt;span class="c1"&gt;# Purpose: run sigal static site generator for provided path&lt;/span&gt;
&lt;span class="c1"&gt;# History:&lt;/span&gt;
&lt;span class="c1"&gt;# Usage:&lt;/span&gt;
&lt;span class="c1"&gt;#    called by regen.cgi, or by hand&lt;/span&gt;
&lt;span class="c1"&gt;# Dependencies:&lt;/span&gt;
&lt;span class="c1"&gt;#    60_regen_gallery_sudo&lt;/span&gt;
&lt;span class="c1"&gt;#    gallery.te&lt;/span&gt;
&lt;span class="c1"&gt;#    service account "sigal" with `pip3 install --user sigal`&lt;/span&gt;
&lt;span class="c1"&gt;# Reverse dependencies:&lt;/span&gt;
&lt;span class="c1"&gt;#    httpd conf &lt;/span&gt;
&lt;span class="nv"&gt;sigal_home&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~sigal

&lt;span class="nb"&gt;test&lt;/span&gt; -z &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt; -z &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Pass to this script the gallery_id or directory path to a sigal.conf.py. Aborted."&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -d &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
   &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; -e /etc/gallery-cgi.conf &lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;then&lt;/span&gt;
      . /etc/gallery-cgi.conf
   &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c1"&gt;# no gallery_id listing exists.&lt;/span&gt;
      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No gallery_id table exists. Aborted."&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
   &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"init"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;then&lt;/span&gt;
   sudo su sigal -s /bin/bash -c &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;sigal_home&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin/sigal init"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
   &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="se"&gt;\"\$&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GALLERY_ID&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;
   sudo su sigal -s /bin/bash -c &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;sigal_home&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin/sigal build"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;h4&gt;Customized theme for sigal&lt;/h4&gt;
&lt;p&gt;Use theme &lt;strong&gt;bgstack15-gallery-theme&lt;/strong&gt; , in any location. You just need to put
its full path as the value of the theme in a sigal.conf.py for a gallery. This
is a fork of the default, included
&lt;a href="https://github.com/saimn/sigal/tree/master/sigal/themes/colorbox"&gt;colorbox&lt;/a&gt;
theme. The full theme is available in this project directory, as well as a
diff of it to the original as of sigal version 2.1.1. The main changes are
adding extra metadata handlers and link logic for the custom links related to
editing metadata.&lt;/p&gt;
&lt;h4&gt;Customized sigal config for that theme&lt;/h4&gt;
&lt;p&gt;When you &lt;strong&gt;run sigal init&lt;/strong&gt; in a directory, it generates a default config you
can modify. The example theme, and this whole solution, depends on adding a
number of settings. A summary of the specific options is here, but the full
example file is in this project directory.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'/var/www/gallery/.my2018'&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'/var/www/gallery/my2018'&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;use_orig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;True&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;edit_cgi_script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"/cgi-bin/gallery/edit.cgi"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgi&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;edit_enabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;False&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;edit_password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"makeupapassword"&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;edit_string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[edit]'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;edit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;toggle_enable_string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"Enable editing"&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;toggle_disable_string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"Disable editing"&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;toggle_link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"/cgi-bin/gallery/toggle-editing.cgi"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;toggle&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;editing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgi&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;toggle_editing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;&lt;/span&gt;
&lt;span class="n"&gt;        (False, 'Enable editing'),&lt;/span&gt;
&lt;span class="n"&gt;        (True, 'Disable editing')&lt;/span&gt;
&lt;span class="n"&gt;    &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;gallery_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;"example_images"&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tuples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;('Example link', 'http://example.org'),&lt;/span&gt;
&lt;span class="n"&gt;#          ('Another link', 'http://example.org')&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;&lt;/span&gt;
&lt;span class="n"&gt;    ('Regenerate pages', '/cgi-bin/gallery/regen.cgi?id=' + gallery_id)&lt;/span&gt;
&lt;span class="n"&gt;        &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;gallery_id&lt;/code&gt; is very important, because the cgi scripts and theme rely on
it.&lt;/p&gt;
&lt;h4&gt;Gallery id table&lt;/h4&gt;
&lt;p&gt;File &lt;strong&gt;/etc/gallery-cgi.conf&lt;/strong&gt; contains a list of &lt;strong&gt;gallery_id&lt;/strong&gt; translations
to directories with sigal.conf.py rules.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;example_images=/mnt/public/www/example/images/.gallery
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;SELinux rules&lt;/h4&gt;
&lt;p&gt;The reference system, server1, runs SELinux. A custom selinux module is needed
to allow all the operations that are a part of this gallery solution, which
include the following. File &lt;strong&gt;gallery.te&lt;/strong&gt; can be installed as an enabled
selinux module.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo checkmodule -M -m -o gallery.mod gallery.te &amp;amp;&amp;amp; sudo semodule_package -o gallery.pp -m gallery.mod &amp;amp;&amp;amp; sudo semodule -i gallery.pp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;File
&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/gallery.te"&gt;gallery.te&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Last modified 2021-01-30&lt;/span&gt;
&lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="n"&gt;gallery&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;faillog_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;security_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;httpd_config_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;init_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;sssd_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;mnt_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;lastlog_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;systemd_logind_sessions_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;initrc_var_run_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;tmpfs_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;gconf_home_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;chkpwd_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;systemd_logind_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;unconfined_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;shadow_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;sssd_selinux_manager_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;sssd_conf_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;var_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;httpd_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;capability&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;audit_write&lt;/span&gt; &lt;span class="n"&gt;dac_read_search&lt;/span&gt; &lt;span class="n"&gt;net_admin&lt;/span&gt; &lt;span class="n"&gt;setgid&lt;/span&gt; &lt;span class="n"&gt;setuid&lt;/span&gt; &lt;span class="n"&gt;sys_resource&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;noatsecure&lt;/span&gt; &lt;span class="n"&gt;rlimitinh&lt;/span&gt; &lt;span class="n"&gt;setrlimit&lt;/span&gt; &lt;span class="n"&gt;siginh&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;netlink_audit_socket&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;nlmsg_relay&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;netlink_selinux_socket&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;passwd&lt;/span&gt; &lt;span class="n"&gt;rootok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;add_name&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;remove_name&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="n"&gt;execute_no_trans&lt;/span&gt; &lt;span class="n"&gt;setattr&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;unlink&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="n"&gt;ioctl&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;dbus&lt;/span&gt; &lt;span class="n"&gt;send_msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;fifo_file&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="n"&gt;compute_av&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;lnk_file&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;filesystem&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;setfscreate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#============= httpd_sys_script_t ==============&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;faillog_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;var_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;ioctl&lt;/span&gt; &lt;span class="n"&gt;setattr&lt;/span&gt; &lt;span class="n"&gt;unlink&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;var_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;add_name&lt;/span&gt; &lt;span class="n"&gt;remove_name&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;gconf_home_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;gconf_home_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt; &lt;span class="n"&gt;execute_no_trans&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;httpd_config_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;initrc_var_run_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;lastlog_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;mnt_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;lnk_file&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;security_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;security_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;security_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="n"&gt;compute_av&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;capability&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;audit_write&lt;/span&gt; &lt;span class="n"&gt;dac_read_search&lt;/span&gt; &lt;span class="n"&gt;net_admin&lt;/span&gt; &lt;span class="n"&gt;setgid&lt;/span&gt; &lt;span class="n"&gt;setuid&lt;/span&gt; &lt;span class="n"&gt;sys_resource&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;netlink_audit_socket&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;nlmsg_relay&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;netlink_selinux_socket&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;bind&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;passwd&lt;/span&gt; &lt;span class="n"&gt;rootok&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;setrlimit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;shadow_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;sssd_conf_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;sssd_conf_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;systemd_logind_sessions_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;fifo_file&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;systemd_logind_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dbus&lt;/span&gt; &lt;span class="n"&gt;send_msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;tmpfs_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;add_name&lt;/span&gt; &lt;span class="n"&gt;remove_name&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;tmpfs_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;tmpfs_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;unlink&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="n"&gt;tmpfs_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;filesystem&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;setfscreate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;#============= init_t ==============&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;init_t&lt;/span&gt; &lt;span class="n"&gt;chkpwd_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;siginh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;init_t&lt;/span&gt; &lt;span class="n"&gt;unconfined_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;siginh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;#============= sssd_t ==============&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;sssd_t&lt;/span&gt; &lt;span class="n"&gt;sssd_selinux_manager_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;noatsecure&lt;/span&gt; &lt;span class="n"&gt;rlimitinh&lt;/span&gt; &lt;span class="n"&gt;siginh&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;#============= systemd_logind_t ==============&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;systemd_logind_t&lt;/span&gt; &lt;span class="n"&gt;httpd_sys_script_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dbus&lt;/span&gt; &lt;span class="n"&gt;send_msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;#============= httpd_t ==============&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="n"&gt;httpd_t&lt;/span&gt; &lt;span class="n"&gt;var_t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;getattr&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Sudo rules&lt;/h4&gt;
&lt;p&gt;For apache httpd to be able to run the sigal.bin, set up sudoers rules. File
&lt;strong&gt;60_regen_gallery_sudo&lt;/strong&gt; adds the permission necessary.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;#&lt;/span&gt; &lt;span class="nl"&gt;file:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sudoers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mh"&gt;60&lt;/span&gt;&lt;span class="n"&gt;_regen_gallery_sudo&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt; &lt;span class="nl"&gt;Reference:&lt;/span&gt; &lt;span class="nl"&gt;server4:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sudoers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mh"&gt;60&lt;/span&gt;&lt;span class="n"&gt;_starbound_sudo&lt;/span&gt;
&lt;span class="n"&gt;apache&lt;/span&gt; &lt;span class="n"&gt;ALL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="nl"&gt;NOPASSWD:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sigal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;CGI scripts for Apache httpd&lt;/h4&gt;
&lt;p&gt;The main focus of the gallery project is the ability to edit metadata from the
web view. While sigal is great for developers, some users might only care
about editing metadata from where they are actually viewing the media.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/edit.cgi"&gt;edit.cgi&lt;/a&gt; is called from the custom theme's "edit" links, and includes the form for making changes to media metadata.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/apply.cgi"&gt;apply.cgi&lt;/a&gt; actually makes the changes, and is called from the edit.cgi form.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/regen.cgi"&gt;regen.cgi&lt;/a&gt; invokes sigal.bin which re-runs sigal.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitlab.com/bgstack15/gallery/-/blob/master/toggle-editing.cgi"&gt;toggle-editing.cgi&lt;/a&gt; enables or disables editing. Enabling requires a password.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These can be placed anywhere you have enabled CGI for httpd, but the canonical
location is &lt;strong&gt;/var/www/cgi-bin/gallery/&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Operations&lt;/h3&gt;
&lt;p&gt;I anticipate that more work is needed on an ongoing basis. Here are some
processes that can be used.&lt;/p&gt;
&lt;h4&gt;Make a new gallery&lt;/h4&gt;
&lt;p&gt;To establish a new gallery, change directory to the source directory for the
gallery and run command&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sigal.bin init
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which generates the basic sigal.conf.py. Add the pertinent variables,
described in section "Customized sigal config for that theme" above.&lt;/p&gt;
&lt;h4&gt;Run sigal from command line&lt;/h4&gt;
&lt;p&gt;While the web links for "regen.cgi" are great for when you are viewing the
web, you can also run the sigal.bin from the cli. You need to include a path
to the directory that holds a sigal.conf.py, or else a &lt;strong&gt;gallery_id&lt;/strong&gt; from
/etc/gallery-cgi.conf.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sigal.bin example_images
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Make metadata changes directly on filesystem&lt;/h4&gt;
&lt;p&gt;You can of course, as designed by the author of sigal, go edit any
&lt;strong&gt;${IMAGENAME%%.jpg}.md&lt;/strong&gt; file with the relevant fields. See references 1 and
2 for the available fields. File index.md will be the metadata for the
directory itself.&lt;/p&gt;
&lt;h3&gt;History&lt;/h3&gt;
&lt;p&gt;In 2020, I installed &lt;a href="https://piwigo.org/"&gt;piwigo&lt;/a&gt; on a dev system. I didn't
want to deal with php, so I dropped it. In January 2021, I started listing
various options for self-hosted galleries. Read heading [Related Files] for
those. Criteria I assembled includes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata: description, date, comments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Related Files&lt;/h3&gt;
&lt;p&gt;These files are important to this gallery project. Check them all out at my
&lt;a href="https://gitlab.com/bgstack15/gallery"&gt;gitlab&lt;/a&gt; space.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/usr/local/bin/sigal.bin&lt;/li&gt;
&lt;li&gt;/var/www/cgi-bin/apply.cgi&lt;/li&gt;
&lt;li&gt;/var/www/cgi-bin/edit.cgi&lt;/li&gt;
&lt;li&gt;/var/www/cgi-bin/regen.cgi&lt;/li&gt;
&lt;li&gt;/var/www/cgi-bin/toggle-editing.cgi&lt;/li&gt;
&lt;li&gt;gallery.te&lt;/li&gt;
&lt;li&gt;/etc/sudoers.d/60_regen_gallery_sudo&lt;/li&gt;
&lt;li&gt;/etc/gallery-cgi.conf&lt;/li&gt;
&lt;li&gt;sigal.conf.py&lt;/li&gt;
&lt;li&gt;bgstack15-gallery-theme/&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://piwigo.org/"&gt;Piwigo&lt;/a&gt; uses PHP which I don't want to maintain.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/awesome-selfhosted/awesome-selfhosted#photo-and-video-galleries"&gt;Awesome selfhosted#photo-and-video-galleries&lt;/a&gt; is a whole list.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ones I considered without trying&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mediagoblin.org/"&gt;mediagoblin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/viktorstrate/photoview"&gt;photoview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bpatrik.github.io/pigallery2/"&gt;pigallery2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ones I listed as tolerable, but not focused on what I need.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lycheeorg.github.io/"&gt;lychee&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/trebonius0/Photato"&gt;photato&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.zx2c4.com/567"&gt;PhotoFloat&lt;/a&gt; written by the cgit author. He has a large body of good works.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;h4&gt;Weblinks&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://sigal.saimon.org/en/latest/album_information.html"&gt;http://sigal.saimon.org/en/latest/album_information.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sigal.saimon.org/en/latest/image_information.html"&gt;http://sigal.saimon.org/en/latest/image_information.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thealaskalinuxuser.wordpress.com/2019/07/23/home-photo-server-part-2-apache-phpalbum-and-piwigo/"&gt;Home photo server, part 2: Apache, phpAlbum, and Piwigo | thealaskalinuxuser&lt;/a&gt; Thealaskalinuxuser's guide to a home photo server with piwigo&lt;/li&gt;
&lt;/ol&gt;</description><category>gallery</category><category>generator</category><category>python</category><category>selinux</category><category>sigal</category><category>static</category><guid>https://bgstack15.ddns.net/blog/posts/2021/02/02/web-gallery-solution/</guid><pubDate>Tue, 02 Feb 2021 13:43:54 GMT</pubDate></item></channel></rss>