複数の画像ファイルをGyazoにuploadするscript
2022-09-16
08:57:49 pool()
で複数の画像を一度にuploadする処理を無くした
upload順序を保証するようにしたので、複数の画像を一度にuploadしようとしても、結局は1枚ずつuploadすることになる
2022-09-11
11:45:17 upload順序を保証する
2022-07-26
19:27:14 末尾に連番をつけないようにするoptionを追加した
18:59:34 created
を指定しない
2022-04-21
一部optionを削った
また必要になったら入れる
使用例
localから複数の画像ファイルを指定してuploadし、uploadしたGyazo URLのlistをJSON形式でdownloadする
buildしたコードの
タイトル
を書き換えて実行する
お好みで refererURL
や app
も指定できる
$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/複数の画像ファイルをGyazoにuploadするscript/script.ts
script.tsimport { uploadBulk } from "./upload.ts";
import { useStatusBar } from "jsr:@cosense/std@0.29/browser/dom";
import { upload } from "../scrapbox-file-uploader/mod.ts";
import { isErr, unwrapErr, unwrapOk } from "npm:option-t@50/plain_result";
await (async () => {
const URLs = [] as string[];
const errors = [] as number[];
const { render, dispose } = useStatusBar();
const errorBar = useStatusBar();
const infoBar = useStatusBar();
try {
const fileList = await upload({ accept: "image/jpeg, image/png", multiple: true });
if (!fileList) return;
const compare = new Intl.Collator().compare;
const files = Array.from(fileList)
.sort((a, b) => compare(a.name, b.name));
let counter = 0;
for await (const result of uploadBulk(
files,
{
title: "タイトル",
noIndex: true,
},
)) {
counter++;
if (isErr(result)) {
if (!(unwrapErr(result) instanceof Error)) throw unwrapErr(result);
console.error(unwrapErr(result));
errors.push(counter);
errorBar.render(
{ type: "exclamation-triangle" },
{
type: "text",
text: `${unwrapErr(result)}`,
},
);
continue;
}
const { permalink_url, name, index } = unwrapOk(result);
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.` },
);
const blob = new Blob([JSON.stringify(URLs)], { type: "application/json" });
window.open(URL.createObjectURL(blob));
} finally {
console.log(URLs);
console.log(errors);
setTimeout(() => {
errorBar.dispose();
infoBar.dispose();
dispose();
}, 1000);
}
})();
code
$ deno check --remote -r=https://scrapbox.io https://scrapbox.io/api/code/takker/複数の画像ファイルをGyazoにuploadするscript/upload.ts
upload.tsimport { upload, UploadResult } from "jsr:@takker/gyazo@0.3";
import { getGyazoToken } from "jsr:@cosense/std@0.29/rest";
import { isErr, unwrapErr, unwrapOk, type Result, createErr, createOk } from "npm:option-t@50/plain_result";
export interface UploadOptions {
title?: string;
refererURL?: string;
app?: string;
noIndex?: boolean;
accessToken?: string;
}
export async function* uploadBulk(
images: File[],
uploadOptions?: UploadOptions,
): AsyncGenerator<Result<UploadResult & { index: number; name: string; }, unknown>, void, unknown> {
const { noIndex, accessToken: token, ...options } = uploadOptions ?? {};
// access token取得
const accessToken = token ?? await (async () => {
const result = await getGyazoToken();
if (isErr(result)) throw new Error(JSON.stringify(unwrapErr(result)));
const accessToken = unwrapOk(result);
if (!accessToken) throw new Error("Could not get the access token");
return accessToken;
})();
const zero = (n: number) => `${n}`.padStart(`${images.length}`.length, "0");
// 一枚ずつuploadして返す
for (let index = 0; index < images.length; index++) {
const result = await upload(images[index], {
accessToken,
description: `${images[index].name}${noIndex === true ? "" :` ${zero(index + 1)}`}`,
...options,
});
if (isErr(result)) {
yield createErr(unwrapErr(result));
continue;
}
yield createOk({ index, name: images[index].name, ...unwrapOk(result) });
}
}