koishi-plugin-booru-lolibooru
Version:
Image service by lolibooru for Koishi
80 lines (79 loc) • 3.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const node_crypto_1 = require("node:crypto");
const koishi_1 = require("koishi");
const koishi_plugin_booru_1 = require("koishi-plugin-booru");
/**
* Lolibooru requires a password hash for authentication.
*
* @see https://lolibooru.moe/help/api
*/
function hashPassword(password) {
const salted = `--${password}--`;
// do a SHA1 hash of the salted password
const hash = (0, node_crypto_1.createHash)('sha1');
hash.update(salted);
return hash.digest('hex');
}
class LolibooruImageSource extends koishi_plugin_booru_1.ImageSource {
constructor(ctx, config) {
super(ctx, config);
this.languages = ['en'];
this.source = 'lolibooru';
}
get keyPair() {
if (!this.config.keyPairs.length)
return;
const key = this.config.keyPairs[Math.floor(Math.random() * this.config.keyPairs.length)];
return {
login: key.login,
password_hash: hashPassword(key.password),
};
}
async get(query) {
// API docs: https://lolibooru.moe/help/api
const params = {
tags: query.tags.join('+') + '+order:random',
limit: `${query.count}`,
};
const url = (0, koishi_1.trimSlash)(this.config.endpoint) + '/post/index.json';
const keyPair = this.keyPair;
if (keyPair) {
params['login'] = keyPair.login;
params['password_hash'] = keyPair.password_hash;
}
const data = await this.http.get(url, { params: new URLSearchParams(params) });
if (!Array.isArray(data)) {
return;
}
return data.map((post) => {
return {
// Since lolibooru returns URL that contains white spaces that are not transformed
// into `%20`, which breaks in go-cqhttp who cannot resolve to a valid URL.
// Fixes: https://github.com/koishijs/koishi-plugin-booru/issues/95
urls: {
original: encodeURI(post.file_url),
medium: encodeURI(post.sample_url),
thumbnail: encodeURI(post.preview_url),
},
pageUrl: post.source,
author: post.author.replace(/ /g, ', ').replace(/_/g, ' '),
tags: post.tags.split(' ').map((t) => t.replace(/_/g, ' ')),
nsfw: ['e', 'q'].includes(post.rating),
};
});
}
}
(function (LolibooruImageSource) {
LolibooruImageSource.Config = koishi_1.Schema.intersect([
koishi_plugin_booru_1.ImageSource.createSchema({ label: 'lolibooru' }),
koishi_1.Schema.object({
endpoint: koishi_1.Schema.string().description('Lolibooru 的 URL。').default('https://lolibooru.moe'),
keyPairs: koishi_1.Schema.array(koishi_1.Schema.object({
login: koishi_1.Schema.string().required().description('用户名'),
password: koishi_1.Schema.string().required().role('secret').description('密码'),
})).description('Lolibooru 的登录凭据。'),
}).description('搜索设置'),
]);
})(LolibooruImageSource || (LolibooruImageSource = {}));
exports.default = LolibooruImageSource;