koishi-plugin-pixluna
Version:
5 lines • 37 kB
JavaScript
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`koishi`),l=require(`wasm-vips`);l=s(l);let u=require(`node:crypto`);const d={};let f=-1;function p(e,t=`pixluna`){let n=d[t]||e.logger(t);return f>=0&&(n.level=f),d[t]=n,n}function m(e){for(let t in f=e,d)d[t].level=e}var h=class{pool;limit;constructor(e){this.pool=[],this.limit=e}add(e){let t=Array.isArray(e)?e:[e];for(let e of t)this.pool.push(e);return this}async run(){let e=[];for(let t=0;t<this.pool.length;t+=this.limit){let n=this.pool.slice(t,t+this.limit);e.push(...await Promise.all(n))}return e}};async function g(e,t,n){return await n()}async function _(e){if(e.length<12)return null;if(e[0]===255&&e[1]===216&&e[2]===255)return`image/jpeg`;if(e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71)return`image/png`;if(e[0]===71&&e[1]===73&&e[2]===70)return`image/gif`;if(e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80)return`image/webp`;if(e[0]===66&&e[1]===77)return`image/bmp`;if(e.length>=12){let t=e.slice(4,12).toString(`ascii`);if(t===`ftypavif`||t===`ftypavis`)return`image/avif`}return null}const v=(0,l.default)({dynamicLibraries:[]}).then(e=>(e.concurrency(1),e.Cache.max(0),e));let y=null;async function b(){return y||=await v,y}function ee(e){return Math.max(0,Math.min(9,e.imageProcessing.compressionLevel??6))}function x(e){switch(e){case`horizontal`:return 1;case`vertical`:return 2;case`both`:return 3;default:return 0}}async function S(e,t,n,r){let i=await b(),a=null,o=[];try{a=i.Image.newFromBuffer(t);let e=a;if(n.imageProcessing.isFlip){let t=x(n.imageProcessing.flipMode);if(t===1){let t=e.flipHor();o.push(t),e=t}else if(t===2){let t=e.flipVer();o.push(t),e=t}else if(t===3){let t=e.flipHor();o.push(t);let n=t.flipVer();o.push(n),e=n}}if(n.imageProcessing.confusion){let t=Math.floor(Math.random()*e.width),n=Math.floor(Math.random()*e.height),r=e.getpoint(t,n);for(let e=0;e<r.length;e++)r[e]+=r[e]<255?1:-1;let a=i.Image.black(1,1);o.push(a);let s=a.newFromImage(r);o.push(s);let c=e.insert(s,t,n);o.push(c),e=c}let r=ee(n),s=e.writeToBuffer(`.png`,{compression:r});return Buffer.from(s)}catch(n){return e.logger?.warn?.(`processImage: decode failed, return original buffer`,{err:n}),t}finally{for(let e=o.length-1;e>=0;e--)o[e]?.[Symbol.dispose]?.();a&&a[Symbol.dispose]?.()}}function C(e){if(e.length<=1)return[...e];let t=[...e],n=new Uint32Array(t.length);u.webcrypto.getRandomValues(n);for(let e=t.length-1;e>0;e--){let r=n[e]%(e+1);[t[e],t[r]]=[t[r],t[e]]}return t}const w=`__PIXLUNA_PROVIDERS__`;function T(){let e=globalThis;return e[w]||(e[w]=new Map),e[w]}function E(e,t){let n=T(),r=Array.isArray(e)?e:[e];for(let e of r){let r=String(e).trim();if(!r)continue;let i=n.get(r);(!i||i!==t)&&n.set(r,t)}}function D(e){return T().get(e)}function O(){let e=T();return Array.from(e.keys())}var k=class{static description;config;ctx;constructor(e,t){this.ctx=e,this.config=t}},te=class extends k{static description=`通过 Danbooru API 获取图片`;endpoint=`https://danbooru.donmai.us`;keyPairs=[];setConfig(e){this.config=e,e.danbooru?.keyPairs?.length&&(this.keyPairs=e.danbooru.keyPairs)}get keyPair(){return this.keyPairs.length?this.keyPairs[Math.floor(Math.random()*this.keyPairs.length)]:null}async getMetaData({context:e},t){try{let n=this.keyPair,r=``;t.tag&&(r=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let i={tags:r,random:!0,limit:1,...n?{login:n.login,api_key:n.apiKey}:{}};this.config.isR18&&t.r18?i.tags+=` rating:explicit`:i.tags+=` rating:safe`;let a=await e.http.get(`${this.endpoint}/posts.json`,{params:i,proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(a)||a.length===0)return{status:`error`,data:Error(`No image data returned`)};let o=a[0],s=this.config.imageProcessing.compress?o.large_file_url:o.file_url,c={id:o.id,title:``,author:o.tag_string_artist.replace(/_/g,` `),r18:o.rating===`e`||o.rating===`q`,tags:o.tag_string.split(` `),extension:o.file_url.split(`.`).pop(),aiType:0,uploadDate:new Date(o.created_at).getTime(),urls:{original:o.file_url,regular:o.large_file_url}};return $.debug(`成功获取图片元数据`,{metadata:c}),{status:`success`,data:{url:s,urls:{regular:o.large_file_url,original:o.file_url},raw:c}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://danbooru.donmai.us`}}};E(`danbooru`,te);var ne=class extends k{static description=`通过 E621 API 获取图片`;endpoint=`https://e621.net`;keyPairs=[];setConfig(e){this.config=e,e.e621?.keyPairs?.length&&(this.keyPairs=e.e621.keyPairs)}get keyPair(){return this.keyPairs.length?this.keyPairs[Math.floor(Math.random()*this.keyPairs.length)]:null}async getMetaData({context:e},t){try{let n=this.keyPair,r=``;t.tag&&(r=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let i={tags:`${r} order:random`,limit:1};this.config.isR18&&t.r18?i.tags+=` -rating:s`:i.tags+=` rating:s`;let a={"User-Agent":`PixLuna/1.0`};n&&(a.Authorization=`Basic `+Buffer.from(`${n.login}:${n.apiKey}`).toString(`base64`));let o=await e.http.get(`${this.endpoint}/posts.json`,{params:i,headers:a,proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(o.posts)||o.posts.length===0)return{status:`error`,data:Error(`No image data returned`)};let s=o.posts[0],c=this.config.imageProcessing.compress?s.sample.url:s.file.url,l={id:s.id,title:``,author:s.tags.artist.join(`, `),r18:s.rating!==`s`,tags:[...s.tags.general,...s.tags.artist],extension:s.file.url.split(`.`).pop(),aiType:0,uploadDate:new Date(s.created_at).getTime(),urls:{original:s.file.url,regular:s.sample.url}};return $.debug(`成功获取图片元数据`,{metadata:l}),{status:`success`,data:{url:c,urls:{regular:s.sample.url,original:s.file.url},raw:l}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://e621.net`}}};E(`e621`,ne);var re=class extends k{static description=`通过 Gelbooru API 获取图片`;endpoint=`https://gelbooru.com/index.php`;get keyPair(){let e=this.config.gelbooru?.keyPairs||[];return e.length?e[Math.floor(Math.random()*e.length)]:null}async getMetaData({context:e},t){let n=``;t.tag&&(n=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let r=new URLSearchParams({page:`dapi`,s:`post`,q:`index`,json:`1`,limit:`1`,tags:`${n} sort:random${this.config.isR18&&t.r18?``:` rating:safe`}`}),i=this.keyPair;i&&r.append(`api_key`,i.apiKey);let a=`${this.endpoint}?${r.toString()}`;try{let t=await e.http.get(a,{proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!t.post?.length)return{status:`error`,data:Error(`No image data returned`)};let n=t.post[0],r={id:n.id,title:n.source||`Gelbooru - ${n.id}`,author:n.owner.replace(/_/g,` `),r18:[`explicit`,`questionable`].includes(n.rating),tags:n.tags.split(` `),extension:n.file_url.split(`.`).pop(),uploadDate:new Date(n.created_at).getTime(),aiType:0,urls:{original:n.file_url,regular:n.sample_url}};return $.debug(`成功获取图片元数据`,{metadata:r}),{status:`success`,data:{url:this.config.imageProcessing.compress?n.file_url:n.sample_url,urls:{regular:n.sample_url,original:n.file_url},raw:r}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://gelbooru.com/`}}setConfig(e){this.config=e}};E(`gelbooru`,re);var A=class extends k{static description=`通过 Konachan API 获取图片`;endpoint=`https://konachan.com`;keyPairs=[];hashPassword(e){let t=`So-I-Heard-You-Like-Mupkids-?--${e}--`,n=(0,u.createHash)(`sha1`);return n.update(t),n.digest(`hex`)}setConfig(e){this.config=e,e.konachan?.keyPairs?.length&&(this.keyPairs=e.konachan.keyPairs)}get keyPair(){if(!this.keyPairs.length)return null;let e=this.keyPairs[Math.floor(Math.random()*this.keyPairs.length)];return{login:e.login,password_hash:this.hashPassword(e.password)}}async getMetaData({context:e},t){try{let n=this.keyPair,r=``;t.tag&&(r=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let i={tags:`order:random ${r}`.trim(),limit:1,api_version:2,...n&&{login:n.login,password_hash:n.password_hash,auth:!0}};this.config.isR18&&t.r18?i.tags=`${i.tags} rating:questionable rating:explicit`.trim():i.tags=`${i.tags} rating:safe`.trim(),$.debug(`请求参数`,i);let a=await e.http.get(`${this.endpoint}/post.json`,{params:i,proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(a)||a.length===0)return{status:`error`,data:Error(`No image data returned`)};let o=a[0],s=this.config.imageProcessing.compress?o.sample_url:o.file_url,c={id:o.id,title:``,author:o.author.replace(/_/g,` `),r18:o.rating===`e`||o.rating===`q`,tags:o.tags.split(` `),extension:o.file_url.split(`.`).pop(),aiType:0,uploadDate:new Date(o.created_at).getTime(),urls:{original:o.file_url,regular:o.sample_url}};return $.debug(`成功获取图片元数据`,{metadata:c}),{status:`success`,data:{url:s,urls:{regular:o.sample_url,original:o.file_url},raw:c}}}catch(e){return $.error(`Konachan请求失败`,e),{status:`error`,data:e}}}getMeta(){return{referer:`https://konachan.com`}}};E(`konachan`,A);function j(e){let t=`--${e}--`,n=(0,u.createHash)(`sha1`);return n.update(t),n.digest(`hex`)}var M=class extends k{static description=`通过 Lolibooru API 获取图片`;endpoint=`https://lolibooru.moe`;keyPairs=[];setConfig(e){this.config=e,e.lolibooru?.keyPairs?.length&&(this.keyPairs=e.lolibooru.keyPairs)}get keyPair(){if(!this.keyPairs.length)return null;let e=this.keyPairs[Math.floor(Math.random()*this.keyPairs.length)];return{login:e.login,password_hash:j(e.password)}}async getMetaData({context:e},t){try{let n=this.keyPair,r=``;t.tag&&(r=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let i={tags:`${r} order:random`,limit:`1`};this.config.isR18&&t.r18?i.tags+=` -rating:s`:i.tags+=` rating:s`,n&&(i.login=n.login,i.password_hash=n.password_hash);let a=await e.http.get(`${this.endpoint}/post/index.json`,{params:i,proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(a)||a.length===0)return{status:`error`,data:Error(`No image data returned`)};let o=a[0],s=this.config.imageProcessing.compress?o.sample_url:o.file_url,c={id:o.id,title:o.source||`Lolibooru - ${o.id}`,author:o.author.replace(/_/g,` `),r18:[`e`,`q`].includes(o.rating),tags:o.tags.split(` `),extension:o.file_url.split(`.`).pop(),aiType:0,uploadDate:new Date(o.created_at).getTime(),urls:{original:encodeURI(o.file_url),regular:encodeURI(o.sample_url)}};return $.debug(`成功获取图片元数据`,{metadata:c}),{status:`success`,data:{url:encodeURI(s),urls:{regular:encodeURI(o.sample_url),original:encodeURI(o.file_url)},raw:c}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://lolibooru.moe`}}};E(`lolibooru`,M);var N=class extends k{constructor(e,t){super(e,t),this.ctx=e,this.config=t}async getMetaData({context:e},t){let n=[];t.tag&&(n=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean));let r={r18:this.config.isR18&&t.r18?1:0,num:1,size:t.size,keyword:n.length===0?t.tag:void 0,tag:n.length>0?n:void 0,excludeAI:t.excludeAI,proxy:t.proxy},i=await e.http.post(this.API_URL,r,{proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(i.error||!i.data||i.data.length===0)return{status:`error`,data:Error(i.error||`No image data returned`)};let a=i.data[0],o=this.config.imageProcessing.compress?a.urls.original:a.urls.regular||a.urls.original,s={id:a.pid,title:a.title,author:a.author,r18:a.r18,tags:a.tags,extension:a.ext,aiType:a.aiType,uploadDate:a.uploadDate,urls:a.urls};return $.debug(`成功获取图片元数据`,{metadata:s}),{status:`success`,data:{url:o,urls:{regular:a.urls.regular,original:a.urls.original},raw:s}}}setConfig(e){this.config=e}getMeta(){return{referer:`https://www.pixiv.net/`}}},P=class extends N{static description=`通过 Lolisuki API 获取图片`;API_URL=`https://lolisuki.cn/api/setu/v1`},F=class extends N{static description=`通过 Lolicon API 获取图片`;API_URL=`https://api.lolicon.app/setu/v2`};E(`lolisuki`,P),E(`lolicon`,F);function I(e,t){let n=[c.h.image(e.data,e.mimeType),(0,c.h)(`text`,{content:`\ntitle:${e.title}\n`}),(0,c.h)(`text`,{content:`id:${e.id}\n`})];return t?.showTags!==!1&&n.push((0,c.h)(`text`,{content:`tags:${e.tags.map(e=>`#${e}`).join(` `)}\n`})),(0,c.h)(``,n)}function L(e,t){return(0,c.h)(``,[(0,c.h)(`at`,{id:e}),(0,c.h)(`text`,{content:` ${t}`})])}function R(e,t){let n=[],r=e[0];return n.push((0,c.h)(`text`,{content:`title:${r.title}\n`}),(0,c.h)(`text`,{content:`id:${r.id}\n`}),(0,c.h)(`text`,{content:`共 ${e.length} 页\n\n`})),t?.showTags!==!1&&n.push((0,c.h)(`text`,{content:`tags:${r.tags.map(e=>`#${e}`).join(` `)}\n\n`})),e.forEach((e,t)=>{n.push((0,c.h)(`text`,{content:`第 ${t+1} 页:\n`}),c.h.image(e.data,e.mimeType),(0,c.h)(`text`,{content:`
`}))}),(0,c.h)(``,n)}async function z(e,t=0,n=!0){(!n||t>0)&&await new Promise(t=>setTimeout(t,e.apiDelay))}function B(e){return e?e.split(/[,,]/).map(e=>e.trim()).filter(Boolean).slice(0,5):[]}function V(e,t){if(!t.length)return!0;let n=e.title?.toLowerCase()||``,r=Array.isArray(e.tags)?e.tags.map(e=>typeof e==`string`?e.toLowerCase():e.tag?.toLowerCase()||``):[];return t.every(e=>{let t=e.toLowerCase();return n.includes(t)||r.some(e=>typeof e==`string`&&e.includes(t))})}function H(e,t){if(!t.length||!e.length)return e;for(let n=t.length;n>0;n--){let r=t.slice(0,n),i=e.filter(e=>V(e,r));if(i.length>0)return i}return e}var U=class extends k{getHeaders(){return{Referer:`https://www.pixiv.net/`,"User-Agent":X,Cookie:`PHPSESSID=${this.config.pixiv.phpSESSID}`}}getProxyAgent(){return this.config.isProxy?this.config.proxyHost:void 0}constructImageUrl(e){let t=this.config.baseUrl||`i.pximg.net`;return e.replace(`i.pximg.net`,t)}async fetchPixivData(e,t){return await e.http.get(t,{headers:this.getHeaders(),proxyAgent:this.getProxyAgent()})}setConfig(e){this.config=e}getMeta(){return{referer:`https://www.pixiv.net/`}}},W=class e extends U{static DISCOVERY_URL=`https://www.pixiv.net/ajax/illust/discovery`;static ILLUST_PAGES_URL=`https://www.pixiv.net/ajax/illust/{ARTWORK_ID}/pages`;async getMetaData({context:t},n){try{let r=B(n.tag),i=`${e.DISCOVERY_URL}?mode=${this.config.isR18&&n.r18?`r18`:`all`}&limit=20`,a=await this.fetchPixivData(t,i);if(a.error||!a.body.illusts.length)return{status:`error`,data:Error(a.message||`未找到插画`)};let o=H(a.body.illusts,r);if(this.config.isR18||(o=o.filter(e=>!(e.xRestrict>0||e.tags.some(e=>e.toLowerCase()===`r-18`)))),o.length===0)return{status:`error`,data:Error(`未找到包含标签 "${r.join(`, `)}" 的插画`)};let s=C(o)[0],c=e.ILLUST_PAGES_URL.replace(`{ARTWORK_ID}`,s.id),l=await t.http.get(c,{headers:this.getHeaders(),proxyAgent:this.getProxyAgent()});if(l.error||!l.body.length)return{status:`error`,data:Error(`无法获取原图链接`)};let u=this.config.baseUrl||`i.pximg.net`,d=l.body[0].urls.original.replace(`i.pximg.net`,u),f={id:parseInt(s.id,10),title:s.title,author:s.userName,r18:s.xRestrict>0,tags:s.tags,extension:d.split(`.`).pop(),aiType:0,uploadDate:new Date(s.createDate).getTime(),urls:{original:d,regular:s.url.replace(`i.pximg.net`,u)}};return{status:`success`,data:{url:d,urls:f.urls,raw:f}}}catch(e){return $.error(`获取 Pixiv Discovery 元数据失败`,{error:e}),{status:`error`,data:e}}}},G=class e extends U{static description=`获取 Pixiv 已关注画师作品,需要 Pixiv 账号`;static FOLLOWING_URL=`https://www.pixiv.net/ajax/user/{USER_ID}/following?offset={OFFSET_COUNT}&limit={LIMIT_COUNT}&rest=show`;static USER_PROFILE_URL=`https://www.pixiv.net/ajax/user/{USER_ID}/profile/all`;static ILLUST_URL=`https://www.pixiv.net/ajax/illust/{ARTWORK_ID}`;async getMetaData({context:e},t){if(!this.config.pixiv.phpSESSID)return{status:`error`,data:Error(`未设置 Pixiv PHPSESSID`)};let n=B(t?.tag);try{let t=await this.getAllFollowingUsers(e);if(!t.length)return{status:`error`,data:Error(`未找到关注的用户`)};let r=[],i=new Set,a=0,o=Math.min(t.length,10),s=C(t);for(;a<o&&r.length<20;){await z({...this.config},a);let t=s[a];if(a++,i.has(t.userId))continue;i.add(t.userId);let o=await this.getUserProfile(e,t.userId);if(o.error||!o.body.illusts)continue;let c=Object.entries(o.body.illusts).map(([e,t])=>({id:e,...t}));if(n.length>0)for(let t of c)try{await z(this.config,0,!1);let i=await this.getIllustDetail(e,t.id);if(!i.error&&i.body){let e=i.body.xRestrict>0||i.body.tags.tags.some(e=>e.tag.toLowerCase()===`r-18`);(this.config.isR18||!e)&&V(i.body,n)&&r.push(i.body)}}catch{}else break}if(n.length>0&&r.length>0){let e=C(r)[0];return{status:`success`,data:{url:this.constructImageUrl(e.urls.original),urls:{original:this.constructImageUrl(e.urls.original)},raw:{id:parseInt(e.id,10),title:e.title,author:e.userName,r18:e.xRestrict>0,tags:e.tags.tags.map(e=>e.tag),extension:e.urls.original.split(`.`).pop(),aiType:0,uploadDate:new Date(e.createDate).getTime(),urls:{original:this.constructImageUrl(e.urls.original)}}}}}else if(n.length>0&&r.length===0)return{status:`error`,data:Error(`未找到包含标签 "${n.join(`, `)}" 的插画`)};else{let n=C(t)[0],r=await this.getUserProfile(e,n.userId);if(r.error||!r.body.illusts)return{status:`error`,data:Error(`无法获取用户作品列表`)};let i=Object.keys(r.body.illusts),a,o=0,s=i.length;do{await z(this.config,o);let t=C(i)[0];if(a=await this.getIllustDetail(e,t),o++,a.error||!a.body){if(o>=s)return{status:`error`,data:Error(`无法获取合适的插画详情`)};continue}let n=a.body.xRestrict>0||a.body.tags.tags.some(e=>e.tag.toLowerCase()===`r-18`);if(!this.config.isR18&&n)continue;break}while(o<s);if(o>=s)return{status:`error`,data:Error(`未找到符合条件的插画`)};let c=a.body;return{status:`success`,data:{url:this.constructImageUrl(c.urls.original),urls:{original:this.constructImageUrl(c.urls.original)},raw:{id:parseInt(c.id,10),title:c.title,author:c.userName,r18:c.xRestrict>0,tags:c.tags.tags.map(e=>e.tag),extension:c.urls.original.split(`.`).pop(),aiType:0,uploadDate:new Date(c.createDate).getTime(),urls:{original:this.constructImageUrl(c.urls.original)}}}}}}catch(e){return $.error(`获取 Pixiv Discovery 元数据失败`,{error:e}),{status:`error`,data:e}}}async getAllFollowingUsers(t){let n=0,r=[];for(;;){await z(this.config,n);let i=e.FOLLOWING_URL.replace(`{USER_ID}`,this.config.pixiv.userId).replace(`{OFFSET_COUNT}`,n.toString()).replace(`{LIMIT_COUNT}`,`100`),a=await this.fetchPixivData(t,i);if(a.error||!a.body.users.length||(r.push(...a.body.users),n+=100,a.body.users.length<100))break}return r}async getUserProfile(t,n){let r=e.USER_PROFILE_URL.replace(`{USER_ID}`,n);return await this.fetchPixivData(t,r)}async getIllustDetail(t,n){let r=e.ILLUST_URL.replace(`{ARTWORK_ID}`,n);return await this.fetchPixivData(t,r)}},ie=class e extends U{static description=`通过作品ID获取Pixiv图片`;static ILLUST_URL=`https://www.pixiv.net/ajax/illust/{ARTWORK_ID}`;async getImageByPid(e,t,n=0){if(!this.config.pixiv.phpSESSID)return{status:`error`,data:Error(`未设置 Pixiv PHPSESSID`)};try{let r=await this.getIllustDetail(e,t);if(r.error||!r.body)return{status:`error`,data:Error(`无法获取插画详情`)};let i=r.body,a=i.urls.original.split(`_p`);if(a.length!==2)return{status:`error`,data:Error(`图片URL格式错误`)};let o=`${a[0]}_p${n}${a[1].substring(a[1].indexOf(`.`))}`;if(n>=i.pageCount)return{status:`error`,data:Error(`页码超出范围,该作品共有 ${i.pageCount} 页`)};let s={id:parseInt(i.id,10),title:i.title,author:i.userName,r18:i.xRestrict>0,tags:i.tags.tags.map(e=>e.tag),extension:o.split(`.`).pop(),aiType:0,uploadDate:new Date(i.createDate).getTime(),urls:{original:this.constructImageUrl(o)}};return $.debug(`成功获取 Pixiv 图片元数据`,{metadata:s}),{status:`success`,data:{url:s.urls.original,urls:s.urls,raw:s}}}catch(e){return $.error(`获取 Pixiv 图片元数据失败`,{error:e}),{status:`error`,data:e}}}async getIllustDetail(t,n){let r=e.ILLUST_URL.replace(`{ARTWORK_ID}`,n);return await t.http.get(r,{headers:this.getHeaders(),proxyAgent:this.getProxyAgent()})}async getMetaData(){return{status:`error`,data:Error(`This provider only supports getting images by ID`)}}async getImageWithBuffer(e,t=0){let n=await this.getImageByPid(this.ctx,e,t);if(n.status===`error`)throw n.data;let[r,i]=await Z(this.ctx,this.config,n.data.url,this);return{data:Buffer.from(r),mimeType:i,id:n.data.raw.id,title:n.data.raw.title,tags:n.data.raw.tags,author:n.data.raw.author,r18:n.data.raw.r18,extension:n.data.raw.extension,aiType:n.data.raw.aiType,uploadDate:n.data.raw.uploadDate,urls:n.data.raw.urls}}async getImageWithAtMessage(e,t){if(!t.pid)return L(e,`请提供作品 ID (PID)`);try{return I(await this.getImageWithBuffer(t.pid,t.page),this.config)}catch(t){return this.ctx.logger.error(t),L(e,(t instanceof Error?t.message:String(t))||`获取图片失败`)}}async getAllImagesWithAtMessage(e,t){if(!t.pid)return L(e,`请提供作品 ID (PID)`);try{let n=await this.getIllustDetail(this.ctx,t.pid);if(n.error||!n.body)return L(e,`无法获取插画详情`);let r=n.body.pageCount||1;if(r===1)return I(await this.getImageWithBuffer(t.pid,0),this.config);let i=[];for(let e=0;e<r;e++){await z(this.config,e);let n=await this.getImageWithBuffer(t.pid,e);i.push(n)}return R(i,this.config)}catch(t){return this.ctx.logger.error(t),L(e,(t instanceof Error?t.message:String(t))||`获取图片失败`)}}};E(`pdiscovery`,W),E(`pfollowing`,G);var K=class extends k{static description=`通过 Safebooru API 获取图片`;endpoint=`https://safebooru.org/index.php`;async getMetaData({context:e},t){try{let n=``;t.tag&&(n=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let r={page:`dapi`,s:`post`,q:`index`,json:`1`,limit:`1`,tags:`${n} sort:random`},i=`${this.endpoint}?${new URLSearchParams(r).toString()}`,a=await e.http.get(i,{proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(a)||a.length===0)return{status:`error`,data:Error(`No image data returned`)};let o=a[0],s=`https://safebooru.org/images/${o.directory}/${o.image}?${o.id}`,c=o.sample?`https://safebooru.org/samples/${o.directory}/sample_${o.image}?${o.id}`:s,l={id:o.id,title:`Safebooru - ${o.id}`,author:o.owner.replace(/_/g,` `),r18:![`safe`,`general`].includes(o.rating),tags:o.tags.split(` `),extension:o.image.split(`.`).pop(),aiType:0,uploadDate:new Date(o.created_at).getTime(),urls:{original:s,regular:c}};return $.debug(`成功获取图片元数据`,{metadata:l}),{status:`success`,data:{url:this.config.imageProcessing.compress?c:s,urls:{regular:c,original:s},raw:l}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://safebooru.org`}}setConfig(e){this.config=e}};E(`safebooru`,K);var q=class extends k{static description=`通过 Sankaku Complex API 获取图片`;endpoint=`https://capi-v2.sankakucomplex.com`;http;constructor(e,t){super(e,t),this.http=e.http.extend({headers:{"User-Agent":X},proxyAgent:t.isProxy?t.proxyHost:void 0})}get keyPair(){let e=this.config.sankaku?.keyPairs||[];return e.length?e[Math.floor(Math.random()*e.length)]:null}async login(e){if(!e.accessToken){let t=await this.http.post(`${this.endpoint}/auth/token`,{login:e.login,password:e.password},{proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});t.access_token&&(e.accessToken=t.access_token,e.tokenType=t.token_type)}return e}async getMetaData(e,t){try{let e=this.keyPair;if(!e)throw Error(`No API credentials provided`);await this.login(e);let n=``;t.tag&&(n=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let r=new URLSearchParams({tags:`${n} order:random${this.config.isR18&&t.r18?``:` rating:safe`}`,limit:`1`}),i=await this.http.get(`${this.endpoint}/posts/random`,{params:r,headers:{Authorization:`${e.tokenType} ${e.accessToken}`},proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!i.length)return{status:`error`,data:Error(`No image data returned`)};let a=i[0],o={id:a.id,title:a.source||`Sankaku - ${a.id}`,author:a.author.name.replace(/_/g,` `),r18:[`explicit`,`questionable`].includes(a.rating),tags:a.tags.map(e=>e.name),extension:a.file_url.split(`.`).pop(),uploadDate:new Date(a.created_at).getTime(),aiType:0,urls:{original:a.file_url,regular:a.sample_url}};return $.debug(`成功获取图片元数据`,{metadata:o}),{status:`success`,data:{url:this.config.imageProcessing.compress?a.sample_url:a.file_url,urls:{regular:a.sample_url,original:a.file_url},raw:o}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://sankaku.app`}}setConfig(e){this.config=e}};E(`sankaku`,q);var J=class extends k{static description=`通过 Yande.re API 获取图片`;endpoint=`https://yande.re`;keyPairs=[];hashPassword(e){let t=`choujin-steiner--${e}--`,n=(0,u.createHash)(`sha1`);return n.update(t),n.digest(`hex`)}setConfig(e){this.config=e,e.yande?.keyPairs?.length&&(this.keyPairs=e.yande.keyPairs)}get keyPair(){if(!this.keyPairs.length)return null;let e=this.keyPairs[Math.floor(Math.random()*this.keyPairs.length)];return{login:e.login,password_hash:this.hashPassword(e.password)}}async getMetaData({context:e},t){try{let n=this.keyPair,r=``;t.tag&&(r=t.tag.split(/[,,]/).map(e=>e.trim()).filter(Boolean).join(` `));let i={tags:`${r} order:random`,limit:1,...n?{login:n.login,password_hash:n.password_hash}:{}};this.config.isR18&&t.r18?i.tags+=` rating:explicit`:i.tags+=` rating:safe`;let a=await e.http.get(`${this.endpoint}/post.json`,{params:i,proxyAgent:this.config.isProxy?this.config.proxyHost:void 0});if(!Array.isArray(a)||a.length===0)return{status:`error`,data:Error(`No image data returned`)};let o=a[0],s=this.config.imageProcessing.compress?o.sample_url:o.file_url,c={id:o.id,title:``,author:o.author.replace(/_/g,` `),r18:o.rating===`e`||o.rating===`q`,tags:o.tags.split(` `),extension:o.file_url.split(`.`).pop(),aiType:0,uploadDate:new Date(o.created_at).getTime(),urls:{original:o.file_url,regular:o.sample_url}};return $.debug(`成功获取图片元数据`,{metadata:c}),{status:`success`,data:{url:s,urls:{regular:o.sample_url,original:o.file_url},raw:c}}}catch(e){return{status:`error`,data:e}}}getMeta(){return{referer:`https://yande.re`}}};E(`yande`,J);function Y(e,t,n){if(n){let r=D(n);if(r)return new r(e,t);throw Error(`未找到提供程序:${n}`)}if(!t.defaultSourceProvider?.length)throw Error(`未配置任何图片来源`);let r=C(t.defaultSourceProvider)[0],i=D(r);if(i)return new i(e,t);throw Error(`未找到提供程序:${r}`)}const X=`Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36`;async function Z(e,t,n,r){return g(e,`fetchImage`,async()=>{let i={"User-Agent":X};r?.getMeta?.()?.referer&&(i.Referer=r.getMeta().referer);let a=await e.http.get(n,{responseType:`arraybuffer`,proxyAgent:t.isProxy?t.proxyHost:void 0,headers:i}),o=await _(Buffer.from(a))||`image/png`;return $.debug(`检测到 MIME 类型`,{mimeType:o}),[a,o]})}async function ae(e,t,n,r){if(!Y(e,n,r))throw Error(`未选择有效的图片来源,请检查配置`);let i=await Y(e,n,r).getMetaData({context:e},{r18:n.isR18&&Math.random()<n.r18P,excludeAI:n.excludeAI,tag:t||void 0,proxy:n.baseUrl?n.baseUrl:void 0});if(i.status===`error`)return null;let[a,o]=await Z(e,n,i.data.url,Y(e,n,r)),s=!!i.data.urls?.regular,c=!!n.imageProcessing.isFlip,l=!!n.imageProcessing.confusion,u=!!n.imageProcessing.compress&&!s,d=a.byteLength>=32*1024*1024;if(!d&&(c||l||u)){let t=await g(e,`processImage`,async()=>await S(e,Buffer.from(a),n,s)),r=await _(t)||`image/png`;return{...i.data.raw,data:t,mimeType:r,raw:i.data.raw}}else{d&&(c||l||u)&&$.warn(`图片过大,已跳过处理并原样发送`,{sizeMB:Math.round(a.byteLength/1024/1024*10)/10});let e=Buffer.from(a);return{...i.data.raw,data:e,mimeType:o,raw:i.data.raw}}}async function oe(e,t,n,r){try{let i=await ae(e,n,t,r);return i?I(i,t):(0,c.h)(`message`,[(0,c.h)(`text`,{content:`没有获取到喵
`})])}catch(t){return e.logger.error(t),(0,c.h)(`message`,[(0,c.h)(`text`,{content:`图片获取失败了喵~,${t}`})])}}async function se(e,t,n,r){let i=new ie(e,t);return r.all?i.getAllImagesWithAtMessage(n,r):i.getImageWithAtMessage(n,r)}function ce(e,t){e.command(`pixluna.get`,`直接通过图源获取图片`),e.command(`pixluna.get.pixiv <pid:string>`,`通过 pid 获取图片`).option(`pages`,`-p <pages:number>`,{fallback:0}).option(`all`,`-a`).action(async({session:n,options:r},i)=>await se(e,t,n.userId,{pid:i,page:r.pages,all:r.all}))}function le(e,t){e.command(`pixluna.source`,`查看图源`).action(async({session:e})=>{let t=O(),n=(0,c.h)(`message`,[(0,c.h)(`text`,{content:`可用的图片来源:
`}),...t.map(e=>(0,c.h)(`text`,{content:`- ${e}: ${D(e)?.description||``}\n`}))]);await e.send(n)})}function ue(e,t){ce(e,t),le(e,t)}async function Q(e,t,n,r){try{await t.deleteMessage(n,r)}catch(t){e.logger(`recall`).warn(`撤回消息时发生错误`,{channelId:n,messageId:r,error:t})}}async function de(e,t,n,r=6e4){n?.length&&(e.logger(`recall`).debug(`设置消息自动撤回`,{channelId:t.channelId,messageIds:n,timeout:r}),setTimeout(async()=>{for(let r of n)await Q(e,t.bot,t.channelId,r)},r))}const fe=c.Schema.intersect([c.Schema.object({isR18:c.Schema.boolean().default(!1).description(`是否允许返回 R18 内容`),messageBefore:c.Schema.string().default(`不可以涩涩哦~`).description(`触发响应时的消息,留空则不发送`),showTags:c.Schema.boolean().default(!0).description(`是否显示图片标签`),excludeAI:c.Schema.boolean().default(!1).description(`是否排除 AI 生成作品`),maxConcurrency:c.Schema.number().default(1).description(`最大并发请求数`).min(1).max(10).step(1),forwardMessage:c.Schema.boolean().default(!0).description(`是否以转发消息格式发送图片`),autoRecall:c.Schema.object({enable:c.Schema.boolean().default(!1).description(`是否启用自动撤回`),delay:c.Schema.number().default(30).description(`自动撤回延迟时间(秒)`).min(1).max(120).step(1)}),apiDelay:c.Schema.number().default(1600).description(`API请求和循环的延迟时间(毫秒)`).min(0).max(1e4).step(100)}).description(`通用设置`),c.Schema.object({imageProcessing:c.Schema.object({confusion:c.Schema.boolean().default(!1).description(`是否启用图片混淆处理(对某些平台有奇效)`),compress:c.Schema.boolean().default(!1).description(`是否压缩图片(能大幅度提升发送的速度,但是对图片质量有影响)`),compressionLevel:c.Schema.number().default(6).description(`压缩等级(0-9,数值越大压缩越强)`).min(0).max(9).step(1),isFlip:c.Schema.boolean().default(!1).description(`是否启用图片翻转处理`),flipMode:c.Schema.union([c.Schema.const(`horizontal`).description(`水平翻转`),c.Schema.const(`vertical`).description(`垂直翻转`),c.Schema.const(`both`).description(`水平和垂直翻转`)]).default(`horizontal`).description(`图片翻转模式`)}).description(`图片处理设置`)}),c.Schema.object({r18P:c.Schema.percent().default(.1).description(`R18 内容出现的概率(仅当 isR18 为 true 时生效)`).min(0).max(1).step(.01)}).description(`R18 内容设置`),c.Schema.object({isProxy:c.Schema.boolean().default(!1).description(`是否使用代理`),proxyHost:c.Schema.string().default(`http://127.0.0.1:7890`).description(`代理服务器地址`),baseUrl:c.Schema.string().default(`i.pixiv.re`).description(`图片反代服务的地址`)}).description(`代理设置`),c.Schema.object({defaultSourceProvider:c.Schema.array(c.Schema.union([c.Schema.const(`danbooru`).description(`Danbooru API`),c.Schema.const(`e621`).description(`E621 API`),c.Schema.const(`gelbooru`).description(`Gelbooru API`),c.Schema.const(`konachan`).description(`Konachan API`),c.Schema.const(`lolibooru`).description(`Lolibooru API`),c.Schema.const(`lolicon`).description(`Lolicon API`),c.Schema.const(`lolisuki`).description(`Lolisuki API`),c.Schema.const(`pdiscovery`).description(`Pixiv Discovery`),c.Schema.const(`pfollowing`).description(`Pixiv Following`),c.Schema.const(`safebooru`).description(`Safebooru API`),c.Schema.const(`sankaku`).description(`Sankaku API`),c.Schema.const(`yande`).description(`Yande.re API`)])).description(`选择默认图片来源(可多选)`).default([`lolicon`]).role(`select`)}).description(`图源设置`),c.Schema.object({pixiv:c.Schema.object({phpSESSID:c.Schema.string().description(`Pixiv 的 PHPSESSID,用于访问个性化内容返回的图片分级取决于该 Pixiv 账号所有者的分级设置`).role(`secret`).default(``),userId:c.Schema.string().description(`Pixiv 用户 ID,用于获取关注列表`).default(``)}).description(`Pixiv 设置`)}),c.Schema.object({danbooru:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`Danbooru 用户名`),apiKey:c.Schema.string().required().role(`secret`).description(`Danbooru API Key`)})).default([]).description(`Danbooru API 鉴权信息`)}).description(`Danbooru 设置`)}),c.Schema.object({e621:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`E621 用户名`),apiKey:c.Schema.string().required().role(`secret`).description(`E621 API Key`)})).default([]).description(`E621 API 鉴权信息`)}).description(`E621 设置`)}),c.Schema.object({gelbooru:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({apiKey:c.Schema.string().required().role(`secret`).description(`Gelbooru API Key`)})).default([]).description(`Gelbooru API 鉴权信息`)}).description(`Gelbooru 设置`)}),c.Schema.object({lolibooru:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`Lolibooru 用户名`),password:c.Schema.string().required().role(`secret`).description(`Lolibooru 密码`)})).default([]).description(`Lolibooru API 鉴权信息`)}).description(`Lolibooru 设置`)}),c.Schema.object({sankaku:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`Sankaku Complex 用户名`),password:c.Schema.string().required().role(`secret`).description(`Sankaku Complex 密码`),tokenType:c.Schema.string().hidden().default(`Bearer`),accessToken:c.Schema.string().hidden()})).default([]).description(`Sankaku Complex API 鉴权信息`)}).description(`Sankaku Complex 设置`),konachan:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`Konachan 用户名`),password:c.Schema.string().required().role(`secret`).description(`Konachan 密码`)})).default([]).description(`Konachan API 鉴权信息`)}).description(`Konachan 设置`),yande:c.Schema.object({keyPairs:c.Schema.array(c.Schema.object({login:c.Schema.string().required().description(`Yande.re 用户名`),password:c.Schema.string().required().role(`secret`).description(`Yande.re 密码`)})).default([]).description(`Yande.re API 鉴权信息`)}).description(`Yande.re 设置`)}),c.Schema.object({isLog:c.Schema.boolean().default(!1).description(`是否输出debug日志`)}).description(`日志设置`)]),pe=`pixluna`;let $;async function me(e,t=0,n=!0){(!n||t>0)&&await new Promise(t=>setTimeout(t,e.apiDelay))}function he(e,t){$=p(e),ge(t),e.command(`pixluna`,`来张色图`).alias(`色图`).option(`number`,`-n <value:number>`,{fallback:1}).option(`source`,`-s <source:string>`,{fallback:``}).option(`tag`,`-t <tags:string>`,{fallback:``}).action(async({session:n,options:r})=>{if(!Number.isInteger(r.number)||r.number<=0)return L(n.userId,`图片数量必须是大于 0 的整数哦~`);t.messageBefore&&await n.send(t.messageBefore);let i=Array.isArray(t.defaultSourceProvider)?t.defaultSourceProvider:[t.defaultSourceProvider],a={...t,defaultSourceProvider:r.source?[r.source]:i};if(r.source)try{Y(e,{...a,defaultSourceProvider:[r.source]})}catch(e){return L(n.userId,e.message)}let o=[],s=new h(t.maxConcurrency);for(let t=0;t<Math.min(10,r.number);t++)await me(a,t),s.add(g(e,`${t+1} image`,async()=>{let t=await oe(e,a,r.tag,r.source);o.push(t)}));await s.run();let l=[];try{let r=await g(e,`send message`,()=>{let e=(0,c.h)(`message`,o);return t.forwardMessage?n.send((0,c.h)(`message`,{forward:t.forwardMessage},o)):n.send(e)});l=Array.isArray(r)?r:[r]}catch(e){$.error(`发送消息时发生错误`,{error:e});let t=await n.send(L(n.userId,`消息发送失败了喵,账号可能被风控
`));t&&(l=l.concat(Array.isArray(t)?t:[t]))}l.length>0&&t.autoRecall.enable&&await de(e,n,l,t.autoRecall.delay*1e3)}),ue(e,t)}function ge(e){e.isLog&&m(c.Logger.DEBUG)}exports.Config=fe,exports.apply=he,Object.defineProperty(exports,`logger`,{enumerable:!0,get:function(){return $}}),exports.name=`pixluna`;