Update Zelluloza (#1209)
* test * fix * Update authortoday.ts * terser@5.34.1 * foxteller
@@ -47,7 +47,7 @@
|
||||
"image-size": "^1.1.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"terser": "^5.31.1",
|
||||
"terser": "^5.34.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.5.2",
|
||||
"typescript-eslint": "^7.14.1",
|
||||
@@ -5223,10 +5223,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.31.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz",
|
||||
"integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==",
|
||||
"version": "5.34.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz",
|
||||
"integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.8.2",
|
||||
@@ -9156,9 +9157,9 @@
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"terser": {
|
||||
"version": "5.31.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz",
|
||||
"integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==",
|
||||
"version": "5.34.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz",
|
||||
"integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"image-size": "^1.1.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"terser": "^5.31.1",
|
||||
"terser": "^5.34.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.5.2",
|
||||
"typescript-eslint": "^7.14.1",
|
||||
|
||||
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1001 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 512 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 484 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 891 B |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 162 B After Width: | Height: | Size: 18 KiB |
@@ -9,6 +9,7 @@ const minSize = 16;
|
||||
const skip = new Set([
|
||||
//custom icons
|
||||
'FWK.US',
|
||||
'RNRF',
|
||||
'ReN',
|
||||
'daonovel',
|
||||
'dragontea',
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
{
|
||||
"filters": {
|
||||
"genre[]": {
|
||||
"type": "Checkbox",
|
||||
"label": "Genre",
|
||||
"value": [],
|
||||
"options": [
|
||||
{
|
||||
"label": "Academy",
|
||||
"value": "academy"
|
||||
},
|
||||
{
|
||||
"label": "Action",
|
||||
"value": "action"
|
||||
},
|
||||
{
|
||||
"label": "Adult",
|
||||
"value": "adult"
|
||||
},
|
||||
{
|
||||
"label": "Adventure",
|
||||
"value": "adventure"
|
||||
},
|
||||
{
|
||||
"label": "Another World",
|
||||
"value": "another-world"
|
||||
},
|
||||
{
|
||||
"label": "Comdey",
|
||||
"value": "comdey"
|
||||
},
|
||||
{
|
||||
"label": "Comedy",
|
||||
"value": "comedy"
|
||||
},
|
||||
{
|
||||
"label": "Dark Fantasy",
|
||||
"value": "dark-fantasy"
|
||||
},
|
||||
{
|
||||
"label": "Drama",
|
||||
"value": "drama"
|
||||
},
|
||||
{
|
||||
"label": "Fantasy",
|
||||
"value": "fantasy"
|
||||
},
|
||||
{
|
||||
"label": "Fantasy Fusion",
|
||||
"value": "fantasy-fusion"
|
||||
},
|
||||
{
|
||||
"label": "Harem",
|
||||
"value": "harem"
|
||||
},
|
||||
{
|
||||
"label": "Historical",
|
||||
"value": "historical"
|
||||
},
|
||||
{
|
||||
"label": "Horror",
|
||||
"value": "horror"
|
||||
},
|
||||
{
|
||||
"label": "Hunter",
|
||||
"value": "hunter"
|
||||
},
|
||||
{
|
||||
"label": "Light Novel",
|
||||
"value": "light-novel"
|
||||
},
|
||||
{
|
||||
"label": "Martial Arts",
|
||||
"value": "martial-arts"
|
||||
},
|
||||
{
|
||||
"label": "Mature",
|
||||
"value": "mature"
|
||||
},
|
||||
{
|
||||
"label": "Misunderstanding",
|
||||
"value": "misunderstanding"
|
||||
},
|
||||
{
|
||||
"label": "Modern",
|
||||
"value": "modern"
|
||||
},
|
||||
{
|
||||
"label": "Modern Fantasy",
|
||||
"value": "modern-fantasy"
|
||||
},
|
||||
{
|
||||
"label": "Munchkin",
|
||||
"value": "munchkin"
|
||||
},
|
||||
{
|
||||
"label": "Murim",
|
||||
"value": "murim"
|
||||
},
|
||||
{
|
||||
"label": "mystery",
|
||||
"value": "mystery"
|
||||
},
|
||||
{
|
||||
"label": "No Harem",
|
||||
"value": "no-harem"
|
||||
},
|
||||
{
|
||||
"label": "NO NTR",
|
||||
"value": "no-ntr"
|
||||
},
|
||||
{
|
||||
"label": "obsession",
|
||||
"value": "obsession"
|
||||
},
|
||||
{
|
||||
"label": "Possession",
|
||||
"value": "possession"
|
||||
},
|
||||
{
|
||||
"label": "Psychological",
|
||||
"value": "psychological"
|
||||
},
|
||||
{
|
||||
"label": "Regression",
|
||||
"value": "regression"
|
||||
},
|
||||
{
|
||||
"label": "Regret",
|
||||
"value": "regret"
|
||||
},
|
||||
{
|
||||
"label": "reincarnation",
|
||||
"value": "reincarnation"
|
||||
},
|
||||
{
|
||||
"label": "Romance",
|
||||
"value": "romance"
|
||||
},
|
||||
{
|
||||
"label": "School Life",
|
||||
"value": "school-life"
|
||||
},
|
||||
{
|
||||
"label": "Seinen",
|
||||
"value": "seinen"
|
||||
},
|
||||
{
|
||||
"label": "Slice of life",
|
||||
"value": "slice-of-life"
|
||||
},
|
||||
{
|
||||
"label": "Supernatural",
|
||||
"value": "supernatural"
|
||||
},
|
||||
{
|
||||
"label": "Tragedy",
|
||||
"value": "tragedy"
|
||||
},
|
||||
{
|
||||
"label": "Transmigrated to Game",
|
||||
"value": "transmigrated-to-game"
|
||||
},
|
||||
{
|
||||
"label": "Transmigration",
|
||||
"value": "transmigration"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type[]": {
|
||||
"type": "Checkbox",
|
||||
"label": "Type",
|
||||
"value": [],
|
||||
"options": [
|
||||
{
|
||||
"label": "korean novel",
|
||||
"value": "korean-novel"
|
||||
},
|
||||
{
|
||||
"label": "Web Novel",
|
||||
"value": "web-novel"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": {
|
||||
"type": "Picker",
|
||||
"label": "Status",
|
||||
"value": "",
|
||||
"options": [
|
||||
{
|
||||
"label": "All",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"label": "Ongoing",
|
||||
"value": "ongoing"
|
||||
},
|
||||
{
|
||||
"label": "Hiatus",
|
||||
"value": "hiatus"
|
||||
},
|
||||
{
|
||||
"label": "Completed",
|
||||
"value": "completed"
|
||||
}
|
||||
]
|
||||
},
|
||||
"order": {
|
||||
"type": "Picker",
|
||||
"label": "Order by",
|
||||
"value": "",
|
||||
"options": [
|
||||
{
|
||||
"label": "Default",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"label": "A-Z",
|
||||
"value": "title"
|
||||
},
|
||||
{
|
||||
"label": "Z-A",
|
||||
"value": "titlereverse"
|
||||
},
|
||||
{
|
||||
"label": "Latest Update",
|
||||
"value": "update"
|
||||
},
|
||||
{
|
||||
"label": "Latest Added",
|
||||
"value": "latest"
|
||||
},
|
||||
{
|
||||
"label": "Popular",
|
||||
"value": "popular"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class Foxteller implements Plugin.PluginBase {
|
||||
id = 'foxteller';
|
||||
name = 'Foxteller';
|
||||
site = 'https://www.foxteller.com';
|
||||
version = '1.0.0';
|
||||
version = '1.0.1';
|
||||
icon = 'src/en/foxteller/icon.png';
|
||||
|
||||
async popularNovels(
|
||||
@@ -227,7 +227,7 @@ class Foxteller implements Plugin.PluginBase {
|
||||
}
|
||||
});
|
||||
|
||||
return decodeURIComponent(escape(decodeBase64(base64)));
|
||||
return decodeURIComponent(decodeBase64(base64));
|
||||
}
|
||||
|
||||
throw new Error('This chapter is closed');
|
||||
@@ -285,7 +285,7 @@ const base64Characters =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
|
||||
function decodeBase64(encodedString: string) {
|
||||
let output = '';
|
||||
const hexcode = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < encodedString.length) {
|
||||
@@ -295,17 +295,18 @@ function decodeBase64(encodedString: string) {
|
||||
const enc4 = base64Characters.indexOf(encodedString.charAt(i++));
|
||||
|
||||
const chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
output += String.fromCharCode(chr1);
|
||||
const chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
const chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
hexcode.push(chr1.toString(16).padStart(2, '0'));
|
||||
|
||||
if (enc3 !== 64) {
|
||||
const chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
output += String.fromCharCode(chr2);
|
||||
hexcode.push(chr2.toString(16).padStart(2, '0'));
|
||||
}
|
||||
if (enc4 !== 64) {
|
||||
const chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
output += String.fromCharCode(chr3);
|
||||
hexcode.push(chr3.toString(16).padStart(2, '0'));
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
return '%' + hexcode.join('%');
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { NovelStatus } from '@libs/novelStatus';
|
||||
class NovelMania implements Plugin.PluginBase {
|
||||
id = 'novelmania.com.br';
|
||||
name = 'Novel Mania';
|
||||
icon = 'src/pt-br/novelmania.png';
|
||||
icon = 'src/pt-br/novelmania/icon.png';
|
||||
site = 'https://novelmania.com.br';
|
||||
version = '1.0.0';
|
||||
imageRequestInit?: Plugin.ImageRequestInit | undefined = undefined;
|
||||
|
||||
@@ -14,7 +14,7 @@ class AuthorToday implements Plugin.PluginBase {
|
||||
site = 'https://author.today';
|
||||
apiSite = 'https://api.author.today/v1/';
|
||||
imageSite = 'https://cm.author.today/content/';
|
||||
version = '1.1.0';
|
||||
version = '1.1.1';
|
||||
|
||||
async popularNovels(
|
||||
pageNo: number,
|
||||
@@ -357,11 +357,13 @@ function decrypt(
|
||||
userId: number | string = '',
|
||||
) {
|
||||
const key = encryptedKey.split('').reverse().join('') + '@_@' + userId;
|
||||
const keyBytes = key.split('').map(char => char.charCodeAt());
|
||||
const keyLength = keyBytes.length;
|
||||
let text = '';
|
||||
|
||||
for (let i = 0; i < encrypt.length; i++) {
|
||||
text += String.fromCharCode(
|
||||
encrypt.charCodeAt(i) ^ key.charCodeAt(i % key.length),
|
||||
encrypt.charCodeAt(i) ^ keyBytes[i % keyLength],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class Zelluloza implements Plugin.PluginBase {
|
||||
id = 'zelluloza';
|
||||
name = 'Целлюлоза';
|
||||
site = 'https://zelluloza.ru';
|
||||
version = '1.0.1';
|
||||
version = '1.0.2';
|
||||
icon = 'src/ru/zelluloza/icon.png';
|
||||
|
||||
async popularNovels(
|
||||
@@ -19,27 +19,17 @@ class Zelluloza implements Plugin.PluginBase {
|
||||
showLatestNovels,
|
||||
}: Plugin.PopularNovelsOptions<typeof this.filters>,
|
||||
): Promise<Plugin.NovelItem[]> {
|
||||
const sort = showLatestNovels ? '0.0' : filters?.sort?.value || '6.0';
|
||||
const genres = filters?.genres?.value || '';
|
||||
const sort = showLatestNovels ? '0' : filters?.sort?.value || '3';
|
||||
|
||||
const body = await fetchApi(this.site + '/ajaxcall/', {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Referer: this.site + '/top/freebooks/',
|
||||
Origin: this.site,
|
||||
},
|
||||
method: 'POST',
|
||||
body: new URLSearchParams({
|
||||
op: 'morebooks',
|
||||
par1: '',
|
||||
par2: `125:0:${genres}:0.${sort}.0.0.0.0.0.0.0.0.0.1.s.1..:${pageNo}`,
|
||||
par4: '',
|
||||
}).toString(),
|
||||
}).then(res => res.text());
|
||||
const path = filters?.genres?.value
|
||||
? `/search/genres/${filters.genres.value}/?page=${pageNo}`
|
||||
: `/top/freebooks/?sort_order=${sort}&page=${pageNo}`;
|
||||
|
||||
const body = await fetchApi(this.site + path).then(res => res.text());
|
||||
const loadedCheerio = parseHTML(body);
|
||||
const novels: Plugin.NovelItem[] = [];
|
||||
|
||||
loadedCheerio('div[style="display: flex;"]').each((index, element) => {
|
||||
loadedCheerio('section[class="book-card-item"]').each((index, element) => {
|
||||
novels.push({
|
||||
name: loadedCheerio(element).find('span[itemprop="name"]').text() || '',
|
||||
cover:
|
||||
@@ -194,13 +184,13 @@ class Zelluloza implements Plugin.PluginBase {
|
||||
filters = {
|
||||
sort: {
|
||||
label: 'Сортировка',
|
||||
value: '6.0',
|
||||
value: '3',
|
||||
options: [
|
||||
{ label: 'Топ-недели', value: '6.0' },
|
||||
{ label: 'Бестселеры', value: '5.0' },
|
||||
{ label: 'Популярные у читателей', value: '2.0' },
|
||||
{ label: 'Книжные новинки', value: '0.0' },
|
||||
{ label: 'Законченные книги', value: '0.1' },
|
||||
{ label: 'По рейтингу', value: '3' },
|
||||
{ label: 'По изменению', value: '0' },
|
||||
{ label: 'По длительности чтения', value: '1' },
|
||||
{ label: 'По количеству читателей', value: '2' },
|
||||
{ label: 'По популярности', value: '4' },
|
||||
],
|
||||
type: FilterTypes.Picker,
|
||||
},
|
||||
@@ -385,54 +375,7 @@ function decrypt(encrypt: string) {
|
||||
hexArray.push(alphabet[firstChar] + alphabet[secondChar]);
|
||||
}
|
||||
|
||||
return '<p>' + hexToUtf8(hexArray) + '</p>';
|
||||
}
|
||||
|
||||
function hexToUtf8(hexArray: string[]) {
|
||||
let index = 0;
|
||||
let result = '';
|
||||
|
||||
while (index < hexArray.length) {
|
||||
const currentHex = parseInt(hexArray[index], 16) & 0xff;
|
||||
|
||||
if (currentHex < 128) {
|
||||
if (currentHex < 16) {
|
||||
switch (currentHex) {
|
||||
case 9:
|
||||
result += ' ';
|
||||
break;
|
||||
case 13:
|
||||
result += '\r';
|
||||
break;
|
||||
case 10:
|
||||
result += '\n';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result += String.fromCharCode(currentHex);
|
||||
}
|
||||
index++;
|
||||
} else if (currentHex > 191 && currentHex < 224) {
|
||||
if (index + 1 < hexArray.length) {
|
||||
const nextHex = parseInt(hexArray[index + 1], 16) & 0xff;
|
||||
result += String.fromCharCode(
|
||||
((currentHex & 31) << 6) | (nextHex & 63),
|
||||
);
|
||||
}
|
||||
index += 2;
|
||||
} else {
|
||||
if (index + 2 < hexArray.length) {
|
||||
const nextHex = parseInt(hexArray[index + 1], 16) & 0xff;
|
||||
const thirdHex = parseInt(hexArray[index + 2], 16) & 0xff;
|
||||
result += String.fromCharCode(
|
||||
((currentHex & 15) << 12) | ((nextHex & 63) << 6) | (thirdHex & 63),
|
||||
);
|
||||
}
|
||||
index += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return '<p>' + decodeURIComponent('%' + hexArray.join('%')) + '</p>';
|
||||
}
|
||||
|
||||
export default new Zelluloza();
|
||||
|
||||