feat: enhance API functionality with new request handling and export methods
This commit is contained in:
@@ -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<T>(URL: string) {
|
||||
export async function requestJSON<T>(URL: string) {
|
||||
const response = await requestRaw(URL);
|
||||
return <T> await response.json();
|
||||
}
|
||||
@@ -62,41 +63,20 @@ async function requestRaw(URL: string) {
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
//List
|
||||
async function getPosts(n: number) {
|
||||
return await requestJSON<ImageResponse[]>(`${postUrl}&limit=${n}`);
|
||||
}
|
||||
|
||||
async function getPostWithID(id: number) {
|
||||
return await requestJSON<ImageResponse[]>(
|
||||
`${postUrl}&id=${encodeURIComponent(id)}`,
|
||||
);
|
||||
}
|
||||
|
||||
async function getPID() {
|
||||
return await requestJSON<ImageResponse[]>(`${postUrl}&pid`);
|
||||
}
|
||||
|
||||
async function getTags(tags: string[]) {
|
||||
const list = tags.join("+");
|
||||
return await requestJSON<ImageResponse[]>(
|
||||
`${postUrl}&tags=${encodeURIComponent(list)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Comments
|
||||
async function getPostComments(postID: number) {
|
||||
export async function getPostComments(postID: number): Promise<CommentResponse[]> {
|
||||
const response = await requestRaw(`${commentsUrl}&post_id=${postID}`);
|
||||
return XMLtoGenericDatatypeParser(response, parseComment);
|
||||
}
|
||||
|
||||
async function getTagByID(id: number) {
|
||||
export async function getTagByID(id: number): Promise<TagResponse[]> {
|
||||
const response = await requestRaw(`${tagUrl}&id=${id}`);
|
||||
return XMLtoGenericDatatypeParser(response, parseTag);
|
||||
}
|
||||
|
||||
async function getTagList(n: number) {
|
||||
export async function getTagList(n: number): Promise<TagResponse[]> {
|
||||
const response = await requestRaw(`${tagUrl}&limit=${n}`);
|
||||
return XMLtoGenericDatatypeParser(response, parseTag);
|
||||
}
|
||||
@@ -151,18 +131,3 @@ async function XMLtoGenericDatatypeParser<T>(
|
||||
}
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
74
src/plugins/rule34/plugin.ts
Normal file
74
src/plugins/rule34/plugin.ts
Normal file
@@ -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<ImageResponse[]>(`${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<ImageResponse[]>(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<PostKeys, string>()
|
||||
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]"))
|
||||
})
|
||||
@@ -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)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user