mirror of
https://github.com/kodjodevf/mangayomi-extensions.git
synced 2026-02-14 10:51:17 +00:00
AniWorld, AnimeFenix, JKAnime and TioAnime: New host, fixes and helper lib update
AniWorld - New Host: Speedfiles - New Host: Filemoon - Better Sorting for preferences AnimeFenix: - Added possible status string JKAnime - Get Studios TioAnime - Fix hasNextPage Helper library - Add new host: Speedfiles - Add new String function: reverse, swapcase
This commit is contained in:
@@ -6,7 +6,7 @@ const mangayomiSources = [{
|
||||
"iconUrl": "https://tioanime.com/assets/img/tio_fb.jpg",
|
||||
"typeSource": "single",
|
||||
"isManga": false,
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"dateFormat": "",
|
||||
"dateFormatLocale": "",
|
||||
"pkgPath": "anime/src/es/tioanime.js"
|
||||
@@ -32,8 +32,8 @@ class DefaultExtension extends MProvider {
|
||||
const link = element.selectFirst("a").getHref;
|
||||
list.push({ name, imageUrl, link });
|
||||
}
|
||||
const hasNextPage = doc.selectFirst("li.page-item.active + li").text == "»";
|
||||
return { "list": list, "hasNextPage": hasNextPage };
|
||||
const isLastPage = doc.selectFirst("li.page-item.active + li").text == "»";
|
||||
return { "list": list, "hasNextPage": !isLastPage };
|
||||
}
|
||||
statusFromString(status) {
|
||||
return {
|
||||
@@ -106,6 +106,11 @@ class DefaultExtension extends MProvider {
|
||||
throw new Error("getFilterList not implemented");
|
||||
}
|
||||
getSourcePreferences() {
|
||||
const languages = ['Español'];
|
||||
const types = ['Sub'];
|
||||
const resolutions = ['1080p', '720p', '480p'];
|
||||
const hosts = ['Okru', 'VidGuard', 'Voe', 'YourUpload'];
|
||||
|
||||
return [
|
||||
{
|
||||
key: 'lang',
|
||||
@@ -113,12 +118,8 @@ class DefaultExtension extends MProvider {
|
||||
title: 'Preferred Language',
|
||||
summary: 'If available, this language will be chosen by default. Priority = 0 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: [
|
||||
'Español'
|
||||
],
|
||||
entryValues: [
|
||||
'Español'
|
||||
]
|
||||
entries: languages,
|
||||
entryValues: languages
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -127,12 +128,8 @@ class DefaultExtension extends MProvider {
|
||||
title: 'Preferred Type',
|
||||
summary: 'If available, this type will be chosen by default. Priority = 1 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: [
|
||||
'Sub'
|
||||
],
|
||||
entryValues: [
|
||||
'Sub'
|
||||
]
|
||||
entries: types,
|
||||
entryValues: types
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -141,36 +138,18 @@ class DefaultExtension extends MProvider {
|
||||
title: 'Preferred Resolution',
|
||||
summary: 'If available, this resolution will be chosen by default. Priority = 2 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: [
|
||||
'1080p',
|
||||
'720p',
|
||||
'480p'
|
||||
],
|
||||
entryValues: [
|
||||
'1080p',
|
||||
'720p',
|
||||
'480p'
|
||||
]
|
||||
entries: resolutions,
|
||||
entryValues: resolutions
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'host',
|
||||
listPreference: {
|
||||
title: 'Preferred Hoster',
|
||||
title: 'Preferred Host',
|
||||
summary: 'If available, this hoster will be chosen by default. Priority = 3 (lower is better)',
|
||||
valueIndex: 0,
|
||||
entries: [
|
||||
'Okru',
|
||||
'VidGuard',
|
||||
'Voe',
|
||||
'YourUpload'
|
||||
],
|
||||
entryValues: [
|
||||
'Okru',
|
||||
'VidGuard',
|
||||
'Voe',
|
||||
'YourUpload'
|
||||
]
|
||||
entries: hosts,
|
||||
entryValues: hosts
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -179,7 +158,7 @@ class DefaultExtension extends MProvider {
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* mangayomi-js-helpers v1.0
|
||||
* mangayomi-js-helpers v1.1
|
||||
*
|
||||
* # Video Extractors
|
||||
* - vidGuardExtractor
|
||||
@@ -190,9 +169,10 @@ class DefaultExtension extends MProvider {
|
||||
* - vidHideExtractor
|
||||
* - filemoonExtractor
|
||||
* - mixdropExtractor
|
||||
* - speedfilesExtractor
|
||||
* - burstcloudExtractor (not working, see description)
|
||||
*
|
||||
* # Video Extractor Format Wrappers
|
||||
* # Video Extractor Wrappers
|
||||
* - streamWishExtractor
|
||||
* - voeExtractor
|
||||
* - mp4UploadExtractor
|
||||
@@ -207,24 +187,34 @@ class DefaultExtension extends MProvider {
|
||||
* - m3u8Extractor
|
||||
* - jwplayerExtractor
|
||||
*
|
||||
* # Extension
|
||||
* # Extension Helpers
|
||||
* - sortVideos()
|
||||
*
|
||||
* # Encoding/Decoding
|
||||
* - Uint8Array.fromBase64()
|
||||
* - Uint8Array.prototype.toBase64()
|
||||
* - Uint8Array.prototype.decode()
|
||||
* # Uint8Array
|
||||
* - Uint8Array.fromBase64()
|
||||
* - Uint8Array.prototype.toBase64()
|
||||
* - Uint8Array.prototype.decode()
|
||||
*
|
||||
* # String
|
||||
* - String.prototype.encode()
|
||||
* - String.prototype.decode()
|
||||
*
|
||||
* # Random string
|
||||
* - String.decode()
|
||||
* - String.prototype.reverse()
|
||||
* - String.prototype.swapcase()
|
||||
* - getRandomString()
|
||||
*
|
||||
* # Encode/Decode Functions
|
||||
* - decodeUTF8
|
||||
* - encodeUTF8
|
||||
*
|
||||
* # URL
|
||||
* # Url
|
||||
* - absUrl()
|
||||
*
|
||||
***************************************************************************************************/
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractors
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function vidGuardExtractor(url) {
|
||||
// get html
|
||||
const res = await new Client().get(url);
|
||||
@@ -305,8 +295,8 @@ async function vidHideExtractor(url) {
|
||||
return await jwplayerExtractor(res.body);
|
||||
}
|
||||
|
||||
async function filemoonExtractor(url) {
|
||||
let res = await new Client().get(url);
|
||||
async function filemoonExtractor(url, headers) {
|
||||
let res = await new Client().get(url, headers);
|
||||
const src = res.body.match(/iframe src="(.*?)"/)?.[1];
|
||||
if (src) {
|
||||
res = await new Client().get(src, {
|
||||
@@ -338,6 +328,37 @@ async function mixdropExtractor(url) {
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: '', headers: headers}];
|
||||
}
|
||||
|
||||
async function speedfilesExtractor(url) {
|
||||
let res = await new Client().get(url);
|
||||
let doc = new Document(res.body);
|
||||
|
||||
const code = doc.selectFirst('script:contains(var)').text;
|
||||
let b64;
|
||||
|
||||
// Get b64
|
||||
for (const match of code.matchAll(/(?:var|let|const)\s*\w+\s*=\s*["']([^"']+)/g)) {
|
||||
if (match[1].match(/[g-zG-Z]/)) {
|
||||
b64 = match[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// decode b64 => b64
|
||||
const step1 = Uint8Array.fromBase64(b64).reverse().decode().swapcase();
|
||||
// decode b64 => hex
|
||||
const step2 = Uint8Array.fromBase64(step1).reverse().decode();
|
||||
// decode hex => b64
|
||||
let step3 = [];
|
||||
for (let i = 0; i < step2.length; i += 2) {
|
||||
step3.push(parseInt(step2.slice(i, i + 2), 16) - 3);
|
||||
}
|
||||
step3 = String.fromCharCode(...step3.reverse()).swapcase();
|
||||
// decode b64 => url
|
||||
const videoUrl = Uint8Array.fromBase64(step3).decode();
|
||||
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: '', headers: null}];
|
||||
}
|
||||
|
||||
/** Does not work: Client always sets 'charset=utf-8' in Content-Type. */
|
||||
async function burstcloudExtractor(url) {
|
||||
let client = new Client();
|
||||
@@ -362,6 +383,10 @@ async function burstcloudExtractor(url) {
|
||||
}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractor Wrappers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
_streamWishExtractor = streamWishExtractor;
|
||||
streamWishExtractor = async (url) => {
|
||||
return (await _streamWishExtractor(url, '')).map(v => {
|
||||
@@ -418,9 +443,13 @@ sendVidExtractor = async (url) => {
|
||||
return [{url: videoUrl, originalUrl: videoUrl, quality: quality, headers: null}];
|
||||
}
|
||||
|
||||
async function extractAny(url, method, lang, type, host) {
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Video Extractor Helpers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function extractAny(url, method, lang, type, host, headers = null) {
|
||||
const m = extractAny.methods[method];
|
||||
return (!m) ? [] : (await m(url)).map(v => {
|
||||
return (!m) ? [] : (await m(url, headers)).map(v => {
|
||||
v.quality = v.quality ? `${lang} ${type} ${v.quality} ${host}` : `${lang} ${type} ${host}`;
|
||||
return v;
|
||||
});
|
||||
@@ -435,6 +464,7 @@ extractAny.methods = {
|
||||
'mp4upload': mp4UploadExtractor,
|
||||
'okru': okruExtractor,
|
||||
'sendvid': sendVidExtractor,
|
||||
'speedfiles': speedfilesExtractor,
|
||||
'streamtape': streamTapeExtractor,
|
||||
'streamwish': vidHideExtractor,
|
||||
'vidguard': vidGuardExtractor,
|
||||
@@ -444,6 +474,10 @@ extractAny.methods = {
|
||||
'yourupload': yourUploadExtractor
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Playlist Extractors
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
async function m3u8Extractor(url, headers = null) {
|
||||
// https://developer.apple.com/documentation/http-live-streaming/creating-a-multivariant-playlist
|
||||
// https://developer.apple.com/documentation/http-live-streaming/adding-alternate-media-to-a-playlist
|
||||
@@ -581,6 +615,10 @@ async function jwplayerExtractor(text, headers) {
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Extension Helpers
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function sortVideos(videos) {
|
||||
const pref = new SharedPreferences();
|
||||
const getres = RegExp('(\\d+)p?', 'i');
|
||||
@@ -612,6 +650,10 @@ function sortVideos(videos) {
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Uint8Array
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
Uint8Array.fromBase64 = function (b64) {
|
||||
// [00,01,02,03,04,05,06,07,08,\t,\n,0b,0c,\r,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,' ', !, ", #, $, %, &, ', (, ), *, +,',', -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <,'=', >, ?, @,A,B,C,D,E,F,G,H,I,J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \, ], ^, _, `, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {, |, }, ~,7f]
|
||||
const m = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]
|
||||
@@ -651,6 +693,10 @@ Uint8Array.prototype.decode = function (encoding = 'utf-8') {
|
||||
return null;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// String
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
String.prototype.encode = function (encoding = 'utf-8') {
|
||||
encoding = encoding.toLowerCase();
|
||||
if (encoding == 'utf-8') {
|
||||
@@ -667,6 +713,32 @@ String.decode = function (data, encoding = 'utf-8') {
|
||||
return null;
|
||||
}
|
||||
|
||||
String.prototype.reverse = function () {
|
||||
return this.split('').reverse().join('');
|
||||
}
|
||||
|
||||
String.prototype.swapcase = function () {
|
||||
const isAsciiLetter = /[A-z]/;
|
||||
const result = [];
|
||||
for (const l of this)
|
||||
result.push(isAsciiLetter.test(l) ? String.fromCharCode(l.charCodeAt() ^ 32) : l);
|
||||
return result.join('');
|
||||
}
|
||||
|
||||
function getRandomString(length) {
|
||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
|
||||
let result = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
const random = Math.floor(Math.random() * 61);
|
||||
result += chars[random];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Encode/Decode Functions
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function decodeUTF8(data) {
|
||||
const codes = [];
|
||||
for (let i = 0; i < data.length;) {
|
||||
@@ -696,15 +768,9 @@ function encodeUTF8(string) {
|
||||
return new Uint8Array(data);
|
||||
}
|
||||
|
||||
function getRandomString(length) {
|
||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
|
||||
let result = "";
|
||||
for (let i = 0; i < length; i++) {
|
||||
const random = Math.floor(Math.random() * 61);
|
||||
result += chars[random];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Url
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
function absUrl(url, base) {
|
||||
if (url.search(/^\w+:\/\//) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user