211 lines
5.6 KiB
TypeScript
211 lines
5.6 KiB
TypeScript
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<Array<booru_post>> {
|
|
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<string>((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<booru_post>( 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<Array<booru_post>> {
|
|
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<string>((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<booru_post>( 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<string>((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<booru_post>( 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;
|
|
}
|
|
|
|
export type danbo_artist = {
|
|
id: number,
|
|
name: string,
|
|
is_banned: bool,
|
|
urls: Array<danbo_artist_url>
|
|
}
|
|
|
|
type danbo_artist_url = {
|
|
url:string,
|
|
is_active:bool
|
|
}
|
|
|
|
export async function danbo_artist_search(tweet_username:string) : Promise<danbo_artist> {
|
|
const artist_api = `${DANBOORU_API}/artists.json`
|
|
const tweet_url = `https://twitter.com/${tweet_username}`;
|
|
|
|
const artists_url = new URL(artist_api);
|
|
artists_url.searchParams.append("search[url_matches]",tweet_url);
|
|
artists_url.searchParams.append("only","id,name,urls,is_banned");
|
|
|
|
const booru_request = new Promise<string>((res,rej) => {
|
|
GM_xmlhttpRequest({
|
|
url: artists_url.toString(),
|
|
method:'GET',
|
|
responseType: 'json',
|
|
anonymous:true,
|
|
onload: (response) => res(response.responseText),
|
|
onerror: (error) => rej(error)
|
|
})
|
|
})
|
|
|
|
const response = await booru_request
|
|
const artists : danbo_artist[] = JSON.parse(response);
|
|
let artist = artists.shift();
|
|
|
|
if ( artist ) artist.urls = artist.urls.filter(x =>
|
|
x.is_active &&
|
|
!( x.url.includes("twitter.com/intent/") || x.url.includes("pixiv.net/stacc/")));
|
|
|
|
return artist
|
|
}
|