ctucx.git: gallery

static-site-generator for image-galleries [used @ photos.ctu.cx]

commit e6889bb69e575a4f96307ba4d573dad82a1f7708
parent 19162c7604ee821291c2f187d9c527358c8c396d
Author: ctucx <c@ctu.cx>
Date: Sun, 24 May 2020 02:37:36 +0200

general code refactoring
3 files changed, 74 insertions(+), 34 deletions(-)
M
src/assets/album.html
|
18
+++++++++---------
M
src/assets/picture.html
|
7
++++++-
M
src/picture_gallery.nim
|
83
++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
diff --git a/src/assets/album.html b/src/assets/album.html
@@ -65,12 +65,12 @@
 						 
 							<tr>
 								<td>Subalbums</td>
-								<td><span class="attr_subalbums">0</span></td>
+								<td><span class="attr_subalbums">{{numAlbums}}</span></td>
 							</tr>
 						 
 							<tr>
 								<td>Pictures</td>
-								<td><span class="attr_pictures">30</span></td>
+								<td><span class="attr_pictures">{{numPictures}}</span></td>
 							</tr>
 						</tbody>
 					</table>

@@ -89,10 +89,10 @@
 
 			{{#subalbums}}
 
-			<a href="{{name}}" class="album">
-				<img src="{{thumbnail1}}" alt="Photo thumbnail" width="200" height="200">
-				<img src="{{thumbnail2}}" alt="Photo thumbnail" width="200" height="200">
-				<img src="{{thumbnail3}}" alt="Photo thumbnail" width="200" height="200">
+			<a href="{{name}}/" class="album">
+				<img src="./{{thumbnail1}}" alt="Photo thumbnail" width="200" height="200">
+				<img src="./{{thumbnail2}}" alt="Photo thumbnail" width="200" height="200">
+				<img src="./{{thumbnail3}}" alt="Photo thumbnail" width="200" height="200">
 				<span class="overlay">
 					<h1>{{name}}</h1>
 					<p>{{numPictures}} Pictures - {{numAlbums}} Albums</p>

@@ -109,10 +109,10 @@
 			{{/hasSubalbums}}
 
 			{{#pictures}}
-			<a href="{{name}}" class="photo">
-				<img src="thumbnails/{{name}}.png" alt="Photo thumbnail" width="200" height="200">
+			<a href="{{name}}/" class="photo">
+				<img src="./thumbnails/{{name}}.png" alt="Photo thumbnail" width="200" height="200">
 				<span class="overlay">
-					<h1>2017.06</h1>
+					<h1>{{name}}</h1>
 					<p><span title="Camera Date"><svg class="iconic "><use xlink:href="/iconic.svg#camera-slr"></use></svg></span></p>
 				</span>
 			</a>
diff --git a/src/assets/picture.html b/src/assets/picture.html
@@ -10,13 +10,18 @@
 		<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="apple-mobile-web-app-status-bar-style" content="black">
 		<meta name="apple-mobile-web-app-capable" content="yes">
+
+		<meta property="og:image" content="../medium/{{name}}.jpg" />
+
+		<link type="text/css" rel="stylesheet" href="/style.css">
+		<link rel="shortcut icon" href="favicon.ico">
 	</head>
 	<body>
 		<header class="header header-view" style="display: flex;">
 			<!--<div class="header-toolbar headerer-toolbar-photo header-toolbar-visible">-->
 			<a class="button" href=".." id="button_close" title="Close Photo"><svg class="iconic"><use xlink:href="/iconic.svg#chevron-left"></use></svg></a>
 			<a class="header-title">{{name}}<svg class="iconic "><use xlink:href="/iconic.svg#caret-bottom"></use></svg></a>
-			<a class="button" href="/original{{orig}}" title="Download"><svg class="iconic"><use xlink:href="/iconic.svg#cloud-download"></use></svg></a>
+			<a class="button" href="/originals/{{orig}}" title="Download"><svg class="iconic"><use xlink:href="/iconic.svg#cloud-download"></use></svg></a>
 			<a class="header-divider"></a>
 
 			<input type="checkbox" id="toggle">
diff --git a/src/picture_gallery.nim b/src/picture_gallery.nim
@@ -1,4 +1,4 @@
-import os, osproc, options, json, strutils, sequtils, random
+import os, osproc, options, json, strutils, sequtils, random, algorithm
 import moustachu
 
 const asset_exif_js      = staticRead"./assets/exif.js"

@@ -24,27 +24,39 @@ type
         desc*:     Option[string]
         size*:     BiggestInt
 
+
 proc createPicture(path: string): Picture = 
     let allowedExtensions = @[".jpg", ".jpeg", ".JPG", ".JPEG"]
     let (dir, name, ext) = splitFile(path)
 
     if not allowedExtensions.contains(ext): return
 
-    if fileExists(dir & "/" & name & ".txt"): result.desc = some(readFile(dir & "/" & name & ".txt")) 
+    if fileExists(joinPath(dir, name, ".txt")): result.desc = some(readFile(joinPath(dir, name,".txt")))
 
     result.name       = name
     result.path       = dir
     result.filename   = lastPathPart(path)
     result.size       = getFileSize(path)
 
+proc sortAlbums(x, y: Album): int =
+  if x.name < y.name: -1
+  elif x.name == y.name: 0
+  else: 1
+
+
+proc sortPictures(x, y: Picture): int =
+  if x.name < y.name: -1
+  elif x.name == y.name: 0
+  else: 1
+
 proc createAlbum(path: string, isRoot: bool): Album = 
     result.name    = lastPathPart(path)
 
     if isRoot != false:
         result.path       = path
 
-    if not fileExists(path & "/.nomedia"): result.visible = true
-    if fileExists(path & "/.description"): result.desc = some(readFile(path & "/.description")) 
+    if not fileExists(joinPath(path, ".nomedia")): result.visible = true
+    if fileExists(joinPath(path, ".description")): result.desc = some(readFile(joinPath(path, ".description")))
 
     for element in walkDir(path):
         if element.kind == pcDir:

@@ -54,23 +66,27 @@ proc createAlbum(path: string, isRoot: bool): Album =
             let picture = createPicture(element.path)
             if picture.name != "": result.pictures.add(picture)
 
+    result.subalbums.sort(sortAlbums)
+    result.pictures.sort(sortPictures)
+
 
 proc placeAssets(targetDir: string) =
     echo "============"
-    echo "Copying Assets to target dir"
+    echo "Create Assets in target dir"
 
     discard existsOrCreateDir(targetDir)
-    writeFile(targetDir & "/exif.js", asset_exif_js)
-    writeFile(targetDir & "/style.css", asset_style_css)
-    writeFile(targetDir & "/no_images.svg", asset_noimages_svg)
-    writeFile(targetDir & "/iconic.svg", asset_iconic_svg)
+    writeFile(joinPath(targetDir, "exif.js"), asset_exif_js)
+    writeFile(joinPath(targetDir, "style.css"), asset_style_css)
+    writeFile(joinPath(targetDir, "no_images.svg"), asset_noimages_svg)
+    writeFile(joinPath(targetDir, "iconic.svg"), asset_iconic_svg)
+
 
 proc generateWebsite(sourceDir: string, targetDir: string, album: Album) =
     echo "============"
     echo "Create Album:" & album.name
     discard existsOrCreateDir(targetDir)
-    discard existsOrCreateDir(targetDir & "/thumbnails")
-    discard existsOrCreateDir(targetDir & "/medium")
+    discard existsOrCreateDir(joinPath(targetDir, "thumbnails"))
+    discard existsOrCreateDir(joinPath(targetDir, "medium"))
 
     var templateContext = %* {
             "name":         album.name,

@@ -91,7 +107,7 @@ proc generateWebsite(sourceDir: string, targetDir: string, album: Album) =
     if album.subalbums.len > 0: templateContext["hasSubalbums"] = %true
 
     for subalbum in album.subalbums:
-        generateWebsite(sourceDir, targetDir & "/" & subalbum.name, subalbum)
+        generateWebsite(sourceDir, joinPath(targetDir,subalbum.name), subalbum)
 
         var thumbnail1 = "/no_images.svg"
         var thumbnail2 = "/no_images.svg"

@@ -112,7 +128,8 @@ proc generateWebsite(sourceDir: string, targetDir: string, album: Album) =
             })
 
     for index, picture in album.pictures:
-        discard existsOrCreateDir(targetDir & "/" & picture.name)
+        discard existsOrCreateDir(joinPath(targetDir, picture.name))
+
         var pictureTemplateContext = %* {
                 "name":        picture.name,
                 "orig":        picture.path.replace(sourceDir, "") & "/" & picture.filename,

@@ -133,14 +150,14 @@ proc generateWebsite(sourceDir: string, targetDir: string, album: Album) =
             pictureTemplateContext["next_name"] = %album.pictures[index+1].name
 
         echo "Generate picture page: " & picture.name
-        writeFile(targetDir & "/" & picture.name & "/index.html", render(asset_picture_html, pictureTemplateContext))
+        writeFile(joinPath(targetDir, picture.name, "index.html"), render(asset_picture_html, pictureTemplateContext))
 
 
         if not fileExists(targetDir & "/thumbnails/" & picture.name & ".png"):
-            smallThumbnails.add("/usr/bin/mogrify -strip -quality 90 -format png -path " & targetDir & "/thumbnails -thumbnail 200x200^ -gravity center -extent 200x200 " & picture.path & "/" & picture.filename)
+            smallThumbnails.add("/usr/bin/env mogrify -strip -quality 90 -format png -path " & quoteShell(joinPath(targetDir, "thumbnails")) & " -thumbnail 200x200^ -gravity center -extent 200x200 " & quoteShell(joinPath(picture.path, picture.filename)))
 
         if not fileExists(targetDir & "/medium/" & picture.name & ".jpg"):
-            mediumThumbnails.add("/usr/bin/mogrify -format jpg -path " & targetDir & "/medium -resize 1920x\\> " & picture.path & "/" & picture.filename)
+            mediumThumbnails.add("/usr/bin/env mogrify -format jpg -path " & quoteShell(joinPath(targetDir, "medium")) & " -resize 1920x\\> " & quoteShell(joinPath(picture.path, picture.filename)))
 
         templateContext["pictures"].add(%* {
                 "name":        picture.name,

@@ -148,19 +165,38 @@ proc generateWebsite(sourceDir: string, targetDir: string, album: Album) =
 
     echo "Generate small thumbnails!"
     discard execProcesses(smallThumbnails)
+
     echo "Generate medium thumbnails!"
     discard execProcesses(mediumThumbnails)
 
     echo "Generate album page!\n"
-    writeFile(targetDir & "/index.html", render(asset_album_html, templateContext))
+    writeFile(joinPath(targetDir, "index.html"), render(asset_album_html, templateContext))
+
+
+
+proc main = 
+  randomize()
+
+  if (execProcess("/usr/bin/env mogrify -v").contains("No such file or directory")):
+    echo "It seems like you don't have ImageMagick installed, which is mandatory to use this tool.\nBye!"
+    quit()
+
+  let sourceDir = normalizedPath(paramStr(1))
+  let targetDir = normalizedPath(paramStr(2))
+
+  if not dirExists(sourceDir):
+    echo "The source directory does not exist!\nBye!"
+    quit()
 
+  if not dirExists(targetDir):
+    echo "The target directory does not exist!\nBye!"
+    quit()
 
+  
 
-randomize()
+  let mainAlbum = createAlbum(sourceDir, true)
 
-let sourceDir = paramStr(1)
-let targetDir = paramStr(2)
+  placeAssets(targetDir)
+  generateWebsite(sourceDir, targetDir, mainAlbum)
 
-let mainAlbum = createAlbum(sourceDir, true)
-placeAssets(targetDir)
-generateWebsite(sourceDir, targetDir, mainAlbum)-
\ No newline at end of file
+main()