Site is building. Let 'er rip.

This commit is contained in:
Matt McWilliams 2024-12-10 21:38:41 -05:00
parent 252734f100
commit 4ff8a61c21
32 changed files with 523 additions and 55 deletions

View File

@ -6,7 +6,11 @@ S3_ACCESS_KEY=""
S3_ACCESS_SECRET=""
S3_BUCKET=""
S3_ENDPOINT=""
UMAMI=""
UMAMI_ID=""
UMAMI_URL=""
DB="data/site.db"
ARTIST="Unknown"
GEOCODE_API_KEY=""
TITLE=""
H1=""
DEST="remote:/dir/"

27
dist/build.js vendored
View File

@ -2,7 +2,10 @@
Object.defineProperty(exports, "__esModule", { value: true });
require("dotenv/config");
const log_1 = require("./log");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const db_1 = require("./db");
const env_1 = require("./env");
const templates_1 = require("./templates");
class Build {
constructor() {
@ -10,13 +13,35 @@ class Build {
this.log.info(`Building site: ${new Date()}`);
this.tmpl = new templates_1.Templates();
this.db = new db_1.DB();
this.www = (0, env_1.envString)('WWW', './www');
this.main();
}
async main() {
let photos;
let html;
let data = {
title: (0, env_1.envString)('TITLE', 'Unknown'),
h1: (0, env_1.envString)('H1', 'Unknown'),
artist: (0, env_1.envString)('ARTIST', 'Unknown'),
umami_url: (0, env_1.envString)('UMAMI_URL', null),
umami_id: (0, env_1.envString)('UMAMI_ID', null),
year: (new Date()).getFullYear()
};
let home = (0, path_1.join)(this.www, 'index.html');
await this.tmpl.build();
photos = await this.db.getAll();
await this.tmpl.render('index', { photos });
photos = photos.map((photo) => {
photo.thumbHeight = Math.round((420.0 / photo.width) * photo.height) + 4;
return photo;
});
html = await this.tmpl.render('index', { ...data, photos });
try {
await (0, promises_1.writeFile)(home, html, 'utf8');
this.log.info(`Wrote ${home}`);
}
catch (err) {
this.log.error(`Error writing home page`, err);
}
}
}
new Build();

2
dist/build.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":";;AAAA,yBAAuB;AAEvB,+BAAkC;AAIlC,6BAA0B;AAE1B,2CAAwC;AAExC,MAAM,KAAK;IAKV;QACC,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,EAAE,GAAG,IAAI,OAAE,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,IAAI;QACjB,IAAI,MAAgB,CAAC;QACrB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAExB,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;CACD;AAED,IAAI,KAAK,EAAE,CAAC"}
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":";;AAAA,yBAAuB;AAEvB,+BAAkC;AAElC,0CAAkD;AAClD,+BAA4B;AAE5B,6BAA0B;AAE1B,+BAAkC;AAClC,2CAAwC;AAExC,MAAM,KAAK;IAOV;QACC,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,EAAE,GAAG,IAAI,OAAE,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,IAAI;QACjB,IAAI,MAAgB,CAAC;QACrB,IAAI,IAAa,CAAC;QAClB,IAAI,IAAI,GAAS;YAChB,KAAK,EAAG,IAAA,eAAS,EAAC,OAAO,EAAE,SAAS,CAAC;YACrC,EAAE,EAAG,IAAA,eAAS,EAAC,IAAI,EAAE,SAAS,CAAC;YAC/B,MAAM,EAAG,IAAA,eAAS,EAAC,QAAQ,EAAE,SAAS,CAAC;YACvC,SAAS,EAAG,IAAA,eAAS,EAAC,WAAW,EAAE,IAAI,CAAC;YACxC,QAAQ,EAAG,IAAA,eAAS,EAAC,UAAU,EAAE,IAAI,CAAC;YACtC,IAAI,EAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE;SACjC,CAAC;QACF,IAAI,IAAI,GAAY,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAEjD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAExB,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAa,EAAE,EAAE;YACrC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACd,CAAC,CAAC,CAAA;QACF,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC;YACJ,MAAM,IAAA,oBAAS,EAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;QAChD,CAAC;IACF,CAAC;CACD;AAED,IAAI,KAAK,EAAE,CAAC"}

6
dist/db/index.js vendored
View File

@ -13,7 +13,7 @@ class DB {
this.db.run('PRAGMA journal_mode = WAL;');
this.log.info(`DB: ${databaseFile}`);
}
async run(query, args = null) {
async run(query, args = []) {
return new Promise((resolve, reject) => {
return this.db.run(query, args, (err, rows) => {
if (err)
@ -22,7 +22,7 @@ class DB {
});
});
}
async all(query, args = null) {
async all(query, args = []) {
return new Promise((resolve, reject) => {
return this.db.all(query, args, (err, rows) => {
if (err)
@ -89,7 +89,7 @@ class DB {
return exists;
}
async getAll() {
const query = `SELECT * FROM photos;`;
const query = `SELECT * FROM photos ORDER BY score ASC, created DESC;`;
let rows = [];
try {
rows = await this.all(query);

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":";;;AAAA,yBAAuB;AAEvB,gCAAmC;AAEnC,qCAAmC;AACnC,gCAAmC;AA6BnC,MAAa,EAAE;IAId;QACC,MAAM,YAAY,GAAY,IAAA,eAAS,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,kBAAQ,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAE,4BAA4B,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,YAAY,EAAE,CAAC,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,GAAG,CAAE,KAAc,EAAE,OAAe,EAAE;QACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAkB,EAAE,MAAiB,EAAE,EAAE;YAC5D,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,GAAW,EAAE,IAAY,EAAE,EAAE;gBAC7D,IAAI,GAAG;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,GAAG,CAAE,KAAc,EAAE,OAAe,EAAE;QACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAkB,EAAE,MAAiB,EAAE,EAAE;YAC5D,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,GAAW,EAAE,IAAY,EAAE,EAAE;gBAC7D,IAAI,GAAG;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC;IAEO,SAAS,CAAE,GAAY;QAC9B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACjC,CAAC;IAEO,WAAW,CAAE,GAAa;QACjC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,mEAAmE;IAC5D,KAAK,CAAC,MAAM,CAAE,KAAa;QACjC,MAAM,IAAI,GAAc,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAY,uBAAuB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA,EAAE,CAAA,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QACzG,MAAM,MAAM,GAAW,EAAE,CAAC;QAC1B,KAAK,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACtB,IAAI,OAAQ,KAAa,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAE,IAAI,CAAC,WAAW,CAAG,KAAa,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,IAAI,CAAE,KAAa,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,CAAC;QACF,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,UAAU,CAAE,IAAa;QACrC,MAAM,KAAK,GAAY,+CAA+C,CAAC;QACvE,IAAI,IAAI,GAAW,EAAE,CAAC;QACtB,IAAI,MAAM,GAAa,KAAK,CAAC;QAC7B,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAE,IAAI,CAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,IAAI,CAAC;QACf,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,UAAU,CAAE,IAAa;QACrC,MAAM,KAAK,GAAY,+CAA+C,CAAC;QACvE,IAAI,IAAI,GAAW,EAAE,CAAC;QACtB,IAAI,MAAM,GAAa,KAAK,CAAC;QAC7B,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAE,IAAI,CAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,GAAG,IAAI,CAAC;QACf,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,MAAM;QAClB,MAAM,KAAK,GAAY,wDAAwD,CAAC;QAChF,IAAI,IAAI,GAAa,EAAE,CAAC;QACxB,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,aAAa,CAAE,QAAiB,EAAE,MAAe;QAC7D,MAAM,KAAK,GAAY,iFAAiF,CAAC;QACzG,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,QAAQ;QACT,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,WAAW,CAAE,QAAiB;QAC1C,MAAM,KAAK,GAAa,qEAAqE,CAAC;QAC9F,IAAI,IAAI,GAAW,EAAE,CAAC;QACtB,IAAI,GAAG,GAAY,IAAI,CAAC;QACxB,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,QAAQ;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,GAAG,GAAG;gBACL,QAAQ,EAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ;gBAC3B,SAAS,EAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;aAC7B,CAAA;QACF,CAAC;QAED,OAAO,GAAG,CAAC;IACZ,CAAC;CAED;AAhID,gBAgIC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,EAAE,EAAE,CAAC"}

14
dist/generate.js vendored
View File

@ -35,17 +35,11 @@ class Generate {
this.log.info(`Generating site: ${new Date()}`);
this.db = new db_1.DB();
this.s3 = new files3_1.Files3((0, env_1.envString)('S3_BUCKET', 's3bucket'), true);
this.geocode = new geocode_1.Geocode();
this.geocode = new geocode_1.Geocode(this.db);
this.generate();
this.score = args.score;
}
async generate() {
//check version
//sync
await this.checkInbox();
//validate
}
async checkInbox() {
let inbox;
let images;
let filename;
@ -108,6 +102,7 @@ class Generate {
}
try {
await this.db.create(photo);
this.log.info(JSON.stringify(photo, null, '\t'));
}
catch (err) {
this.log.error(`Error inserting photo into database`, err);
@ -147,7 +142,7 @@ class Generate {
const filePath = await this.mktemp('photosite_exif');
const created = moment_1.default.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss');
let exif = `-Artist=${this.artist}
-ImageTitle=${photo.name}
-Title=${photo.description}
-ImageUniqueId=${photo.id}
-DateTimeOriginal=${created}`;
const iso = photo.filmstock.split(' ').filter(el => this.isOnlyNumbers(el)).map(el => parseInt(el)).filter(el => el > 25);
@ -247,6 +242,7 @@ class Generate {
return {
id: (0, uuid_1.v4)(),
name: (0, path_1.basename)(image),
description: meta.description,
original: meta.original,
hash,
width: dimensions.width,
@ -270,7 +266,7 @@ class Generate {
const name = (0, path_1.basename)(image);
const dest = (0, path_1.join)(this.photos, name);
try {
//await rename(image, dest);
await (0, promises_1.rename)(image, dest);
this.log.info(`Moved image ${name} to outbox`);
}
catch (err) {

File diff suppressed because one or more lines are too long

View File

@ -9,13 +9,12 @@ const url_1 = require("url");
const node_fetch_1 = __importDefault(require("node-fetch"));
const log_1 = require("../log");
const env_1 = require("../env");
const db_1 = require("../db");
class Geocode {
constructor() {
constructor(db) {
this.log = (0, log_1.createLog)('geocode');
this.baseUrl = 'https://geocode.maps.co/search';
this.apiKey = (0, env_1.envString)('GEOCODE_API_KEY', null);
this.db = new db_1.DB();
this.db = db;
}
async query(location) {
let res = await this.db.getLocation(location);
@ -47,6 +46,10 @@ class Geocode {
this.log.error('Error getting response', err);
return null;
}
if (response.status !== 200) {
this.log.warn(`Invalid response from API [${response.status}]`);
return null;
}
try {
json = await response.json();
}

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/geocode/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/geocode/index.ts"],"names":[],"mappings":"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"}

4
less/bluesky.svg Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="600" height="530" version="1.1" xmlns="http://www.w3.org/2000/svg"><script xmlns=""/>
<path d="m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 759 B

1
less/github.svg Normal file
View File

@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 960 B

153
less/style.less Normal file
View File

@ -0,0 +1,153 @@
* {
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
:hover {
color: #080810;
}
a {
text-decoration: none;
}
html {
height: 100%;
background: #f3f1f1
}
body {
min-height: 100%;
}
body,html {
padding: 0;
margin: 0;
height: auto!important;
height: 100%;
min-height: 100%;
position: relative;
}
#title{
width: 320px;
margin: 0 auto;
position: relative;
}
h1 {
font-size: 43px;
line-height: 70px;
font-weight: 200;
text-align: center;
cursor: default;
color: #fff;
text-shadow: 1px 1px 3px #969696;
margin-bottom: 15px;
&:hover{
color: #fff;
}
a {
display: block;
text-align: center;
cursor: pointer;
text-rendering: geometricPrecision;
color: #fff;
&:hover{
color: transparent;
}
}
&:focus:before,
&:hover:before {
content: "hi@";
position: absolute;
left: -38px;
}
&:focus:after,
&:hover:after {
content: ".com";
position: absolute;
}
}
header {
ul {
list-style: none;
display: flex;
align-items: center;
justify-content: center;
width: 320px;
margin: 15px auto;
li {
padding: 0 10px;
a {
color: #fff;
font-weight: bold;
font-size: 24px;
text-shadow: 1px 1px 3px #969696;
&:hover {
color: #fff;
}
img {
max-height: 35px;
height: 35px;
width: auto;
-webkit-filter: drop-shadow( 1px 1px 3px #969696);
filter: drop-shadow( 1px 1px 3px #969696);
}
}
}
}
}
footer {
color: #fff;
text-shadow: 1px 1px 3px #969696;
font-weight: bold;
margin-top: 50px;
margin-bottom: 30px;
&:hover {
color: #fff;
}
}
.copyleft {
display: inline-block;
transform: rotate(180deg);
}
@media (max-width: 420px) {
#main {
.container {
&:focus,
&:hover {
font-size: 30px !important
}
&:focus:before,
&:hover:before {
left: 20px !important
}
}
}
}
#photos{
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: center;
a {
display: block;
width: 420px;
}
}

19
less/vimeo.svg Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -1.5 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>vimeo [#144]</title>
<desc>Created with Sketch.</desc>
<defs>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Dribbble-Light-Preview" transform="translate(-60.000000, -7560.000000)" fill="#fff">
<g id="icons" transform="translate(56.000000, 160.000000)">
<path d="M23.99,7403.93262 C23.9,7405.8454 22.541,7408.46538 19.911,7411.79058 C17.192,7415.26353 14.891,7417 13.009,7417 C11.843,7417 10.857,7415.94019 10.051,7413.82155 L8.437,7407.99457 C7.839,7405.87495 7.197,7404.81514 6.51,7404.81514 C6.36,7404.81514 5.837,7405.12441 4.941,7405.74296 L4,7404.55117 C4.986,7403.69722 5.957,7402.84326 6.913,7401.99029 C8.228,7400.87138 9.214,7400.28337 9.871,7400.22427 C11.425,7400.07751 12.381,7401.12156 12.74,7403.35839 C13.128,7405.77251 13.397,7407.2726 13.547,7407.8616 C13.995,7409.86303 14.488,7410.86374 15.026,7410.86374 C15.444,7410.86374 16.072,7410.21662 16.908,7408.92141 C17.745,7407.6262 18.193,7406.64026 18.253,7405.96359 C18.372,7404.84469 17.924,7404.28622 16.908,7404.28622 C16.43,7404.28622 15.937,7404.38865 15.429,7404.59451 C16.415,7401.44561 18.298,7399.91499 21.077,7400.00364 C23.138,7400.06274 24.11,7401.37174 23.99,7403.93262 L23.99,7403.93262 Z" id="vimeo-[#144]">
</path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

171
package-lock.json generated
View File

@ -16,6 +16,7 @@
"handlebars": "^4.7.8",
"handlebars-helpers": "^0.10.0",
"image-size": "^1.1.1",
"less": "^4.2.1",
"lodash": "^4.17.21",
"mime-types": "^2.1.35",
"moment": "^2.30.1",
@ -1337,6 +1338,18 @@
"license": "ISC",
"optional": true
},
"node_modules/copy-anything": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
"license": "MIT",
"dependencies": {
"is-what": "^3.14.1"
},
"funding": {
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@ -1592,6 +1605,19 @@
"license": "MIT",
"optional": true
},
"node_modules/errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
"license": "MIT",
"optional": true,
"dependencies": {
"prr": "~1.0.1"
},
"bin": {
"errno": "cli.js"
}
},
"node_modules/error-symbol": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz",
@ -2839,6 +2865,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-what": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
"license": "MIT"
},
"node_modules/is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@ -2919,6 +2951,52 @@
"node": ">=0.10.0"
}
},
"node_modules/less": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/less/-/less-4.2.1.tgz",
"integrity": "sha512-CasaJidTIhWmjcqv0Uj5vccMI7pJgfD9lMkKtlnTHAdJdYK/7l8pM9tumLyJ0zhbD4KJLo/YvTj+xznQd5NBhg==",
"license": "Apache-2.0",
"dependencies": {
"copy-anything": "^2.0.1",
"parse-node-version": "^1.0.1",
"tslib": "^2.3.0"
},
"bin": {
"lessc": "bin/lessc"
},
"engines": {
"node": ">=6"
},
"optionalDependencies": {
"errno": "^0.1.1",
"graceful-fs": "^4.1.2",
"image-size": "~0.5.0",
"make-dir": "^2.1.0",
"mime": "^1.4.1",
"needle": "^3.1.0",
"source-map": "~0.6.0"
}
},
"node_modules/less/node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC",
"optional": true
},
"node_modules/less/node_modules/image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
"integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
"license": "MIT",
"optional": true,
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@ -3030,6 +3108,30 @@
"node": ">=10"
}
},
"node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"license": "MIT",
"optional": true,
"dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/make-fetch-happen": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
@ -3141,6 +3243,19 @@
"node": ">=0.10.0"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"license": "MIT",
"optional": true,
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@ -3428,6 +3543,30 @@
"deprecated": "This module relies on Node.js's internals and will break at some point. Do not use it, and update to graceful-fs@4.x.",
"license": "ISC"
},
"node_modules/needle": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz",
"integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"iconv-lite": "^0.6.3",
"sax": "^1.2.4"
},
"bin": {
"needle": "bin/needle"
},
"engines": {
"node": ">= 4.4.x"
}
},
"node_modules/needle/node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
"license": "ISC",
"optional": true
},
"node_modules/negotiator": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
@ -3702,6 +3841,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/pascalcase": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@ -3727,6 +3875,16 @@
"integrity": "sha512-oQiRXTFeL4KY2IAVuBsaokdEw4+WpKUu8qr/bFyKEpaqpcaflo3M/v5AORXbKxd1liRNtoOEfAV5FRjzrr1jJA==",
"license": "MIT"
},
"node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=6"
}
},
"node_modules/posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -3798,6 +3956,13 @@
"node": ">=10"
}
},
"node_modules/prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
"license": "MIT",
"optional": true
},
"node_modules/pump": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@ -4942,6 +5107,12 @@
"node": ">= 14.0.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",

View File

@ -39,6 +39,7 @@
"handlebars": "^4.7.8",
"handlebars-helpers": "^0.10.0",
"image-size": "^1.1.1",
"less": "^4.2.1",
"lodash": "^4.17.21",
"mime-types": "^2.1.35",
"moment": "^2.30.1",

View File

@ -4,3 +4,4 @@ set -e
bash scripts/generate.sh
bash scripts/build.sh
bash scripts/upload.sh

View File

@ -2,4 +2,14 @@
set -e
source .env
mkdir -p "${WWW}"
mkdir -p "${WWW}/css"
node dist/build
./node_modules/.bin/lessc less/style.less www/css/style.css
cp less/*.svg "${WWW}/css/"

View File

@ -4,9 +4,9 @@ set -e
source .env
rm -rf data/site.db
#rm -rf data/site.db
mkdir -p data
mkdir -p www
mkdir -p "${WWW}"
cat "sql/setup.sql" | sqlite3 "${DB}"

View File

@ -28,5 +28,9 @@ for sizeRaw in ${SIZES[@]}; do
name=${name%.*}
output="${WWW}/img/${ID}_${sizeName}.jpg"
img "${1}" "${output}" "${size}"
if [[ -f "${WWW}/img/${ID}_${sizeName}-1.jpg" ]]; then
mv "${WWW}/img/${ID}_${sizeName}-0.jpg" "${WWW}/img/${ID}_${sizeName}.jpg"
rm "${WWW}/img/${ID}_${sizeName}-1.jpg"
fi
exiftool -overwrite_original -@ "${EXIF}" "${output}"
done

8
scripts/server.sh Normal file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
source .env
cd "${WWW}"
python3 -m http.server

7
scripts/upload.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -e
source .env
rsync -rzdv "${WWW}/" "${DEST}"

View File

@ -1,6 +1,7 @@
CREATE TABLE IF NOT EXISTS photos (
id TEXT PRIMARY KEY,
name TEXT UNIQUE,
description TEXT,
original TEXT UNIQUE,
hash TEXT UNIQUE,
width INTEGER,

View File

@ -3,9 +3,11 @@ import 'dotenv/config';
import { createLog } from './log';
import type { Logger } from 'winston';
import { readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { DB } from './db';
import type { Photo } from './db';
import { envString } from './env';
import { Templates } from './templates';
class Build {
@ -13,20 +15,45 @@ class Build {
private tmpl : Templates;
private db : DB;
private www : string;
constructor () {
this.log = createLog('build');
this.log.info(`Building site: ${new Date()}`);
this.tmpl = new Templates();
this.db = new DB();
this.www = envString('WWW', './www');
this.main();
}
private async main () {
let photos : Photo[];
let html : string;
let data : any = {
title : envString('TITLE', 'Unknown'),
h1 : envString('H1', 'Unknown'),
artist : envString('ARTIST', 'Unknown'),
umami_url : envString('UMAMI_URL', null),
umami_id : envString('UMAMI_ID', null),
year : (new Date()).getFullYear()
};
let home : string = join(this.www, 'index.html');
await this.tmpl.build();
photos = await this.db.getAll();
await this.tmpl.render('index', { photos });
photos = photos.map((photo : Photo) => {
photo.thumbHeight = Math.round((420.0 / photo.width) * photo.height) + 4;
return photo;
})
html = await this.tmpl.render('index', { ...data, photos });
try {
await writeFile(home, html, 'utf8');
this.log.info(`Wrote ${home}`);
} catch (err) {
this.log.error(`Error writing home page`, err);
}
}
}

View File

@ -13,10 +13,12 @@ interface LatLng {
interface Photo {
id : string;
name : string;
description : string;
original? : string;
hash : string;
width : number;
height : number;
thumbHeight? : number;
format? : string;
filmstock? : string;
location? : string;
@ -42,7 +44,7 @@ export class DB {
this.log.info(`DB: ${databaseFile}`);
}
private async run (query : string, args : any[] = null) {
private async run (query : string, args : any[] = []) {
return new Promise((resolve : Function, reject : Function) => {
return this.db.run(query, args, (err : Error, rows : any[]) => {
if (err) return reject(err);
@ -51,7 +53,7 @@ export class DB {
});
}
private async all (query : string, args : any[] = null) : Promise<any[]> {
private async all (query : string, args : any[] = []) : Promise<any[]> {
return new Promise((resolve : Function, reject : Function) => {
return this.db.all(query, args, (err : Error, rows : any[]) => {
if (err) return reject(err);
@ -119,7 +121,7 @@ export class DB {
}
public async getAll () : Promise<Photo[]> {
const query : string = `SELECT * FROM photos;`;
const query : string = `SELECT * FROM photos ORDER BY score ASC, created DESC;`;
let rows : Photo[] = [];
try {
rows = await this.all(query);

View File

@ -53,20 +53,12 @@ class Generate {
this.log.info(`Generating site: ${new Date()}`);
this.db = new DB();
this.s3 = new Files3(envString('S3_BUCKET', 's3bucket'), true);
this.geocode = new Geocode();
this.geocode = new Geocode(this.db);
this.generate();
this.score = args.score;
}
private async generate () {
//check version
//sync
await this.checkInbox();
//validate
}
private async checkInbox () {
private async generate () {
let inbox : string;
let images : string[];
let filename : string;
@ -138,6 +130,7 @@ class Generate {
try {
await this.db.create(photo);
this.log.info(JSON.stringify(photo, null, '\t'));
} catch (err) {
this.log.error(`Error inserting photo into database`, err);
continue;
@ -178,7 +171,7 @@ class Generate {
const filePath : string = await this.mktemp('photosite_exif');
const created : string = moment.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss');
let exif : string = `-Artist=${this.artist}
-ImageTitle=${photo.name}
-Title=${photo.description}
-ImageUniqueId=${photo.id}
-DateTimeOriginal=${created}`
const iso : number[] = photo.filmstock.split(' ').filter(el => this.isOnlyNumbers(el)).map(el => parseInt(el)).filter(el => el > 25);
@ -287,6 +280,7 @@ class Generate {
return {
id : uuid(),
name : basename(image),
description : meta.description,
original: meta.original,
hash,
width : dimensions.width,
@ -313,7 +307,7 @@ class Generate {
const dest : string = join(this.photos, name);
try {
//await rename(image, dest);
await rename(image, dest);
this.log.info(`Moved image ${name} to outbox`);
} catch (err) {
this.log.error(`Error moving image`, err);

View File

@ -7,17 +7,16 @@ import type { Response } from 'node-fetch';
import { createLog } from '../log';
import type { Logger } from 'winston';
import { envString } from '../env';
import { DB } from '../db';
import type { LatLng } from '../db';
import type { DB, LatLng } from '../db';
export class Geocode {
private log : Logger = createLog('geocode');
private baseUrl : string = 'https://geocode.maps.co/search';
private apiKey : string = envString('GEOCODE_API_KEY', null);
private db : DB = new DB();
constructor () {
private db : DB;
constructor (db : DB) {
this.db = db;
}
public async query (location : string) : Promise<LatLng> {
@ -56,6 +55,11 @@ export class Geocode {
return null;
}
if (response.status !== 200) {
this.log.warn(`Invalid response from API [${response.status}]`);
return null;
}
try {
json = await response.json();
} catch (err) {

View File

@ -1,3 +1,3 @@
{{> head}}
{{{body}}}
{{> body }}
{{> foot}}

7
views/partials/body.hbs Normal file
View File

@ -0,0 +1,7 @@
<div id="photos">
{{#each photos}}
{{> photo this}}
{{/each}}
</div>

View File

@ -1,5 +1,5 @@
<script src="/js/script.js"></script>
<script>
</script>
<footer>
<span class="copyleft">&copy;</span> {{year}} {{artist}}
</footer>
</body>
</html>

View File

@ -5,5 +5,30 @@
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>{{title}}</title>
<link href="/css/style.css" rel="stylesheet" />
{{#if umami_url}}
<script async defer data-website-id="{{umami_id}}" src="{{umami_url}}"></script>
{{/if}}
</head>
<body>
<header>
<div id="title">
<h1>{{h1}}</h1>
</div>
<ul>
<li>
<a href="https://sixteenmillimeter.com?ref=mmcwilliams.com" target="_blank" onclick="umami.trackEvent('sixteenmillimeter.com');">16MM</a>
</li>
<li>
<a href="https://git.sixteenmillimeter.com?ref=mmcwilliams.com" target="_blank" onclick="umami.trackEvent('git.sixteenmillimeter.com');">CODE</a>
</li>
<li>
<a href="https://vimeo.com/flashfra" target="_blank" onclick="umami.trackEvent('vimeo');"><img src="/css/vimeo.svg" /></a>
</li>
<li>
<a href="https://github.com/mattmcw" target="_blank" onclick="umami.trackEvent('github');"><img src="/css/github.svg" /></a>
</li>
<li>
<a href="https://bsky.app/profile/flashrame.bsky.social" target="_blank" onclick="umami.trackEvent('bluesky');"><img src="/css/bluesky.svg" /></a>
</li>
</ul>
</header>

View File

@ -1,3 +0,0 @@
<a href="{{full}}">
<img id="{{public_id}}" src="{{home}}" loading="lazy" class="lazy" width="420" alt="{{alt}}" title="{{title}}" />
</a>

4
views/partials/photo.hbs Normal file
View File

@ -0,0 +1,4 @@
<a class="photo" href="/img/{{id}}_full.jpg" target="_blank" onclick="umami.trackEvent('{{id}}');" style="min-height:{{thumbHeight}}px;">
<img id="{{id}}" src="/img/{{id}}_thumb.jpg" loading="lazy" class="lazy" width="420" alt="{{description}}" title="{{description}}" />
</a>