197 lines
5.6 KiB
JavaScript
197 lines
5.6 KiB
JavaScript
process.on("unhandledRejection", error => console.error(error.stack));
|
|
require("dotenv").config();
|
|
var Discord = require("discord.js");
|
|
var puppeteer = require("puppeteer");
|
|
var fetch = require("node-fetch");
|
|
var exitHook = require('async-exit-hook');
|
|
|
|
|
|
var browser;
|
|
puppeteer.launch({
|
|
headless: !Boolean(process.env.INIT),
|
|
userDataDir: process.cwd() + "/chromium_data"
|
|
}).then(x => {
|
|
browser = x;
|
|
exitHook(cb => browser.close().then(cb))
|
|
});
|
|
|
|
|
|
|
|
var client = new Discord.Client({intents: 32767, restRequestTimeout: 10*60*1000});
|
|
client.login(process.env.TOKEN);
|
|
client.once("ready", () => {
|
|
client.guilds.resolve("672956423545815040").commands.set([
|
|
{
|
|
name: "dump",
|
|
description: "Dump popular results of a Pixiv tag",
|
|
options: [
|
|
{
|
|
name: "tag",
|
|
description: "Pixiv tag",
|
|
type: "STRING",
|
|
required: true
|
|
}
|
|
]
|
|
}
|
|
]);
|
|
});
|
|
|
|
client.on("interactionCreate", async i => {
|
|
if (i.isCommand() && i.commandName == "dump") {
|
|
if (i.channel.id != "889598863944609882") return i.reply({content: "in <#889598863944609882> only pls", ephemeral: true});
|
|
|
|
let tag = i.options.getString("tag");
|
|
if (!tag) return i.reply({content: "bruh no tag", ephemeral: true});
|
|
|
|
let reply = await i.reply({content: `${i.user} started Pixiv dump for tag **${tag}**`, fetchReply: true});
|
|
let thread = await reply.startThread({name: tag, autoArchiveDuration: 'MAX'});
|
|
dump(tag, thread);
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function dump(tag, thread) {
|
|
try {
|
|
var page_number = 1;
|
|
var page = await browser.newPage();
|
|
|
|
let sefg8uyaogse8ygiluahrgihseiufhguisdg = true;
|
|
let lastpagefirstpostid;
|
|
|
|
// for each page of search
|
|
while (true) {
|
|
let url = `https://www.pixiv.net/ajax/search/artworks/${encodeURIComponent(tag)}?order=popular_d&mode=all&p=${page_number}`;
|
|
console.log(`p get ${url}`);
|
|
await page.goto(url);
|
|
let data = JSON.parse(await page.evaluate(() => document.querySelector("body").innerText));
|
|
if (data.error) throw data.message;
|
|
|
|
if (data.body.illustManga.data.length == 0) {
|
|
await thread.send(`No data on next page. Abort.`);
|
|
break;
|
|
}
|
|
|
|
if (sefg8uyaogse8ygiluahrgihseiufhguisdg) { await thread.send(`${data.body.illustManga.total?.toLocaleString()} works`); sefg8uyaogse8ygiluahrgihseiufhguisdg = false; }
|
|
|
|
if (data.body.illustManga.data[0].id == lastpagefirstpostid) {
|
|
await thread.send("It appears the next page has the same data, so I guess I've reached the end.\n\nAbort.");
|
|
break;
|
|
} else lastpagefirstpostid = data.body.illustManga.data[0].id;
|
|
|
|
|
|
// for each post on page
|
|
for (let i = 0; i < data.body.illustManga.data.length; i++) {
|
|
let item = data.body.illustManga.data[i];
|
|
let post_url = `https://www.pixiv.net/en/artworks/${item.id}`;
|
|
try {
|
|
|
|
let url = `https://www.pixiv.net/ajax/illust/${item.id}/pages`;
|
|
console.log(`p get ${url}`);
|
|
await page.goto(url);
|
|
let data = JSON.parse(await page.evaluate(() => document.querySelector("body").innerText));
|
|
if (data.error) throw data.message;
|
|
let attachments = [];
|
|
|
|
// for each image on post
|
|
for (let image of data.body) {
|
|
let url = image.urls.original;
|
|
console.log(`f get ${url}`);
|
|
|
|
attachments.push({
|
|
attachment: await (await fetch(url, {
|
|
headers: { "Referer": "https://www.pixiv.net" }
|
|
})).buffer(),
|
|
name: (item.xRestrict ? "SPOILER_" : '') + url.split('/').pop(),
|
|
x: image
|
|
});
|
|
}
|
|
|
|
// chunk for posts with more than 10 images
|
|
let chunked_attachments = chunkArray(attachments, 10);
|
|
let m = `**${item.alt}**\n<${post_url}>`
|
|
|
|
// if all chunks small enough send in fewest messages
|
|
console.log("uploading");
|
|
if (chunked_attachments.some(x => {
|
|
let totalsize = 0;
|
|
x.forEach(x => totalsize += x.attachment.length);
|
|
return totalsize < 50000000 // 8000000 if not boost lvl 2
|
|
})) {
|
|
for (let i = 0; i < chunked_attachments.length; i++) {
|
|
await thread.send({
|
|
content: i == 0 ? m : undefined,
|
|
files: chunked_attachments[i]
|
|
});
|
|
}
|
|
}
|
|
|
|
// else send each image separate message
|
|
else {
|
|
for (let i = 0; i < attachments.length; i++) {
|
|
let attachment = attachments[i]
|
|
try {
|
|
await thread.send({
|
|
content: i == 0 ? m : undefined,
|
|
files: [attachment]
|
|
});
|
|
} catch (error) {
|
|
await thread.send(`for ${attachment.x.urls.original} (page ${page_number} item ${i}:): \`\`\`\n${error.stack}\n\`\`\``);
|
|
// if too large try the regular edition
|
|
if (error.message == "Request entity too large") {
|
|
await thread.send(`trying regular size instead`);
|
|
let url = attachment.x.urls.regular;
|
|
console.log(`f get 2 ${url}`);
|
|
try {
|
|
await thread.send({files:[{
|
|
attachment: (await fetch(url, {headers:{"Referer":"https://www.pixiv.net"}})).buffer(),
|
|
name: (item.xRestrict ? "SPOILER_" : '') + url.split('/').pop()
|
|
}]});
|
|
} catch (err0r) {
|
|
await thread.send(`still: ${err0r.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
// error for post
|
|
await thread.send(`for <${post_url}>:\n\`\`\`\n${error.stack || error}\n\`\`\``);
|
|
}
|
|
|
|
}
|
|
page_number++;
|
|
}
|
|
} catch (error) {
|
|
// error on this dump
|
|
await thread.send(`\`\`\`\n${error.stack || error}\n\`\`\`\n\nAborted.`);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function chunkArray(array, n) {
|
|
return array.reduce((resultArray, item, index) => {
|
|
const chunkIndex = Math.floor(index/n)
|
|
if(!resultArray[chunkIndex]) {
|
|
resultArray[chunkIndex] = []
|
|
}
|
|
resultArray[chunkIndex].push(item)
|
|
return resultArray
|
|
}, [])
|
|
} |