Files
update_ts/update_ts.mjs
2024-02-18 15:00:07 +01:00

80 lines
1.8 KiB
JavaScript

import fs from "fs/promises";
import ExifReader from "exifreader";
import path from "path";
if (process.argv.length === 2) {
console.error("Expected exactly one argument");
process.exit(1);
}
const dir = process.argv[2];
let fileNames;
try {
fileNames = await fs.readdir(dir);
} catch (error) {
console.error("Error reading directory.", error);
process.exit(2);
}
/**
* @param fileName {string}
* @return {Date|null}
*/
function getDateFromFileName(fileName) {
const r = /(\d{4})-?(\d{2})-?(\d{2})[_\-](\d{2})-?(\d{2})-?(\d{2})/.exec(
fileName,
);
if (!r) throw new Error("The file name did not match the pattern.");
return new Date(`${r[1]}-${r[2]}-${r[3]}T${r[4]}:${r[5]}:${r[6]}`);
}
/**
* @param filePath {string}
* @param fileName {string}
* @return {Promise<Date|null>}
*/
async function getDate(filePath, fileName) {
if (/\.mp4$/.test(fileName)) {
return getDateFromFileName(fileName);
}
const tags = await ExifReader.load(filePath);
let timeString = tags.DateTime?.value[0];
if (timeString === undefined) {
return getDateFromFileName(fileName);
}
const exifDate = new Date(
timeString.replace(
/(\d{4}):(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})/,
"$1-$2-$3T$4:$5:$6",
),
);
if (isNaN(exifDate.getTime()) || exifDate.getFullYear() < 2000) {
return getDateFromFileName(fileName);
}
return exifDate;
}
for (const fileName of fileNames) {
const filePath = path.resolve(dir, fileName);
let date;
try {
date = await getDate(filePath, fileName);
} catch (error) {
console.error(filePath, error.message);
continue;
}
if (date === null) {
console.error(filePath, "Could not get a date.");
continue;
}
console.log(filePath, date);
await fs.utimes(filePath, date, date);
}