Fixing all the stuff

This commit is contained in:
Daniel Kluge 2022-05-07 19:08:33 +02:00
parent 3e4e4ef4a9
commit 334f96ac3f
2 changed files with 62 additions and 9 deletions

View File

@ -1,12 +1,11 @@
import fetch from "node-fetch"; import fetch from "node-fetch";
import readline from "readline"; import readline from "readline";
import { exit } from "process";
import { writeFileSync } from "fs"; import { writeFileSync } from "fs";
import { secretsFile, secrets, getToken } from "./common.js"; import { secretsFile, secrets, getToken } from "./common.js";
if (!secrets.refreshToken) { if (!secrets.refreshToken) {
console.error("No refresh token found. Please run 'npm run token' first."); console.error("No refresh token found. Please run 'npm run token' first.");
exit(); process.exit(1);
} }
const rl = readline.createInterface({ const rl = readline.createInterface({

View File

@ -1,26 +1,80 @@
import fetch from "node-fetch"; import fetch from "node-fetch";
import { createWriteStream } from "fs"; import fs from "fs";
import path from "path";
import { secrets, getToken } from "./common.js"; import { secrets, getToken } from "./common.js";
if (!secrets.refreshToken) { if (!secrets.refreshToken) {
console.error("No refresh token found. Please run 'npm run token' first."); console.error("No refresh token found. Please run 'npm run token' first.");
process.exit(1);
} else if (!secrets.album || !secrets.album.id || !secrets.album.count || !secrets.album.name) { } else if (!secrets.album || !secrets.album.id || !secrets.album.count || !secrets.album.name) {
console.error("No valid album found in secrets. Please run 'npm run albums' first."); console.error("No valid album found in secrets. Please run 'npm run albums' first.");
process.exit(1);
} }
// TODO: Check for argument for folder const args = process.argv.slice(2);
// TODO: Create folder and check permissions const argsConfig = {
const path = "./album"; path: args.length > 0 ? args[0] : "./album",
downloadVideo: false, //args.includes("--video") not implemented,
downloadRaw: args.includes("--raw"),
}
argsConfig.path = path.resolve(argsConfig.path);
if (!fs.existsSync(argsConfig.path)) {
try {
fs.mkdirSync(argsConfig.path);
} catch (e) {
console.error("Could not create album directory: ", e);
process.exit(1);
}
} else {
try {
fs.accessSync(argsConfig.path, fs.constants.W_OK);
} catch {
console.error("Album directory is not writable: ", argsConfig.path);
process.exit(1);
}
}
let tokenDeath = 0; let tokenDeath = 0;
let token = ""; let token = "";
const filenameCounter = {};
function shouldDownload(mimeType) {
switch (true) {
case mimeType.startsWith("video/"): return argsConfig.downloadVideo;
case mimeType === "image/raw": return argsConfig.downloadRaw;
case mimeType === "image/jpeg": return true;
case mimeType === "image/png": return true;
default: return false;
}
}
async function syncImage(imageObject) { async function syncImage(imageObject) {
// TODO: Test if file exists if (!shouldDownload(imageObject.mimeType)) return;
if (imageObject.mimeType !== "image/jpeg" && imageObject.mimeType !== "image/png") return;
/*
Problem: Google Photo Albums can have multiple images with the same filename.
We want to preserve the original filename, but we also want to make sure that
each image is only downloaded when necessary.
Solution: We use a counter to keep track of how many times we've downloaded
the same filename. This is only dependend on the sync but not accross syncs.
This want work when the creation time of the images change because Google sorts
images by that. And we can't sort them ourself because "orderBy" needs a
"dateFilter" and that is exclusive with the "albumId"...
*/
const filename = filenameCounter[imageObject.filename] ? `${imageObject.filename.substring(0, imageObject.filename.lastIndexOf("."))}_${filenameCounter[imageObject.filename] + 1}.${imageObject.filename.substring(imageObject.filename.lastIndexOf(".") + 1)}` : imageObject.filename;
filenameCounter[imageObject.filename] = filenameCounter[imageObject.filename] ? filenameCounter[imageObject.filename] + 1 : 1;
const filepath = path.resolve(argsConfig.path, filename);
if (fs.existsSync(filepath)) {
console.log(`Skipping ${filename} (already exists)`);
return
};
const response = await fetch(`${imageObject.baseUrl}=w${imageObject.mediaMetadata.width}-h${imageObject.mediaMetadata.height}`); const response = await fetch(`${imageObject.baseUrl}=w${imageObject.mediaMetadata.width}-h${imageObject.mediaMetadata.height}`);
const fileStream = createWriteStream(`${path}/${imageObject.filename}`); const fileStream = fs.createWriteStream(filepath);
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
response.body.pipe(fileStream); response.body.pipe(fileStream);
response.body.on("error", reject); response.body.on("error", reject);