100 lines
2.9 KiB
JavaScript
100 lines
2.9 KiB
JavaScript
class Rule34 {
|
|
baseUrl = "https://rule34.xxx";
|
|
|
|
headers = {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
|
};
|
|
|
|
constructor() {
|
|
this.type = "image-board";
|
|
this.version = "1.0"
|
|
}
|
|
|
|
async search(query = "alisa_mikhailovna_kujou", page = 1, perPage = 42) {
|
|
const offset = (page - 1) * perPage;
|
|
const url = `${this.baseUrl}/index.php?page=post&s=list&tags=${query}&pid=${offset}`;
|
|
|
|
const response = await fetch(url, { headers: this.headers });
|
|
const data = await response.text();
|
|
const $ = this.cheerio.load(data);
|
|
|
|
const results = [];
|
|
|
|
$('.image-list span').each((_, e) => {
|
|
const $e = $(e);
|
|
const id = $e.attr('id')?.replace('s', '');
|
|
let image = $e.find('img').attr('src');
|
|
|
|
if (image && !image.startsWith('http')) {
|
|
image = `https:${image}`;
|
|
}
|
|
|
|
const tags = $e.find('img')
|
|
.attr('alt')
|
|
?.trim()
|
|
.split(' ')
|
|
.filter(Boolean);
|
|
|
|
if (id && image) {
|
|
results.push({
|
|
id,
|
|
image,
|
|
tags
|
|
});
|
|
}
|
|
});
|
|
|
|
const pagination = $('#paginator .pagination');
|
|
const lastPageLink = pagination.find('a[alt="last page"]');
|
|
|
|
let totalPages = 1;
|
|
if (lastPageLink.length) {
|
|
const pid = Number(lastPageLink.attr('href')?.split('pid=')[1] ?? 0);
|
|
totalPages = Math.ceil(pid / perPage) + 1;
|
|
}
|
|
|
|
return {
|
|
page,
|
|
hasNextPage: page < totalPages,
|
|
results
|
|
};
|
|
}
|
|
|
|
async getInfo(id) {
|
|
const url = `${this.baseUrl}/index.php?page=post&s=view&id=${id}`;
|
|
|
|
const resizeCookies = {
|
|
'resize-notification': 1,
|
|
'resize-original': 1
|
|
};
|
|
|
|
const cookieString = Object.entries(resizeCookies).map(([key, value]) => `${key}=${value}`).join('; ');
|
|
|
|
const fetchHeaders = { ...this.headers };
|
|
const resizeHeaders = { ...this.headers, 'cookie': cookieString };
|
|
|
|
const [resizedResponse, nonResizedResponse] = await Promise.all([
|
|
fetch(url, { headers: resizeHeaders }),
|
|
fetch(url, { headers: fetchHeaders })
|
|
]);
|
|
|
|
const [resized, original] = await Promise.all([resizedResponse.text(), nonResizedResponse.text()]);
|
|
|
|
const $ = this.cheerio.load(original);
|
|
|
|
let fullImage = $('#image').attr('src');
|
|
if (fullImage && !fullImage.startsWith('http')) {
|
|
fullImage = `https:${fullImage}`;
|
|
}
|
|
|
|
const tags = $('#image').attr('alt')?.trim()?.split(' ').filter(tag => tag !== "");
|
|
|
|
return {
|
|
id,
|
|
image: fullImage,
|
|
tags
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = Rule34; |