✅@2022-07-27 山と渓谷を全部Gyazoにuploadする
目的
Gyazoの検索から探せるようにする
やること
すでにuploadしてある号は飛ばす
いいや。重複してても気にせずuploadしてしまおう
重複して何か不便があるわけでもないし
それに本当に画像データが全く同じなら、uploadしても何も起きないはずだし
metadataの更新すらされないのはちょっと困るかもだけど
2014年1月号までuploadしてあるみたい
それ以外をuploadする
2022-07-27
19:46:54 まとめてuploadするdeno scriptを新しく作った
手作業の手間が多い
全ての雑誌を一括してuploadするDeno scriptを組んだほうがいいな。時間の無駄だ。
18:27:58 2015-12までuploadした
09:17:09 2014-12までuploadした
前処理
使ったscriptの都合上、一部乱丁がある
乱丁を直した号から順にuploadしたい
2022-07-27 18:29:04 めんどくさくてやっていない
どうuploadするか
referrerはなしでいいや
ページタイトル
雑誌の名前とページ数だけ載せておこう
特集名まで書くのは大変なのでやらない
uploaderの実装
DenoでCLIを作る
スピナーとupload状況を表示したいな
upload errorが出たら、それも表示する
2022-07-26 18:57:44 おかしい。半分しかuploadされない
created_at
が全く同じだと、uploadに成功してもserver側で保存されないみたい?
created
の指定をやめよう
19:20:37 直ったっぽい!
tsimport { uploadBulk } from "../複数の画像ファイルをGyazoにuploadするscript/upload.ts";
import { useStatusBar } from "../scrapbox-userscript-std/dom.ts";
import { upload } from "../scrapbox-file-uploader/mod.ts";
const main = async () => {
const URLs = [] as string[];
const { render, dispose } = useStatusBar();
const errorBar = useStatusBar();
const infoBar = useStatusBar();
try {
const fileList = await upload({ accept: "*.jpeg, *.png", multiple: true });
if (!fileList) return;
const files = Array.from(fileList)
.sort((a, b) => parseInt(a.name) - parseInt(b.name));
let counter = 0;
const errors = [] as number[];
for await (const result of uploadBulk(
files,
{
title: "『山と渓谷 2014年5月号』",
noIndex: true,
},
)) {
counter++;
if (!result.success) {
if (!(result.reason instanceof Error)) throw result.reason;
console.error(result.reason);
errors.push(counter);
errorBar.render(
{ type: "exclamation-triangle" },
{
type: "text",
text: `${result.reason.name} ${result.reason.message}`,
},
);
continue;
} else {
const { permalink_url, name, index } = result.value;
URLs[index] = permalink_url;
infoBar.render(
{ type: "text", text: `${name} ${permalink_url}` },
);
}
render(
{ type: "spinner" },
{
type: "text",
text: `${files.length} images, ${
counter - errors.length
} uploaded, ${errors.length} failed`,
},
);
}
render(
{ type: "check-circle" },
{ type: "text", text: `Finish uploading.` },
);
console.log(URLs);
console.log(errors);
const blob = new Blob([JSON.stringify(URLs)], { type: "application/json" });
window.open(URL.createObjectURL(blob));
} finally {
setTimeout(() => {
errorBar.dispose();
infoBar.dispose();
dispose();
}, 1000);
}
};
await main();
directory中のすべてのzipファイルから画像を全部Gyazoにuploadし、URLリストをjsonファイルとして保存する
複数の山と渓谷の画像zipを一括uploadする
one commandで実行できるよう作ってある
$ deno run --allow-read --allow-write --allow-net=upload.gyazo.com -r=https://scrapbox.io https://scrapbox.io/api/code/takker/✅@2022-07-27_山と渓谷を全部Gyazoにuploadする/main.ts
$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/✅@2022-07-27_山と渓谷を全部Gyazoにuploadする/main.ts
main.tsimport { uploadBulk } from "../複数の画像ファイルをGyazoにuploadするscript/upload.ts";
import {
basename,
extname,
resolve,
} from "https://deno.land/std@0.122.0/path/mod.ts";
import { readZip } from "https://deno.land/x/jszip@0.11.0/mod.ts";
// directory内の全てのzipを読み込む
const dir = resolve(Deno.cwd(), Deno.args[0]);
console.log(dir);
const name = basename(dir);
if (!(await Deno.stat(dir)).isDirectory) {
throw Error(`"${name}" is not a directory. Specify a directory path.`);
}
for await (const { name: fileName } of Deno.readDir(dir)) {
const path = resolve(dir, fileName);
if (extname(path) !== ".zip") continue;
const zip = await readZip(path);
console.log(`Open ${fileName}`);
const files: File[] = [];
for (const file of zip) {
const blob = await file.async("blob");
files.push(new File([blob], file.name, {
lastModified: file.date.getTime(),
}));
console.log(`Extract ${file.name}`);
}
files.sort((a, b) => parseInt(a.name) - parseInt(b.name));
const [year, date] = fileName.match(/(\d{4})-(\d{2})/)?.slice?.(1) ?? ["", ""];
const title = `『山と渓谷 ${parseInt(year)}年${parseInt(date)}月号』`;
console.log(`Upload ${title}`);
const errors = [] as number[];
let counter = 0;
const URLs = [] as string[];
for await (const result of uploadBulk(
files,
{
title,
noIndex: true,
accessToken: Deno.args[1],
},
)) {
counter++;
if (!result.success) {
if (!(result.reason instanceof Error)) throw result.reason;
console.error(`[${counter}/${files.length}] `, result.reason);
errors.push(counter);
} else {
const { permalink_url, name, index } = result.value;
URLs[index] = permalink_url;
console.log(`[${counter}/${files.length}] ${name} ${permalink_url}`);
}
}
if (errors.length > 0) console.log(errors);
// .zipを削ってファイル名を組み立てる
await Deno.writeTextFile(resolve(dir, `./${fileName.slice(0, -extname(fileName).length)}-gyazo.json`), JSON.stringify(URLs));
}