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_ACCESS_SECRET=""
S3_BUCKET="" S3_BUCKET=""
S3_ENDPOINT="" S3_ENDPOINT=""
UMAMI="" UMAMI_ID=""
UMAMI_URL=""
DB="data/site.db" DB="data/site.db"
ARTIST="Unknown" ARTIST="Unknown"
GEOCODE_API_KEY="" 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 }); Object.defineProperty(exports, "__esModule", { value: true });
require("dotenv/config"); require("dotenv/config");
const log_1 = require("./log"); const log_1 = require("./log");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const db_1 = require("./db"); const db_1 = require("./db");
const env_1 = require("./env");
const templates_1 = require("./templates"); const templates_1 = require("./templates");
class Build { class Build {
constructor() { constructor() {
@ -10,13 +13,35 @@ class Build {
this.log.info(`Building site: ${new Date()}`); this.log.info(`Building site: ${new Date()}`);
this.tmpl = new templates_1.Templates(); this.tmpl = new templates_1.Templates();
this.db = new db_1.DB(); this.db = new db_1.DB();
this.www = (0, env_1.envString)('WWW', './www');
this.main(); this.main();
} }
async main() { async main() {
let photos; 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(); await this.tmpl.build();
photos = await this.db.getAll(); 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(); 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.db.run('PRAGMA journal_mode = WAL;');
this.log.info(`DB: ${databaseFile}`); this.log.info(`DB: ${databaseFile}`);
} }
async run(query, args = null) { async run(query, args = []) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
return this.db.run(query, args, (err, rows) => { return this.db.run(query, args, (err, rows) => {
if (err) if (err)
@ -22,7 +22,7 @@ class DB {
}); });
}); });
} }
async all(query, args = null) { async all(query, args = []) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
return this.db.all(query, args, (err, rows) => { return this.db.all(query, args, (err, rows) => {
if (err) if (err)
@ -89,7 +89,7 @@ class DB {
return exists; return exists;
} }
async getAll() { async getAll() {
const query = `SELECT * FROM photos;`; const query = `SELECT * FROM photos ORDER BY score ASC, created DESC;`;
let rows = []; let rows = [];
try { try {
rows = await this.all(query); 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.log.info(`Generating site: ${new Date()}`);
this.db = new db_1.DB(); this.db = new db_1.DB();
this.s3 = new files3_1.Files3((0, env_1.envString)('S3_BUCKET', 's3bucket'), true); 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.generate();
this.score = args.score; this.score = args.score;
} }
async generate() { async generate() {
//check version
//sync
await this.checkInbox();
//validate
}
async checkInbox() {
let inbox; let inbox;
let images; let images;
let filename; let filename;
@ -108,6 +102,7 @@ class Generate {
} }
try { try {
await this.db.create(photo); await this.db.create(photo);
this.log.info(JSON.stringify(photo, null, '\t'));
} }
catch (err) { catch (err) {
this.log.error(`Error inserting photo into database`, err); this.log.error(`Error inserting photo into database`, err);
@ -147,7 +142,7 @@ class Generate {
const filePath = await this.mktemp('photosite_exif'); const filePath = await this.mktemp('photosite_exif');
const created = moment_1.default.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss'); const created = moment_1.default.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss');
let exif = `-Artist=${this.artist} let exif = `-Artist=${this.artist}
-ImageTitle=${photo.name} -Title=${photo.description}
-ImageUniqueId=${photo.id} -ImageUniqueId=${photo.id}
-DateTimeOriginal=${created}`; -DateTimeOriginal=${created}`;
const iso = photo.filmstock.split(' ').filter(el => this.isOnlyNumbers(el)).map(el => parseInt(el)).filter(el => el > 25); 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 { return {
id: (0, uuid_1.v4)(), id: (0, uuid_1.v4)(),
name: (0, path_1.basename)(image), name: (0, path_1.basename)(image),
description: meta.description,
original: meta.original, original: meta.original,
hash, hash,
width: dimensions.width, width: dimensions.width,
@ -270,7 +266,7 @@ class Generate {
const name = (0, path_1.basename)(image); const name = (0, path_1.basename)(image);
const dest = (0, path_1.join)(this.photos, name); const dest = (0, path_1.join)(this.photos, name);
try { try {
//await rename(image, dest); await (0, promises_1.rename)(image, dest);
this.log.info(`Moved image ${name} to outbox`); this.log.info(`Moved image ${name} to outbox`);
} }
catch (err) { 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 node_fetch_1 = __importDefault(require("node-fetch"));
const log_1 = require("../log"); const log_1 = require("../log");
const env_1 = require("../env"); const env_1 = require("../env");
const db_1 = require("../db");
class Geocode { class Geocode {
constructor() { constructor(db) {
this.log = (0, log_1.createLog)('geocode'); this.log = (0, log_1.createLog)('geocode');
this.baseUrl = 'https://geocode.maps.co/search'; this.baseUrl = 'https://geocode.maps.co/search';
this.apiKey = (0, env_1.envString)('GEOCODE_API_KEY', null); this.apiKey = (0, env_1.envString)('GEOCODE_API_KEY', null);
this.db = new db_1.DB(); this.db = db;
} }
async query(location) { async query(location) {
let res = await this.db.getLocation(location); let res = await this.db.getLocation(location);
@ -47,6 +46,10 @@ class Geocode {
this.log.error('Error getting response', err); this.log.error('Error getting response', err);
return null; return null;
} }
if (response.status !== 200) {
this.log.warn(`Invalid response from API [${response.status}]`);
return null;
}
try { try {
json = await response.json(); 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": "^4.7.8",
"handlebars-helpers": "^0.10.0", "handlebars-helpers": "^0.10.0",
"image-size": "^1.1.1", "image-size": "^1.1.1",
"less": "^4.2.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"moment": "^2.30.1", "moment": "^2.30.1",
@ -1337,6 +1338,18 @@
"license": "ISC", "license": "ISC",
"optional": true "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": { "node_modules/copy-descriptor": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@ -1592,6 +1605,19 @@
"license": "MIT", "license": "MIT",
"optional": true "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": { "node_modules/error-symbol": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz", "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz",
@ -2839,6 +2865,12 @@
"url": "https://github.com/sponsors/ljharb" "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": { "node_modules/is-windows": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@ -2919,6 +2951,52 @@
"node": ">=0.10.0" "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": { "node_modules/lodash": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@ -3030,6 +3108,30 @@
"node": ">=10" "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": { "node_modules/make-fetch-happen": {
"version": "9.1.0", "version": "9.1.0",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
@ -3141,6 +3243,19 @@
"node": ">=0.10.0" "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": { "node_modules/mime-db": {
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "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.", "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" "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": { "node_modules/negotiator": {
"version": "0.6.4", "version": "0.6.4",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
@ -3702,6 +3841,15 @@
"url": "https://github.com/sponsors/sindresorhus" "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": { "node_modules/pascalcase": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@ -3727,6 +3875,16 @@
"integrity": "sha512-oQiRXTFeL4KY2IAVuBsaokdEw4+WpKUu8qr/bFyKEpaqpcaflo3M/v5AORXbKxd1liRNtoOEfAV5FRjzrr1jJA==", "integrity": "sha512-oQiRXTFeL4KY2IAVuBsaokdEw4+WpKUu8qr/bFyKEpaqpcaflo3M/v5AORXbKxd1liRNtoOEfAV5FRjzrr1jJA==",
"license": "MIT" "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": { "node_modules/posix-character-classes": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -3798,6 +3956,13 @@
"node": ">=10" "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": { "node_modules/pump": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
@ -4942,6 +5107,12 @@
"node": ">= 14.0.0" "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": { "node_modules/tunnel-agent": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",

View File

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

View File

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

View File

@ -2,4 +2,14 @@
set -e set -e
source .env
mkdir -p "${WWW}"
mkdir -p "${WWW}/css"
node dist/build 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 source .env
rm -rf data/site.db #rm -rf data/site.db
mkdir -p data mkdir -p data
mkdir -p www mkdir -p "${WWW}"
cat "sql/setup.sql" | sqlite3 "${DB}" cat "sql/setup.sql" | sqlite3 "${DB}"

View File

@ -28,5 +28,9 @@ for sizeRaw in ${SIZES[@]}; do
name=${name%.*} name=${name%.*}
output="${WWW}/img/${ID}_${sizeName}.jpg" output="${WWW}/img/${ID}_${sizeName}.jpg"
img "${1}" "${output}" "${size}" 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}" exiftool -overwrite_original -@ "${EXIF}" "${output}"
done 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 ( CREATE TABLE IF NOT EXISTS photos (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
name TEXT UNIQUE, name TEXT UNIQUE,
description TEXT,
original TEXT UNIQUE, original TEXT UNIQUE,
hash TEXT UNIQUE, hash TEXT UNIQUE,
width INTEGER, width INTEGER,

View File

@ -3,9 +3,11 @@ import 'dotenv/config';
import { createLog } from './log'; import { createLog } from './log';
import type { Logger } from 'winston'; import type { Logger } from 'winston';
import { readFile, writeFile } from 'fs/promises'; import { readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { DB } from './db'; import { DB } from './db';
import type { Photo } from './db'; import type { Photo } from './db';
import { envString } from './env';
import { Templates } from './templates'; import { Templates } from './templates';
class Build { class Build {
@ -13,20 +15,45 @@ class Build {
private tmpl : Templates; private tmpl : Templates;
private db : DB; private db : DB;
private www : string;
constructor () { constructor () {
this.log = createLog('build'); this.log = createLog('build');
this.log.info(`Building site: ${new Date()}`); this.log.info(`Building site: ${new Date()}`);
this.tmpl = new Templates(); this.tmpl = new Templates();
this.db = new DB(); this.db = new DB();
this.www = envString('WWW', './www');
this.main(); this.main();
} }
private async main () { private async main () {
let photos : Photo[]; 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(); await this.tmpl.build();
photos = await this.db.getAll(); 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 { interface Photo {
id : string; id : string;
name : string; name : string;
description : string;
original? : string; original? : string;
hash : string; hash : string;
width : number; width : number;
height : number; height : number;
thumbHeight? : number;
format? : string; format? : string;
filmstock? : string; filmstock? : string;
location? : string; location? : string;
@ -42,7 +44,7 @@ export class DB {
this.log.info(`DB: ${databaseFile}`); 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 new Promise((resolve : Function, reject : Function) => {
return this.db.run(query, args, (err : Error, rows : any[]) => { return this.db.run(query, args, (err : Error, rows : any[]) => {
if (err) return reject(err); 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 new Promise((resolve : Function, reject : Function) => {
return this.db.all(query, args, (err : Error, rows : any[]) => { return this.db.all(query, args, (err : Error, rows : any[]) => {
if (err) return reject(err); if (err) return reject(err);
@ -119,7 +121,7 @@ export class DB {
} }
public async getAll () : Promise<Photo[]> { 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[] = []; let rows : Photo[] = [];
try { try {
rows = await this.all(query); rows = await this.all(query);

View File

@ -53,20 +53,12 @@ class Generate {
this.log.info(`Generating site: ${new Date()}`); this.log.info(`Generating site: ${new Date()}`);
this.db = new DB(); this.db = new DB();
this.s3 = new Files3(envString('S3_BUCKET', 's3bucket'), true); this.s3 = new Files3(envString('S3_BUCKET', 's3bucket'), true);
this.geocode = new Geocode(); this.geocode = new Geocode(this.db);
this.generate(); this.generate();
this.score = args.score; this.score = args.score;
} }
private async generate () { private async generate () {
//check version
//sync
await this.checkInbox();
//validate
}
private async checkInbox () {
let inbox : string; let inbox : string;
let images : string[]; let images : string[];
let filename : string; let filename : string;
@ -138,6 +130,7 @@ class Generate {
try { try {
await this.db.create(photo); await this.db.create(photo);
this.log.info(JSON.stringify(photo, null, '\t'));
} catch (err) { } catch (err) {
this.log.error(`Error inserting photo into database`, err); this.log.error(`Error inserting photo into database`, err);
continue; continue;
@ -178,7 +171,7 @@ class Generate {
const filePath : string = await this.mktemp('photosite_exif'); const filePath : string = await this.mktemp('photosite_exif');
const created : string = moment.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss'); const created : string = moment.unix(photo.created / 1000).format('YYYY:MM:DD HH:mm:ss');
let exif : string = `-Artist=${this.artist} let exif : string = `-Artist=${this.artist}
-ImageTitle=${photo.name} -Title=${photo.description}
-ImageUniqueId=${photo.id} -ImageUniqueId=${photo.id}
-DateTimeOriginal=${created}` -DateTimeOriginal=${created}`
const iso : number[] = photo.filmstock.split(' ').filter(el => this.isOnlyNumbers(el)).map(el => parseInt(el)).filter(el => el > 25); 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 { return {
id : uuid(), id : uuid(),
name : basename(image), name : basename(image),
description : meta.description,
original: meta.original, original: meta.original,
hash, hash,
width : dimensions.width, width : dimensions.width,
@ -313,7 +307,7 @@ class Generate {
const dest : string = join(this.photos, name); const dest : string = join(this.photos, name);
try { try {
//await rename(image, dest); await rename(image, dest);
this.log.info(`Moved image ${name} to outbox`); this.log.info(`Moved image ${name} to outbox`);
} catch (err) { } catch (err) {
this.log.error(`Error moving image`, 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 { createLog } from '../log';
import type { Logger } from 'winston'; import type { Logger } from 'winston';
import { envString } from '../env'; import { envString } from '../env';
import { DB } from '../db'; import type { DB, LatLng } from '../db';
import type { LatLng } from '../db';
export class Geocode { export class Geocode {
private log : Logger = createLog('geocode'); private log : Logger = createLog('geocode');
private baseUrl : string = 'https://geocode.maps.co/search'; private baseUrl : string = 'https://geocode.maps.co/search';
private apiKey : string = envString('GEOCODE_API_KEY', null); private apiKey : string = envString('GEOCODE_API_KEY', null);
private db : DB = new DB(); private db : DB;
constructor () {
constructor (db : DB) {
this.db = db;
} }
public async query (location : string) : Promise<LatLng> { public async query (location : string) : Promise<LatLng> {
@ -56,6 +55,11 @@ export class Geocode {
return null; return null;
} }
if (response.status !== 200) {
this.log.warn(`Invalid response from API [${response.status}]`);
return null;
}
try { try {
json = await response.json(); json = await response.json();
} catch (err) { } catch (err) {

View File

@ -1,3 +1,3 @@
{{> head}} {{> head}}
{{{body}}} {{> body }}
{{> foot}} {{> 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> <footer>
<script> <span class="copyleft">&copy;</span> {{year}} {{artist}}
</script> </footer>
</body> </body>
</html> </html>

View File

@ -5,5 +5,30 @@
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>{{title}}</title> <title>{{title}}</title>
<link href="/css/style.css" rel="stylesheet" /> <link href="/css/style.css" rel="stylesheet" />
{{#if umami_url}}
<script async defer data-website-id="{{umami_id}}" src="{{umami_url}}"></script>
{{/if}}
</head> </head>
<body> <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>