source/temp/temp.js
2025-10-26 22:55:39 +00:00

242 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

async function searchResults(keyword) {
try {
const encodedKeyword = encodeURIComponent(keyword);
const response = await fetchv2(`https://mangakatana.com/?search=${encodedKeyword}&search_by=book_name`);
const html = await response.text();
const results = [];
const itemRegex = /<div class="item"[^>]*data-genre="[^"]*"[^>]*data-id="[^"]*"[^>]*>([\s\S]*?)(?=<div class="item"|$)/g;
let itemMatch;
while ((itemMatch = itemRegex.exec(html)) !== null) {
const itemHtml = itemMatch[1];
const titleRegex = /<h3 class="title">\s*<a href="([^"]+)"[^>]*>([^<]+)<\/a>/;
const imageRegex = /<div class="wrap_img">\s*<a[^>]*><img src="([^"]+)"/;
const titleMatch = titleRegex.exec(itemHtml);
const imageMatch = imageRegex.exec(itemHtml);
if (titleMatch && imageMatch) {
const title = titleMatch[2].trim();
const href = titleMatch[1].trim();
const image = imageMatch[1].trim();
if (
title && href && image &&
!title.includes("'+") &&
!href.includes("'+") &&
href.startsWith("http")
) {
results.push({
title: title,
href: href,
image: image
});
}
}
}
console.log(`Search results for "${keyword}":`, JSON.stringify(results));
return JSON.stringify(results);
} catch (error) {
console.log('Fetch error in searchResults:', error);
return JSON.stringify([{ title: 'Error', href: '', image: '' }]);
}
}
async function extractDetails(url) {
try {
const response = await soraFetch(url);
const htmlText = await response.text();
const descMatch = htmlText.match(/<div class="label">Description<\/div>\s*<p>([\s\S]*?)<\/p>/);
let description = 'No description available';
if (descMatch && descMatch[1]) {
description = descMatch[1]
.replace(/<[^>]+>/g, '')
.replace(/\s+/g, ' ')
.trim();
}
const transformedResults = [{
description,
aliases: 'N/A',
airdate: 'N/A'
}];
console.log(`Details for "${url}":`, JSON.stringify(transformedResults));
return JSON.stringify(transformedResults);
} catch (error) {
console.log('Details error:', error);
return JSON.stringify([{
description: 'Error loading description',
aliases: 'N/A',
airdate: 'N/A'
}]);
}
}
async function extractChapters(url) {
try {
const response = await soraFetch(url);
const htmlText = await response.text();
const chapterRegex = /<tr data-jump="0">[\s\S]*?<a href="([^"]+)">([\s\S]*?)<\/a>[\s\S]*?<\/tr>/g;
const chapters = [];
let match;
while ((match = chapterRegex.exec(htmlText)) !== null) {
const href = match[1].trim();
const titleMatch = /Chapter \d+[:\s]?.*/i.exec(match[2]);
const title = titleMatch ? decodeHtmlEntities(titleMatch[0].trim()) : "Unknown Chapter";
const numberMatch = /Chapter (\d+)/i.exec(title);
const number = numberMatch ? parseInt(numberMatch[1]) : NaN;
chapters.push({
number: number === 0 ? 1 : number,
href: href.startsWith("http") ? href : "https://mangakatana.com" + href,
title: title
});
}
chapters.reverse();
console.log(JSON.stringify(chapters));
return chapters;
} catch (error) {
console.error('Fetch error in extractChapters:', error);
return [];
}
}
async function extractText(url) {
try {
const response = await soraFetch(url);
const htmlText = await response.text();
// Extract image URLs using regex
const regex = /'(https:\/\/[^']+\.jpg)'/g;
const matches = [...htmlText.matchAll(regex)];
const imageUrls = matches.map(match => match[1]);
// Generate HTML
const html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Manga</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
body {
background: #000;
-webkit-touch-callout: none;
}
.img-container {
width: 100%;
min-height: 1200px;
background: #000;
position: relative;
}
img {
width: 100%;
display: block;
opacity: 0;
transition: opacity 0.3s ease;
-webkit-user-select: none;
position: absolute;
top: 0;
left: 0;
}
img.loaded {
opacity: 1;
position: relative;
}
</style>
</head>
<body>
${imageUrls.map(url => ` <div class="img-container"><img data-src="${url}" alt=""></div>`).join('\n')}
<script>
(function() {
var images = document.querySelectorAll('img[data-src]');
var containers = document.querySelectorAll('.img-container');
var loadQueue = [];
var loading = false;
function loadImage(index) {
if (index >= images.length || loading) return;
loading = true;
var img = images[index];
var container = containers[index];
img.src = img.dataset.src;
img.onload = function() {
container.style.minHeight = img.naturalHeight + 'px';
img.classList.add('loaded');
loading = false;
loadImage(index + 1);
};
img.onerror = function() {
loading = false;
loadImage(index + 1);
};
}
loadImage(0);
})();
</script>
</body>
</html>`;
return html;
} catch (error) {
console.error("❌ Error in extractImages:", error);
return {
error: `Error loading chapter images: ${error.message}`
};
}
}
function decodeHtmlEntities(str) {
const named = {
amp: '&',
lt: '<',
gt: '>',
quot: '"',
apos: "'",
nbsp: ' ',
hellip: '…',
rsquo: '',
lsquo: '',
ndash: '',
mdash: '—'
};
return str
.replace(/&([a-z]+);/gi, (match, name) => named[name] || match)
.replace(/&#(\d+);/g, (_, code) => String.fromCharCode(code));
}
async function soraFetch(url, options = { headers: {}, method: 'GET', body: null }) {
try {
return await fetchv2(url, options.headers ?? {}, options.method ?? 'GET', options.body ?? null);
} catch(e) {
try {
return await fetch(url, options);
} catch(error) {
return null;
}
}
}