From 30b0adcacef48ac53aea13cbdc3288db0bd8d103 Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sun, 17 Oct 2021 16:54:53 +0200 Subject: Init --- src/api/e621/index.ts | 50 ++++++++++++++++++++++++++++++++++++++++ src/api/mastodon/index.ts | 58 +++++++++++++++++++++++++++++++++++++++++++++++ src/api/misskey/index.ts | 26 +++++++++++++++++++++ src/config.ts | 34 +++++++++++++++++++++++++++ src/index.ts | 36 +++++++++++++++++++++++++++++ 5 files changed, 204 insertions(+) create mode 100644 src/api/e621/index.ts create mode 100644 src/api/mastodon/index.ts create mode 100644 src/api/misskey/index.ts create mode 100644 src/config.ts create mode 100644 src/index.ts (limited to 'src') diff --git a/src/api/e621/index.ts b/src/api/e621/index.ts new file mode 100644 index 0000000..6aa6a35 --- /dev/null +++ b/src/api/e621/index.ts @@ -0,0 +1,50 @@ +import got from "got"; +import config from "../../config"; + +export interface Post { + id: number; + file: { + url: string; + }; + sources: readonly string[]; + + tags: { + general: readonly string[]; + species: readonly string[]; + character: readonly string[]; + copyright: readonly string[]; + artist: readonly string[]; + invalid: readonly string[]; + lore: readonly string[]; + meta: readonly string[]; + }; +} + +export const client = got.extend({ + headers: { + "User-Agent": config.e621.userAgent, + }, +}); + +export async function randomPost() { + const page = Math.floor(Math.random() * (config.e621.maxPage - 1)) + 1; + + const response = await client + .get("https://e926.net/posts.json", { + searchParams: { + limit: 75, + page, + tags: config.e621.tags.join(" "), + }, + }) + .json<{ posts: readonly Post[] }>(); + + if (!response.posts.length) { + throw new Error("No posts received"); + } + + const postIndex = Math.floor(Math.random() * response.posts.length); + const post = response.posts[postIndex]; + + return post; +} diff --git a/src/api/mastodon/index.ts b/src/api/mastodon/index.ts new file mode 100644 index 0000000..2d8636e --- /dev/null +++ b/src/api/mastodon/index.ts @@ -0,0 +1,58 @@ +import got from "got"; +import FormData from "form-data"; +import fileType from "file-type"; +import { nanoid } from "nanoid"; +import config from "../../config"; + +export interface Attachment { + id: string; +} + +export interface Status { + url: string; +} + +export const client = got.extend({ + prefixUrl: config.mastodon.instance, + headers: { + Authorization: `Bearer ${config.mastodon.token}`, + }, +}); + +export async function upload(buf: Buffer, filename: string) { + const type = await fileType.fromBuffer(buf); + + const body = new FormData(); + body.append("i", config.mastodon.token); + body.append("file", buf, { filename: `${filename}.${type.ext}`, contentType: type.mime }); + + return client.post("api/v1/media", { body }).json(); +} + +export async function createStatus( + postUrl: string, + sourceUrl: string | undefined, + spoiler: string[], + attachmentId: string +) { + let lines = [postUrl]; + if (sourceUrl) { + lines.push(`Source: ${sourceUrl}`); + } + + const spoilerText = spoiler.length ? `CW: ${spoiler.join(", ")}` : undefined; + + return client + .post("api/v1/statuses", { + headers: { + "Idempotency-Key": nanoid(), + }, + json: { + status: lines.join("\n"), + media_ids: [attachmentId], + sensitive: true, + spoiler_text: spoilerText, + }, + }) + .json(); +} diff --git a/src/api/misskey/index.ts b/src/api/misskey/index.ts new file mode 100644 index 0000000..64bfe67 --- /dev/null +++ b/src/api/misskey/index.ts @@ -0,0 +1,26 @@ +/* +import got from "got"; +import FormData from "form-data"; +import stream from "stream"; +import config from "../../config"; + +export interface DriveFile { + id: string; +} + +export const client = got.extend({ + prefixUrl: config.misskey.instance, +}); + +export function upload(buf: Buffer, filename: string) { + const body = new FormData(); + body.append("i", config.misskey.token); + body.append("file", buf, { filename }); + + return client.post("drive/files/create", { body }).json(); +}; + +export function createNote() { + +} +*/ diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..f051888 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,34 @@ +export default { + e621: { + userAgent: "@feralbot@botsin.space (by RedFoxxo)", + tags: [ + "feral", + "-anthro", + "-human", + "-meme", + "-humor", + "-photography_(artwork)", + "-portrait", + "-comic", + "-saliva", + "-friendship_is_magic", + "-my_little_pony", + "-type:swf", + "-type:webm", + "-type:gif", + "status:active", + "score:>=20", + "inpool:false", + ], + maxPage: 131, + }, + /*misskey: { + instance: "https://mk.vulpes.one/", + token: process.env.MISSKEY_TOKEN, + },*/ + mastodon: { + instance: "https://botsin.space/", + token: process.env.MASTODON_TOKEN, + }, + cw: ["gun"], +}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..7185e23 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,36 @@ +import * as e621 from "./api/e621"; +import * as mastodon from "./api/mastodon"; +import config from "./config"; + +(async () => { + console.log("Fetching post..."); + + const post = await e621.randomPost(); + const source = post.sources.length ? post.sources[0] : undefined; + const cws = config.cw.filter((w) => post.tags.general.includes(w)); + + console.log(`Got ${post.id}`); + console.log(`Downloading image...`); + + const file = await e621.client.get(post.file.url).buffer(); + + /*console.log(`Compressing...`); + + const compressedFile = await sharp(file) + .resize(1000, 1000, { + fit: "inside", + withoutEnlargement: true, + }) + .jpeg({ quality: 85, mozjpeg: true }) + .toBuffer();*/ + + console.log(`Uploading...`); + + const attachment = await mastodon.upload(file, post.id.toString(10)); + + console.log(`Posting status...`); + + const status = await mastodon.createStatus(`https://e926.net/posts/${post.id}`, source, cws, attachment.id); + + console.log(`Done! ${status.url}`); +})(); -- cgit v1.2.3-70-g09d2