From fe4e6690d4e7259ede794628b3266fa3c8d30a66 Mon Sep 17 00:00:00 2001 From: fzzin <43480857+fzzinchemical@users.noreply.github.com> Date: Sun, 30 Mar 2025 04:18:28 +0200 Subject: [PATCH] feat: enhance API functionality with new request handling and export methods --- src/plugins/rule34/api.ts | 51 ++++------------------- src/plugins/rule34/messages.ts | 54 ++++++++----------------- src/plugins/rule34/plugin.ts | 74 ++++++++++++++++++++++++++++++++++ src/plugins/rule34/test.ts | 34 ++++++++++++---- 4 files changed, 125 insertions(+), 88 deletions(-) create mode 100644 src/plugins/rule34/plugin.ts diff --git a/src/plugins/rule34/api.ts b/src/plugins/rule34/api.ts index faedeb7..2cbb4a2 100755 --- a/src/plugins/rule34/api.ts +++ b/src/plugins/rule34/api.ts @@ -1,6 +1,7 @@ +//TODO Add optional extensions like limit at Posts with tags etc. import * as xml_parser from "jsr:@melvdouc/xml-parser"; -type ImageResponse = { +export type ImageResponse = { preview_url: string; sample_url: string; file_url: string; @@ -44,11 +45,11 @@ type TagResponse = { // Define the API URL const baseUrl = "https://api.rule34.xxx"; -const postUrl = `${baseUrl}/index.php?page=dapi&s=post&q=index&json=1`; +export const postUrl = new URL(`${baseUrl}/index.php?page=dapi&s=post&q=index&json=1`); const tagUrl = `${baseUrl}/index.php?page=dapi&s=tag&q=index`; const commentsUrl = `${baseUrl}/index.php?page=dapi&s=comment&q=index`; -async function requestJSON(URL: string) { +export async function requestJSON(URL: string) { const response = await requestRaw(URL); return await response.json(); } @@ -62,41 +63,20 @@ async function requestRaw(URL: string) { } return response; } - //List -async function getPosts(n: number) { - return await requestJSON(`${postUrl}&limit=${n}`); -} - -async function getPostWithID(id: number) { - return await requestJSON( - `${postUrl}&id=${encodeURIComponent(id)}`, - ); -} - -async function getPID() { - return await requestJSON(`${postUrl}&pid`); -} - -async function getTags(tags: string[]) { - const list = tags.join("+"); - return await requestJSON( - `${postUrl}&tags=${encodeURIComponent(list)}`, - ); -} // Comments -async function getPostComments(postID: number) { +export async function getPostComments(postID: number): Promise { const response = await requestRaw(`${commentsUrl}&post_id=${postID}`); return XMLtoGenericDatatypeParser(response, parseComment); } -async function getTagByID(id: number) { +export async function getTagByID(id: number): Promise { const response = await requestRaw(`${tagUrl}&id=${id}`); return XMLtoGenericDatatypeParser(response, parseTag); } -async function getTagList(n: number) { +export async function getTagList(n: number): Promise { const response = await requestRaw(`${tagUrl}&limit=${n}`); return XMLtoGenericDatatypeParser(response, parseTag); } @@ -150,19 +130,4 @@ async function XMLtoGenericDatatypeParser( } } return stack; -} - -Deno.test("Post Comment", async () => { - const response = await getPostComments(1213); - console.debug(response); -}); - -Deno.test("Get Tag by ID", async () => { - const response = await getTagByID(1); - console.debug(response); -}); - -Deno.test("Get Tag List", async () => { - const response = await getTagList(6); - console.debug(response); -}); +} \ No newline at end of file diff --git a/src/plugins/rule34/messages.ts b/src/plugins/rule34/messages.ts index cfc0646..6d0e724 100644 --- a/src/plugins/rule34/messages.ts +++ b/src/plugins/rule34/messages.ts @@ -1,44 +1,22 @@ import { Bot, Message } from "npm:discordeno@18.0.1"; -import { dropRule5, dropRule, refresh } from "./api.ts"; +import { drop, help, requestWorker } from "./plugin.ts"; import { logMessage } from "@root/logging.ts"; import { defaultString } from "@root/defaultString.ts"; export async function rule34MessageHandler(bot: Bot, message: Message) { - const command = message.content.split(" ").slice(1).join(" "); - switch (command) { - case `drop`: - logMessage(message); - if ( - message.channelId === 754338073101205524n || - message.guildId === undefined - ) { - bot.helpers.sendMessage(message.channelId, { - content: defaultString(await dropRule()), - }); - } - break; - case `drop 5`: - logMessage(message); - if ( - message.channelId === 754338073101205524n || - message.guildId === undefined - ) { - bot.helpers.sendMessage(message.channelId, { - content: defaultString(await dropRule5()), - }); - } - break; - case `refresh`: - logMessage(message); - if ( - message.channelId === 754338073101205524n || - message.guildId === undefined - ) { - await refresh(); - bot.helpers.sendMessage(message.channelId, { - content: "Refreshed", - }); - } - break; - } + const command = message.content.trim().split(" ").slice(1).join(" "); + + if (command.startsWith("[") && command.endsWith("]")) { + logMessage(message); + bot.helpers.sendMessage(message.channelId, { + content: defaultString(await requestWorker(command)), + }); + } else if (command === "help") { + logMessage(message); + bot.helpers.sendMessage(message.channelId, { + content: defaultString(help()), + }); + } else { + drop(); + } } diff --git a/src/plugins/rule34/plugin.ts b/src/plugins/rule34/plugin.ts new file mode 100644 index 0000000..3654df1 --- /dev/null +++ b/src/plugins/rule34/plugin.ts @@ -0,0 +1,74 @@ +import { assert } from "@std/assert/assert"; +import {requestJSON, postUrl, ImageResponse} from "./api.ts" + + +const keys = ["limit" , "id" , "pid" , "tags"] as const +type PostKeys = typeof keys[number] + +function isKey(key: string): key is PostKeys { + return keys.includes(key as any); +} + +export async function drop() { + const response = await requestJSON(`${postUrl}&limit=1`) + if (response[0] === undefined) throw Error("Bro, get some sleep") + return response[0].file_url +} + +export async function requestWorker(requestString: string){ + const response = await requestJSON(generateRequestURL(requestString)) + const stack: string[] = [] + for (const img of response) { + stack.push(img.file_url) + } + return stack.join("\n") +} + +//TODO: get help in form of a nice beautiful format +export function help() { + return "WIP" +} + +export function requestParser(requestString: string) { + const res = requestString.match(/\[([\s*w+:\s*[\d+|\w+,]+)\]/g) + const map = new Map() + if (res !== null) { + res[0] + .split(",") + .forEach(param => { + const match = param.match(/\s*(\w+)\s*:\s*([\w+,]+)/) + if (match !== null) { + if (match[1] === undefined || match[2] === undefined) throw Error("Unreachable") + if (!isKey(match[1])) throw Error(`Key: ${match[1]} is not a Key!`) + map.set(match[1], match[2]) + } else { + throw Error(`match returned null in param = ${Deno.inspect(param)}`) + } + }) + } else { + throw Error("Request String had some major issues chief") + } + return map +} + +export function generateRequestURL(requestString: string) { + const postCpy = new URL(postUrl.toString()) + postCpy.search = new URLSearchParams([...postCpy.searchParams, ...requestParser(requestString)]).toString() + return postCpy.toString() +} + +Deno.test("Test Request Parser", () => { + assert(requestParser("[limit: 12,tags:bro+likes+bread]"), '{ "limit" => "12", "tags" => "bro+likes+bread" }') +}) + +Deno.test("Test URL Search Parameters", () => { + console.debug(generateRequestURL("[limit:3]")) +}) + +Deno.test("Test Drop", async() => { + console.debug(await drop()) +}) + +Deno.test("Test Request Workder", async() => { + console.debug(await requestWorker("[limit: 12,tags:sfw]")) +}) diff --git a/src/plugins/rule34/test.ts b/src/plugins/rule34/test.ts index 31203d0..469d8a3 100644 --- a/src/plugins/rule34/test.ts +++ b/src/plugins/rule34/test.ts @@ -1,8 +1,28 @@ -// import { assert } from "jsr:@std/assert"; -// import { dropRule, refresh } from "@root/plugins/rule34/api.ts"; +import { assert } from "jsr:@std/assert"; +import * as api from "@root/plugins/rule34/api.ts" -// Deno.test("Test Drop", async () => { -// await refresh(); -// const link = await dropRule(); -// assert(link !== "", "Empty String was dropped!"); -// }); + +Deno.test("Post Comment", async () => { + const response = await api.getPostComments(1213); + assert(response !== undefined) +}); + +Deno.test("Get Tag by ID", async () => { + const response = await api.getTagByID(1); + assert(response !== undefined) +}); + +Deno.test("Get Post Comments", async () => { + const response = await api.getPostComments(1); + assert(response !== undefined) +}); + +Deno.test("Get Tag by ID 1", async () => { + const response = await api.getTagByID(1); + assert(response !== undefined) +}); + +Deno.test("Get Tag List", async () => { + const response = await api.getTagList(6); + assert(response !== undefined) +});