export var credentials = JSON.parse(Deno.readTextFileSync("credentials.json")); var {client_id, client_secret, username, password, pixiv_cookie, access_token} = credentials; export var known_ids = {}; try { known_ids = Object.fromEntries(Deno.readTextFileSync("known_ids.csv").trim().split("\n").map(line => line.split(","))); } catch (e) {} if (!access_token) { let form = new FormData(); form.append("client_id", client_id); form.append("client_secret", client_secret); form.append("grant_type", "password"); form.append("username", username); form.append("password", password); let data = await fetch("https://pleroma.lamp.wtf/oauth/token", { method: "POST", body: form }).then(res => res.json()); console.log ("logged in", data); credentials.access_token = access_token = data.access_token; Deno.writeTextFileSync("credentials.json", JSON.stringify(credentials, null, '\t')); } async function uploadFile({data, name}) { var form = new FormData(); form.append("file", data, name); var res = await fetch("https://pleroma.lamp.wtf/api/v1/media", { method: "POST", body: form, headers: {"Authorization": `Bearer ${access_token}`} }); if (!res.ok) throw new Error("HTTP " + res.status); var json = await res.json(); console.log("uploaded file", res.status, json.url); return json; } async function postStatus({status, visibility = "unlisted", content_type = "text/plain", media_ids = [], sensitive, files}) { if (files) { media_ids = (await Promise.all(files.map(file => uploadFile(file)))).map(d => d.id); } var form = new FormData(); form.append("status", status); form.append("visibility", visibility); form.append("source", "bot"); form.append("content_type", content_type); for (let media_id of media_ids) { form.append("media_ids[]", media_id); } if (sensitive) form.append("sensitive", "true"); var res = await fetch("https://pleroma.lamp.wtf/api/v1/statuses", { method: "POST", body: form, headers: {"Authorization": `Bearer ${access_token}`} }); if (!res.ok) throw new Error("HTTP " + res.status); var json = await res.json(); console.log("posted", res.status, json.uri || json); return json; } async function downloadPixivIllust(illust_id) { var url = `https://www.pixiv.net/en/artworks/${illust_id}`; console.log("fetch", url); var res = await fetch(url, {headers: {"Cookie": pixiv_cookie}}); if (!res.ok) throw new Error("HTTP " + res.status); var html = await res.text(); var illust = Object.values(JSON.parse(html.match(//)[1]).illust)[0]; try { let u = `https://www.pixiv.net/ajax/illust/${illust_id}/pages`; console.log("fetch", u); let res = await fetch(u, {headers: {"Cookie": pixiv_cookie}}); if (!res.ok) throw new Error("HTTP " + res.status); let json = await res.json(); var images = json.body.map(x => ({ url: x.urls.original, width: x.width, height: x.height })); } catch (error) { console.error(error.stack); var images = []; for (let i = 0; i < illust.pageCount; i++) { images.push({ url: illust.urls.original.replace('p0', 'p'+i) }); } } for (let image of images) { image.name = image.url.split('/').pop(); console.log("fetch", image.url); image.data = await fetch(image.url, {headers: {"Referer": "https://www.pixiv.net/"}}).then(res => res.blob()); }; return {illust, images}; } export async function pixivToPleroma(illust_id) { try { var {illust, images} = await downloadPixivIllust(illust_id); var {url} = await postStatus({ status: `https://www.pixiv.net/en/artworks/${illust_id}` + ((images.length > 4) ? `\n⚠ There are ${images.length} attachments` : '') + ((illust.illustType == 2) ? '\n⚠ ugoira conversion not implemented, view on Pixiv' : ''), files: images, visibility: "unlisted", sensitive: Boolean(illust.xRestrict) }); Deno.writeTextFileSync("known_ids.csv", `${illust_id},${url}\n`, {append: true}); var {postPixivIllustToMatrix} = await import("./matrix.js"); //circular dependency -.- await postPixivIllustToMatrix(illust, images, url); } catch (error) { console.error(error.stack); postStatus({ status: `https://www.pixiv.net/en/artworks/${illust_id}` + `\n#error:\n${error.stack}` }); } }