import { GM_getValue, GM_xmlhttpRequest } from 'vite-plugin-monkey/dist/client'; export const DANBOORU_API = "https://danbooru.donmai.us" const SAUCENAO_KEY = "debugging only" export type booru_post = { id: number, timestamp: string, source_domain: string, thumbnail: string, img_width: number, img_height: number } export async function tweet_search(id:string,username:string) : Promise> { const posts_api = `${DANBOORU_API}/posts.json` const tweet_url = `https://twitter.com/${username}/status/${id}`; const posts_url = new URL(posts_api); posts_url.searchParams.append('tags',`status:any source:${tweet_url}`); posts_url.searchParams.append('limit',`5`); const booru_request = new Promise((res,rej) => { GM_xmlhttpRequest({ url: posts_url.toString(), method:'GET', responseType: 'json', anonymous:true, onload: (response) => res(response.responseText), onerror: (error) => rej(error) }) }) const response = await booru_request const posts:any[] = JSON.parse(response) //console.debug({grape:posts}) const result = posts.map( post => { const preview = post.media_asset.variants?.find( (v:any) => v.type=="preview" || v.type=="180x180") const source_domain = new URL(post.source).hostname return { id: post.id, timestamp: post.created_at, source_domain: source_domain, thumbnail: preview?.url, img_width: post.image_width, img_height: post.image_height } }) return result } export async function iqdb_search(media_url:string) : Promise> { const iqdb_api = `${DANBOORU_API}/iqdb_queries.json` const iqdb_url = new URL(iqdb_api); iqdb_url.searchParams.append('url',media_url); iqdb_url.searchParams.append('similarity','80'); iqdb_url.searchParams.append('limit','5'); const booru_request = new Promise((res,rej) => { GM_xmlhttpRequest({ url: iqdb_url.toString(), method:'GET', responseType: 'json', anonymous:true, onload: (response) => res(response.responseText), onerror: (error) => rej(error) }) }) const response = await booru_request const iqdb_res = JSON.parse(response) as any[] const result = iqdb_res.map( i => { const post = i.post; const preview = post.media_asset.variants?.find( (v:any) => v.type=="preview" || v.type=="180x180") const source_domain = new URL(post.source).hostname return { id: post.id, timestamp: post.created_at, source_domain: source_domain, thumbnail: preview?.url, img_width: post.image_width, img_height: post.image_height } }) return result } type sauce_response = { header: any, results: sauce_item[] } type sauce_item = { header: { similarity : string, thumbnail : string }, data: { danbooru_id: number, source: string } } export async function saucenao_search(media_url:string) { const saucenao_key = GM_getValue('DunkOatmeal_SNKey',''); if ( !saucenao_key ) { alert("SauceNAO API required. \nGo to Profile Menu > Settings to add it.") return [] } const danbo_bm = 0b1000000000; //const pixiv_bm = 0b0000100000; const bitmask = danbo_bm //| pixiv_bm; const min_similarity = 80 const sauce_api = `http://saucenao.com/search.php`; const sauce_url = new URL(sauce_api); sauce_url.searchParams.append('numres','5'); sauce_url.searchParams.append('output_type','2'); sauce_url.searchParams.append('dbmask',String(bitmask)); sauce_url.searchParams.append('api_key',saucenao_key); sauce_url.searchParams.append('url',media_url); const booru_request = new Promise((res,rej) => { GM_xmlhttpRequest({ url: sauce_url.toString(), method:'GET', responseType: 'json', anonymous:true, onload: (response) => res(response.responseText), onerror: (error) => rej(error) }) }) const response = await booru_request const sauce_res:sauce_response = JSON.parse(response) console.debug({sauce:sauce_res}) const result = sauce_res.results .filter(x => Number(x.header.similarity) >= min_similarity ) .map( s => { const danbo = s.data; const preview = s.header.thumbnail; const source_domain = new URL(danbo.source).hostname return { id: danbo.danbooru_id, timestamp: "", source_domain: source_domain, thumbnail: preview, img_width: -1, img_height: -1 } }) return result; }