mirror of https://github.com/qist/tvbox.git
parent
513c46a467
commit
a5391a344e
File diff suppressed because one or more lines are too long
@ -0,0 +1,577 @@
|
||||
/*!
|
||||
* Jinja Templating for JavaScript v0.1.8
|
||||
* https://github.com/sstur/jinja-js
|
||||
*
|
||||
* This is a slimmed-down Jinja2 implementation [http://jinja.pocoo.org/]
|
||||
*
|
||||
* In the interest of simplicity, it deviates from Jinja2 as follows:
|
||||
* - Line statements, cycle, super, macro tags and block nesting are not implemented
|
||||
* - auto escapes html by default (the filter is "html" not "e")
|
||||
* - Only "html" and "safe" filters are built in
|
||||
* - Filters are not valid in expressions; `foo|length > 1` is not valid
|
||||
* - Expression Tests (`if num is odd`) not implemented (`is` translates to `==` and `isnot` to `!=`)
|
||||
*
|
||||
* Notes:
|
||||
* - if property is not found, but method '_get' exists, it will be called with the property name (and cached)
|
||||
* - `{% for n in obj %}` iterates the object's keys; get the value with `{% for n in obj %}{{ obj[n] }}{% endfor %}`
|
||||
* - subscript notation `a[0]` takes literals or simple variables but not `a[item.key]`
|
||||
* - `.2` is not a valid number literal; use `0.2`
|
||||
*
|
||||
*/
|
||||
/*global require, exports, module, define */
|
||||
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jinja = {}));
|
||||
})(this, (function (jinja) {
|
||||
"use strict";
|
||||
var STRINGS = /'(\\.|[^'])*'|"(\\.|[^"'"])*"/g;
|
||||
var IDENTS_AND_NUMS = /([$_a-z][$\w]*)|([+-]?\d+(\.\d+)?)/g;
|
||||
var NUMBER = /^[+-]?\d+(\.\d+)?$/;
|
||||
//non-primitive literals (array and object literals)
|
||||
var NON_PRIMITIVES = /\[[@#~](,[@#~])*\]|\[\]|\{([@i]:[@#~])(,[@i]:[@#~])*\}|\{\}/g;
|
||||
//bare identifiers such as variables and in object literals: {foo: 'value'}
|
||||
var IDENTIFIERS = /[$_a-z][$\w]*/ig;
|
||||
var VARIABLES = /i(\.i|\[[@#i]\])*/g;
|
||||
var ACCESSOR = /(\.i|\[[@#i]\])/g;
|
||||
var OPERATORS = /(===?|!==?|>=?|<=?|&&|\|\||[+\-\*\/%])/g;
|
||||
//extended (english) operators
|
||||
var EOPS = /(^|[^$\w])(and|or|not|is|isnot)([^$\w]|$)/g;
|
||||
var LEADING_SPACE = /^\s+/;
|
||||
var TRAILING_SPACE = /\s+$/;
|
||||
|
||||
var START_TOKEN = /\{\{\{|\{\{|\{%|\{#/;
|
||||
var TAGS = {
|
||||
'{{{': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}\}/,
|
||||
'{{': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}/,
|
||||
'{%': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?%\}/,
|
||||
'{#': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?#\}/
|
||||
};
|
||||
|
||||
var delimeters = {
|
||||
'{%': 'directive',
|
||||
'{{': 'output',
|
||||
'{#': 'comment'
|
||||
};
|
||||
|
||||
var operators = {
|
||||
and: '&&',
|
||||
or: '||',
|
||||
not: '!',
|
||||
is: '==',
|
||||
isnot: '!='
|
||||
};
|
||||
|
||||
var constants = {
|
||||
'true': true,
|
||||
'false': false,
|
||||
'null': null
|
||||
};
|
||||
|
||||
function Parser() {
|
||||
this.nest = [];
|
||||
this.compiled = [];
|
||||
this.childBlocks = 0;
|
||||
this.parentBlocks = 0;
|
||||
this.isSilent = false;
|
||||
}
|
||||
|
||||
Parser.prototype.push = function (line) {
|
||||
if (!this.isSilent) {
|
||||
this.compiled.push(line);
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.parse = function (src) {
|
||||
this.tokenize(src);
|
||||
return this.compiled;
|
||||
};
|
||||
|
||||
Parser.prototype.tokenize = function (src) {
|
||||
var lastEnd = 0, parser = this, trimLeading = false;
|
||||
matchAll(src, START_TOKEN, function (open, index, src) {
|
||||
//here we match the rest of the src against a regex for this tag
|
||||
var match = src.slice(index + open.length).match(TAGS[open]);
|
||||
match = (match ? match[0] : '');
|
||||
//here we sub out strings so we don't get false matches
|
||||
var simplified = match.replace(STRINGS, '@');
|
||||
//if we don't have a close tag or there is a nested open tag
|
||||
if (!match || ~simplified.indexOf(open)) {
|
||||
return index + 1;
|
||||
}
|
||||
var inner = match.slice(0, 0 - open.length);
|
||||
//check for white-space collapse syntax
|
||||
if (inner.charAt(0) === '-') var wsCollapseLeft = true;
|
||||
if (inner.slice(-1) === '-') var wsCollapseRight = true;
|
||||
inner = inner.replace(/^-|-$/g, '').trim();
|
||||
//if we're in raw mode and we are not looking at an "endraw" tag, move along
|
||||
if (parser.rawMode && (open + inner) !== '{%endraw') {
|
||||
return index + 1;
|
||||
}
|
||||
var text = src.slice(lastEnd, index);
|
||||
lastEnd = index + open.length + match.length;
|
||||
if (trimLeading) text = trimLeft(text);
|
||||
if (wsCollapseLeft) text = trimRight(text);
|
||||
if (wsCollapseRight) trimLeading = true;
|
||||
if (open === '{{{') {
|
||||
//liquid-style: make {{{x}}} => {{x|safe}}
|
||||
open = '{{';
|
||||
inner += '|safe';
|
||||
}
|
||||
parser.textHandler(text);
|
||||
parser.tokenHandler(open, inner);
|
||||
});
|
||||
var text = src.slice(lastEnd);
|
||||
if (trimLeading) text = trimLeft(text);
|
||||
this.textHandler(text);
|
||||
};
|
||||
|
||||
Parser.prototype.textHandler = function (text) {
|
||||
this.push('write(' + JSON.stringify(text) + ');');
|
||||
};
|
||||
|
||||
Parser.prototype.tokenHandler = function (open, inner) {
|
||||
var type = delimeters[open];
|
||||
if (type === 'directive') {
|
||||
this.compileTag(inner);
|
||||
} else if (type === 'output') {
|
||||
var extracted = this.extractEnt(inner, STRINGS, '@');
|
||||
//replace || operators with ~
|
||||
extracted.src = extracted.src.replace(/\|\|/g, '~').split('|');
|
||||
//put back || operators
|
||||
extracted.src = extracted.src.map(function (part) {
|
||||
return part.split('~').join('||');
|
||||
});
|
||||
var parts = this.injectEnt(extracted, '@');
|
||||
if (parts.length > 1) {
|
||||
var filters = parts.slice(1).map(this.parseFilter.bind(this));
|
||||
this.push('filter(' + this.parseExpr(parts[0]) + ',' + filters.join(',') + ');');
|
||||
} else {
|
||||
this.push('filter(' + this.parseExpr(parts[0]) + ');');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Parser.prototype.compileTag = function (str) {
|
||||
var directive = str.split(' ')[0];
|
||||
var handler = tagHandlers[directive];
|
||||
if (!handler) {
|
||||
throw new Error('Invalid tag: ' + str);
|
||||
}
|
||||
handler.call(this, str.slice(directive.length).trim());
|
||||
};
|
||||
|
||||
Parser.prototype.parseFilter = function (src) {
|
||||
src = src.trim();
|
||||
var match = src.match(/[:(]/);
|
||||
var i = match ? match.index : -1;
|
||||
if (i < 0) return JSON.stringify([src]);
|
||||
var name = src.slice(0, i);
|
||||
var args = src.charAt(i) === ':' ? src.slice(i + 1) : src.slice(i + 1, -1);
|
||||
args = this.parseExpr(args, {terms: true});
|
||||
return '[' + JSON.stringify(name) + ',' + args + ']';
|
||||
};
|
||||
|
||||
Parser.prototype.extractEnt = function (src, regex, placeholder) {
|
||||
var subs = [], isFunc = typeof placeholder == 'function';
|
||||
src = src.replace(regex, function (str) {
|
||||
var replacement = isFunc ? placeholder(str) : placeholder;
|
||||
if (replacement) {
|
||||
subs.push(str);
|
||||
return replacement;
|
||||
}
|
||||
return str;
|
||||
});
|
||||
return {src: src, subs: subs};
|
||||
};
|
||||
|
||||
Parser.prototype.injectEnt = function (extracted, placeholder) {
|
||||
var src = extracted.src, subs = extracted.subs, isArr = Array.isArray(src);
|
||||
var arr = (isArr) ? src : [src];
|
||||
var re = new RegExp('[' + placeholder + ']', 'g'), i = 0;
|
||||
arr.forEach(function (src, index) {
|
||||
arr[index] = src.replace(re, function () {
|
||||
return subs[i++];
|
||||
});
|
||||
});
|
||||
return isArr ? arr : arr[0];
|
||||
};
|
||||
|
||||
//replace complex literals without mistaking subscript notation with array literals
|
||||
Parser.prototype.replaceComplex = function (s) {
|
||||
var parsed = this.extractEnt(s, /i(\.i|\[[@#i]\])+/g, 'v');
|
||||
parsed.src = parsed.src.replace(NON_PRIMITIVES, '~');
|
||||
return this.injectEnt(parsed, 'v');
|
||||
};
|
||||
|
||||
//parse expression containing literals (including objects/arrays) and variables (including dot and subscript notation)
|
||||
//valid expressions: `a + 1 > b.c or c == null`, `a and b[1] != c`, `(a < b) or (c < d and e)`, 'a || [1]`
|
||||
Parser.prototype.parseExpr = function (src, opts) {
|
||||
opts = opts || {};
|
||||
//extract string literals -> @
|
||||
var parsed1 = this.extractEnt(src, STRINGS, '@');
|
||||
//note: this will catch {not: 1} and a.is; could we replace temporarily and then check adjacent chars?
|
||||
parsed1.src = parsed1.src.replace(EOPS, function (s, before, op, after) {
|
||||
return (op in operators) ? before + operators[op] + after : s;
|
||||
});
|
||||
//sub out non-string literals (numbers/true/false/null) -> #
|
||||
// the distinction is necessary because @ can be object identifiers, # cannot
|
||||
var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function (s) {
|
||||
return (s in constants || NUMBER.test(s)) ? '#' : null;
|
||||
});
|
||||
//sub out object/variable identifiers -> i
|
||||
var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, 'i');
|
||||
//remove white-space
|
||||
parsed3.src = parsed3.src.replace(/\s+/g, '');
|
||||
|
||||
//the rest of this is simply to boil the expression down and check validity
|
||||
var simplified = parsed3.src;
|
||||
//sub out complex literals (objects/arrays) -> ~
|
||||
// the distinction is necessary because @ and # can be subscripts but ~ cannot
|
||||
while (simplified !== (simplified = this.replaceComplex(simplified))) ;
|
||||
//now @ represents strings, # represents other primitives and ~ represents non-primitives
|
||||
//replace complex variables (those with dot/subscript accessors) -> v
|
||||
while (simplified !== (simplified = simplified.replace(/i(\.i|\[[@#i]\])+/, 'v'))) ;
|
||||
//empty subscript or complex variables in subscript, are not permitted
|
||||
simplified = simplified.replace(/[iv]\[v?\]/g, 'x');
|
||||
//sub in "i" for @ and # and ~ and v (now "i" represents all literals, variables and identifiers)
|
||||
simplified = simplified.replace(/[@#~v]/g, 'i');
|
||||
//sub out operators
|
||||
simplified = simplified.replace(OPERATORS, '%');
|
||||
//allow 'not' unary operator
|
||||
simplified = simplified.replace(/!+[i]/g, 'i');
|
||||
var terms = opts.terms ? simplified.split(',') : [simplified];
|
||||
terms.forEach(function (term) {
|
||||
//simplify logical grouping
|
||||
while (term !== (term = term.replace(/\(i(%i)*\)/g, 'i'))) ;
|
||||
if (!term.match(/^i(%i)*/)) {
|
||||
throw new Error('Invalid expression: ' + src + " " + term);
|
||||
}
|
||||
});
|
||||
parsed3.src = parsed3.src.replace(VARIABLES, this.parseVar.bind(this));
|
||||
parsed2.src = this.injectEnt(parsed3, 'i');
|
||||
parsed1.src = this.injectEnt(parsed2, '#');
|
||||
return this.injectEnt(parsed1, '@');
|
||||
};
|
||||
|
||||
Parser.prototype.parseVar = function (src) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var str = args.pop(), index = args.pop();
|
||||
//quote bare object identifiers (might be a reserved word like {while: 1})
|
||||
if (src === 'i' && str.charAt(index + 1) === ':') {
|
||||
return '"i"';
|
||||
}
|
||||
var parts = ['"i"'];
|
||||
src.replace(ACCESSOR, function (part) {
|
||||
if (part === '.i') {
|
||||
parts.push('"i"');
|
||||
} else if (part === '[i]') {
|
||||
parts.push('get("i")');
|
||||
} else {
|
||||
parts.push(part.slice(1, -1));
|
||||
}
|
||||
});
|
||||
return 'get(' + parts.join(',') + ')';
|
||||
};
|
||||
|
||||
//escapes a name to be used as a javascript identifier
|
||||
Parser.prototype.escName = function (str) {
|
||||
return str.replace(/\W/g, function (s) {
|
||||
return '$' + s.charCodeAt(0).toString(16);
|
||||
});
|
||||
};
|
||||
|
||||
Parser.prototype.parseQuoted = function (str) {
|
||||
if (str.charAt(0) === "'") {
|
||||
str = str.slice(1, -1).replace(/\\.|"/, function (s) {
|
||||
if (s === "\\'") return "'";
|
||||
return s.charAt(0) === '\\' ? s : ('\\' + s);
|
||||
});
|
||||
str = '"' + str + '"';
|
||||
}
|
||||
//todo: try/catch or deal with invalid characters (linebreaks, control characters)
|
||||
return JSON.parse(str);
|
||||
};
|
||||
|
||||
|
||||
//the context 'this' inside tagHandlers is the parser instance
|
||||
var tagHandlers = {
|
||||
'if': function (expr) {
|
||||
this.push('if (' + this.parseExpr(expr) + ') {');
|
||||
this.nest.unshift('if');
|
||||
},
|
||||
'else': function () {
|
||||
if (this.nest[0] === 'for') {
|
||||
this.push('}, function() {');
|
||||
} else {
|
||||
this.push('} else {');
|
||||
}
|
||||
},
|
||||
'elseif': function (expr) {
|
||||
this.push('} else if (' + this.parseExpr(expr) + ') {');
|
||||
},
|
||||
'endif': function () {
|
||||
this.nest.shift();
|
||||
this.push('}');
|
||||
},
|
||||
'for': function (str) {
|
||||
var i = str.indexOf(' in ');
|
||||
var name = str.slice(0, i).trim();
|
||||
var expr = str.slice(i + 4).trim();
|
||||
this.push('each(' + this.parseExpr(expr) + ',' + JSON.stringify(name) + ',function() {');
|
||||
this.nest.unshift('for');
|
||||
},
|
||||
'endfor': function () {
|
||||
this.nest.shift();
|
||||
this.push('});');
|
||||
},
|
||||
'raw': function () {
|
||||
this.rawMode = true;
|
||||
},
|
||||
'endraw': function () {
|
||||
this.rawMode = false;
|
||||
},
|
||||
'set': function (stmt) {
|
||||
var i = stmt.indexOf('=');
|
||||
var name = stmt.slice(0, i).trim();
|
||||
var expr = stmt.slice(i + 1).trim();
|
||||
this.push('set(' + JSON.stringify(name) + ',' + this.parseExpr(expr) + ');');
|
||||
},
|
||||
'block': function (name) {
|
||||
if (this.isParent) {
|
||||
++this.parentBlocks;
|
||||
var blockName = 'block_' + (this.escName(name) || this.parentBlocks);
|
||||
this.push('block(typeof ' + blockName + ' == "function" ? ' + blockName + ' : function() {');
|
||||
} else if (this.hasParent) {
|
||||
this.isSilent = false;
|
||||
++this.childBlocks;
|
||||
blockName = 'block_' + (this.escName(name) || this.childBlocks);
|
||||
this.push('function ' + blockName + '() {');
|
||||
}
|
||||
this.nest.unshift('block');
|
||||
},
|
||||
'endblock': function () {
|
||||
this.nest.shift();
|
||||
if (this.isParent) {
|
||||
this.push('});');
|
||||
} else if (this.hasParent) {
|
||||
this.push('}');
|
||||
this.isSilent = true;
|
||||
}
|
||||
},
|
||||
'extends': function (name) {
|
||||
name = this.parseQuoted(name);
|
||||
var parentSrc = this.readTemplateFile(name);
|
||||
this.isParent = true;
|
||||
this.tokenize(parentSrc);
|
||||
this.isParent = false;
|
||||
this.hasParent = true;
|
||||
//silence output until we enter a child block
|
||||
this.isSilent = true;
|
||||
},
|
||||
'include': function (name) {
|
||||
name = this.parseQuoted(name);
|
||||
var incSrc = this.readTemplateFile(name);
|
||||
this.isInclude = true;
|
||||
this.tokenize(incSrc);
|
||||
this.isInclude = false;
|
||||
}
|
||||
};
|
||||
|
||||
//liquid style
|
||||
tagHandlers.assign = tagHandlers.set;
|
||||
//python/django style
|
||||
tagHandlers.elif = tagHandlers.elseif;
|
||||
|
||||
var getRuntime = function runtime(data, opts) {
|
||||
var defaults = {autoEscape: 'toJson'};
|
||||
var _toString = Object.prototype.toString;
|
||||
var _hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var getKeys = Object.keys || function (obj) {
|
||||
var keys = [];
|
||||
for (var n in obj) if (_hasOwnProperty.call(obj, n)) keys.push(n);
|
||||
return keys;
|
||||
};
|
||||
var isArray = Array.isArray || function (obj) {
|
||||
return _toString.call(obj) === '[object Array]';
|
||||
};
|
||||
var create = Object.create || function (obj) {
|
||||
function F() {
|
||||
}
|
||||
|
||||
F.prototype = obj;
|
||||
return new F();
|
||||
};
|
||||
var toString = function (val) {
|
||||
if (val == null) return '';
|
||||
return (typeof val.toString == 'function') ? val.toString() : _toString.call(val);
|
||||
};
|
||||
var extend = function (dest, src) {
|
||||
var keys = getKeys(src);
|
||||
for (var i = 0, len = keys.length; i < len; i++) {
|
||||
var key = keys[i];
|
||||
dest[key] = src[key];
|
||||
}
|
||||
return dest;
|
||||
};
|
||||
//get a value, lexically, starting in current context; a.b -> get("a","b")
|
||||
var get = function () {
|
||||
var val, n = arguments[0], c = stack.length;
|
||||
while (c--) {
|
||||
val = stack[c][n];
|
||||
if (typeof val != 'undefined') break;
|
||||
}
|
||||
for (var i = 1, len = arguments.length; i < len; i++) {
|
||||
if (val == null) continue;
|
||||
n = arguments[i];
|
||||
val = (_hasOwnProperty.call(val, n)) ? val[n] : (typeof val._get == 'function' ? (val[n] = val._get(n)) : null);
|
||||
}
|
||||
return (val == null) ? '' : val;
|
||||
};
|
||||
var set = function (n, val) {
|
||||
stack[stack.length - 1][n] = val;
|
||||
};
|
||||
var push = function (ctx) {
|
||||
stack.push(ctx || {});
|
||||
};
|
||||
var pop = function () {
|
||||
stack.pop();
|
||||
};
|
||||
var write = function (str) {
|
||||
output.push(str);
|
||||
};
|
||||
var filter = function (val) {
|
||||
for (var i = 1, len = arguments.length; i < len; i++) {
|
||||
var arr = arguments[i], name = arr[0], filter = filters[name];
|
||||
if (filter) {
|
||||
arr[0] = val;
|
||||
//now arr looks like [val, arg1, arg2]
|
||||
val = filter.apply(data, arr);
|
||||
} else {
|
||||
throw new Error('Invalid filter: ' + name);
|
||||
}
|
||||
}
|
||||
if (opts.autoEscape && name !== opts.autoEscape && name !== 'safe') {
|
||||
//auto escape if not explicitly safe or already escaped
|
||||
val = filters[opts.autoEscape].call(data, val);
|
||||
}
|
||||
output.push(val);
|
||||
};
|
||||
var each = function (obj, loopvar, fn1, fn2) {
|
||||
if (obj == null) return;
|
||||
var arr = isArray(obj) ? obj : getKeys(obj), len = arr.length;
|
||||
var ctx = {loop: {length: len, first: arr[0], last: arr[len - 1]}};
|
||||
push(ctx);
|
||||
for (var i = 0; i < len; i++) {
|
||||
extend(ctx.loop, {index: i + 1, index0: i});
|
||||
fn1(ctx[loopvar] = arr[i]);
|
||||
}
|
||||
if (len === 0 && fn2) fn2();
|
||||
pop();
|
||||
};
|
||||
var block = function (fn) {
|
||||
push();
|
||||
fn();
|
||||
pop();
|
||||
};
|
||||
var render = function () {
|
||||
return output.join('');
|
||||
};
|
||||
data = data || {};
|
||||
opts = extend(defaults, opts || {});
|
||||
var filters = extend({
|
||||
html: function (val) {
|
||||
return toString(val)
|
||||
.split('&').join('&')
|
||||
.split('<').join('<')
|
||||
.split('>').join('>')
|
||||
.split('"').join('"');
|
||||
},
|
||||
safe: function (val) {
|
||||
return val;
|
||||
},
|
||||
toJson: function (val) {
|
||||
if (typeof val === 'object') {
|
||||
return JSON.stringify(val);
|
||||
}
|
||||
return toString(val);
|
||||
}
|
||||
}, opts.filters || {});
|
||||
var stack = [create(data || {})], output = [];
|
||||
return {
|
||||
get: get,
|
||||
set: set,
|
||||
push: push,
|
||||
pop: pop,
|
||||
write: write,
|
||||
filter: filter,
|
||||
each: each,
|
||||
block: block,
|
||||
render: render
|
||||
};
|
||||
};
|
||||
|
||||
var runtime;
|
||||
|
||||
jinja.compile = function (markup, opts) {
|
||||
opts = opts || {};
|
||||
var parser = new Parser();
|
||||
parser.readTemplateFile = this.readTemplateFile;
|
||||
var code = [];
|
||||
code.push('function render($) {');
|
||||
code.push('var get = $.get, set = $.set, push = $.push, pop = $.pop, write = $.write, filter = $.filter, each = $.each, block = $.block;');
|
||||
code.push.apply(code, parser.parse(markup));
|
||||
code.push('return $.render();');
|
||||
code.push('}');
|
||||
code = code.join('\n');
|
||||
if (opts.runtime === false) {
|
||||
var fn = new Function('data', 'options', 'return (' + code + ')(runtime(data, options))');
|
||||
} else {
|
||||
runtime = runtime || (runtime = getRuntime.toString());
|
||||
fn = new Function('data', 'options', 'return (' + code + ')((' + runtime + ')(data, options))');
|
||||
}
|
||||
return {render: fn};
|
||||
};
|
||||
|
||||
jinja.render = function (markup, data, opts) {
|
||||
var tmpl = jinja.compile(markup);
|
||||
return tmpl.render(data, opts);
|
||||
};
|
||||
|
||||
jinja.templateFiles = [];
|
||||
|
||||
jinja.readTemplateFile = function (name) {
|
||||
var templateFiles = this.templateFiles || [];
|
||||
var templateFile = templateFiles[name];
|
||||
if (templateFile == null) {
|
||||
throw new Error('Template file not found: ' + name);
|
||||
}
|
||||
return templateFile;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function trimLeft(str) {
|
||||
return str.replace(LEADING_SPACE, '');
|
||||
}
|
||||
|
||||
function trimRight(str) {
|
||||
return str.replace(TRAILING_SPACE, '');
|
||||
}
|
||||
|
||||
function matchAll(str, reg, fn) {
|
||||
//copy as global
|
||||
reg = new RegExp(reg.source, 'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
|
||||
var match;
|
||||
while ((match = reg.exec(str))) {
|
||||
var result = fn(match[0], match.index, str);
|
||||
if (typeof result == 'number') {
|
||||
reg.lastIndex = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,138 @@
|
||||
const peq = new Uint32Array(0x10000);
|
||||
const myers_32 = (a, b) => {
|
||||
const n = a.length;
|
||||
const m = b.length;
|
||||
const lst = 1 << (n - 1);
|
||||
let pv = -1;
|
||||
let mv = 0;
|
||||
let sc = n;
|
||||
let i = n;
|
||||
while (i--) {
|
||||
peq[a.charCodeAt(i)] |= 1 << i;
|
||||
}
|
||||
for (i = 0; i < m; i++) {
|
||||
let eq = peq[b.charCodeAt(i)];
|
||||
const xv = eq | mv;
|
||||
eq |= ((eq & pv) + pv) ^ pv;
|
||||
mv |= ~(eq | pv);
|
||||
pv &= eq;
|
||||
if (mv & lst) {
|
||||
sc++;
|
||||
}
|
||||
if (pv & lst) {
|
||||
sc--;
|
||||
}
|
||||
mv = (mv << 1) | 1;
|
||||
pv = (pv << 1) | ~(xv | mv);
|
||||
mv &= xv;
|
||||
}
|
||||
i = n;
|
||||
while (i--) {
|
||||
peq[a.charCodeAt(i)] = 0;
|
||||
}
|
||||
return sc;
|
||||
};
|
||||
const myers_x = (b, a) => {
|
||||
const n = a.length;
|
||||
const m = b.length;
|
||||
const mhc = [];
|
||||
const phc = [];
|
||||
const hsize = Math.ceil(n / 32);
|
||||
const vsize = Math.ceil(m / 32);
|
||||
for (let i = 0; i < hsize; i++) {
|
||||
phc[i] = -1;
|
||||
mhc[i] = 0;
|
||||
}
|
||||
let j = 0;
|
||||
for (; j < vsize - 1; j++) {
|
||||
let mv = 0;
|
||||
let pv = -1;
|
||||
const start = j * 32;
|
||||
const vlen = Math.min(32, m) + start;
|
||||
for (let k = start; k < vlen; k++) {
|
||||
peq[b.charCodeAt(k)] |= 1 << k;
|
||||
}
|
||||
for (let i = 0; i < n; i++) {
|
||||
const eq = peq[a.charCodeAt(i)];
|
||||
const pb = (phc[(i / 32) | 0] >>> i) & 1;
|
||||
const mb = (mhc[(i / 32) | 0] >>> i) & 1;
|
||||
const xv = eq | mv;
|
||||
const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;
|
||||
let ph = mv | ~(xh | pv);
|
||||
let mh = pv & xh;
|
||||
if ((ph >>> 31) ^ pb) {
|
||||
phc[(i / 32) | 0] ^= 1 << i;
|
||||
}
|
||||
if ((mh >>> 31) ^ mb) {
|
||||
mhc[(i / 32) | 0] ^= 1 << i;
|
||||
}
|
||||
ph = (ph << 1) | pb;
|
||||
mh = (mh << 1) | mb;
|
||||
pv = mh | ~(xv | ph);
|
||||
mv = ph & xv;
|
||||
}
|
||||
for (let k = start; k < vlen; k++) {
|
||||
peq[b.charCodeAt(k)] = 0;
|
||||
}
|
||||
}
|
||||
let mv = 0;
|
||||
let pv = -1;
|
||||
const start = j * 32;
|
||||
const vlen = Math.min(32, m - start) + start;
|
||||
for (let k = start; k < vlen; k++) {
|
||||
peq[b.charCodeAt(k)] |= 1 << k;
|
||||
}
|
||||
let score = m;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const eq = peq[a.charCodeAt(i)];
|
||||
const pb = (phc[(i / 32) | 0] >>> i) & 1;
|
||||
const mb = (mhc[(i / 32) | 0] >>> i) & 1;
|
||||
const xv = eq | mv;
|
||||
const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;
|
||||
let ph = mv | ~(xh | pv);
|
||||
let mh = pv & xh;
|
||||
score += (ph >>> (m - 1)) & 1;
|
||||
score -= (mh >>> (m - 1)) & 1;
|
||||
if ((ph >>> 31) ^ pb) {
|
||||
phc[(i / 32) | 0] ^= 1 << i;
|
||||
}
|
||||
if ((mh >>> 31) ^ mb) {
|
||||
mhc[(i / 32) | 0] ^= 1 << i;
|
||||
}
|
||||
ph = (ph << 1) | pb;
|
||||
mh = (mh << 1) | mb;
|
||||
pv = mh | ~(xv | ph);
|
||||
mv = ph & xv;
|
||||
}
|
||||
for (let k = start; k < vlen; k++) {
|
||||
peq[b.charCodeAt(k)] = 0;
|
||||
}
|
||||
return score;
|
||||
};
|
||||
const distance = (a, b) => {
|
||||
if (a.length < b.length) {
|
||||
const tmp = b;
|
||||
b = a;
|
||||
a = tmp;
|
||||
}
|
||||
if (b.length === 0) {
|
||||
return a.length;
|
||||
}
|
||||
if (a.length <= 32) {
|
||||
return myers_32(a, b);
|
||||
}
|
||||
return myers_x(a, b);
|
||||
};
|
||||
const closest = (str, arr) => {
|
||||
let min_distance = Infinity;
|
||||
let min_index = 0;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const dist = distance(str, arr[i]);
|
||||
if (dist < min_distance) {
|
||||
min_distance = dist;
|
||||
min_index = i;
|
||||
}
|
||||
}
|
||||
return arr[min_index];
|
||||
};
|
||||
export { closest, distance };
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,46 @@
|
||||
var rule = {
|
||||
title: '盘他',
|
||||
host: 'https://sousou.pro',
|
||||
searchUrl: '/search?exact=false&page=fypage&q=**&share_time=&type=&user=',
|
||||
searchable: 2,
|
||||
quickSearch: 0,
|
||||
headers: {
|
||||
'User-Agent': 'PC_UA',
|
||||
},
|
||||
timeout: 5000,
|
||||
play_parse: true,
|
||||
lazy: $js.toString(() => {
|
||||
let url = input.startsWith('push://') ? input : 'push://' + input;
|
||||
input = {parse: 0, url: url};
|
||||
}),
|
||||
一级: '',
|
||||
二级: $js.toString(() => {
|
||||
VOD = {};
|
||||
VOD.vod_id = input;
|
||||
let html = request(input);
|
||||
let title = pdfh(html, 'h1&&Text');
|
||||
let share_url = pdfh(html, '.semi-typography-link:eq(-1)&&a&&href');
|
||||
let share_type = pdfh(html, '.semi-descriptions-value:eq(3)&&Text');
|
||||
VOD.vod_name = title;
|
||||
VOD.vod_pic = '';
|
||||
VOD.content = share_url;
|
||||
VOD.vod_remarks = pdfh(html, '.semi-descriptions-value&&Text');
|
||||
VOD.vod_play_from = '点击下方播放';
|
||||
VOD.vod_play_url = share_type + '$' + 'push://' + share_url;
|
||||
}),
|
||||
搜索: $js.toString(() => {
|
||||
let html = request(input);
|
||||
let data = pdfa(html, '.rm-search-content&&.semi-space-vertical');
|
||||
let d = [];
|
||||
data.forEach(it => {
|
||||
d.push({
|
||||
title: pdfh(it, 'a&&title'),
|
||||
desc: pdfh(it, 'span:eq(3)&&Text') + '|' + pdfh(it, 'span:eq(-1)&&Text'),
|
||||
img: "",
|
||||
url: pd(it, 'a&&href', MY_URL)
|
||||
});
|
||||
|
||||
});
|
||||
setResult(d);
|
||||
}),
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
{
|
||||
"规则名": "河马短剧",
|
||||
"规则作者": "香雅情",
|
||||
"请求头参数": "MOBILE_UA",
|
||||
"网页编码格式": "UTF-8",
|
||||
"图片是否需要代理": "否",
|
||||
"是否开启获取首页数据": "否",
|
||||
"首页推荐链接": "https://www.kuaikaw.cn",
|
||||
"首页列表数组规则": "body&&.module-items",
|
||||
"首页片单列表数组规则": ".module-item:lt(12)",
|
||||
"首页片单是否Jsoup写法": "1",
|
||||
"分类起始页码": "1",
|
||||
"分类链接": "https://www.kuaikaw.cn/browse/{cateId}/{catePg}[firstPage=https://www.kuaikaw.cn/browse/{cateId}]",
|
||||
"分类名称": "全部",
|
||||
"分类名称替换词": "0",
|
||||
//"筛选数据": {},
|
||||
"筛选数据": "ext",
|
||||
//{cateId}
|
||||
"筛选子分类名称": "全部&民国&萌宝&动漫&超能&甜宠&豪门恩怨&长生&神医&寻亲&抗战谍战&电视剧&奇幻&闪婚&职场商战&权谋&高手下山&神话&时空之旅&欢喜冤家&都市&体育&家庭&喜剧&都市修仙&神豪&科幻&致富&奇幻脑洞&强者回归&励志&复仇&电影&马甲&亲情&小人物&无敌&现实&重生&穿越&年代&悬疑&婚姻&家国情仇&虐恋&古装&仙侠&玄幻仙侠&传承觉醒&功夫武打&戏曲歌舞&情感&逆袭&战争",
|
||||
"筛选子分类替换词": "0&590-839&589&1115&442&462&585&1073&438&1125&1093&1092-1097&715&713&943&840-1101&474&1094&718&717&1129&1128&714-1126&917&1124&475&1130&918&721&476&1076-1100&416-463&1091-1096&719&835-837&472&1074&441-469&439-465&916&716-722&445-470&1127&915&466&444-468&1102&720&473&1095&1098&838&417-464&1099",
|
||||
//{class}
|
||||
"筛选类型名称": "",
|
||||
"筛选类型替换词": "*",
|
||||
//{area}
|
||||
"筛选地区名称": "",
|
||||
"筛选地区替换词": "*",
|
||||
//{year}
|
||||
"筛选年份名称": "",
|
||||
"筛选年份替换词": "*",
|
||||
//{lang}
|
||||
"筛选语言名称": "",
|
||||
"筛选语言替换词": "*",
|
||||
//{by}
|
||||
"筛选排序名称": "时间&人气&评分",
|
||||
"筛选排序替换词": "time&hits&score",
|
||||
"分类截取模式": "1",
|
||||
"分类列表数组规则": ".BrowseList_listBox__MyeBa&&.BrowseList_listItem__h7lD4",
|
||||
"分类片单是否Jsoup写法": "是",
|
||||
"分类片单标题": "img&&alt",
|
||||
"分类片单链接": "a&&href",
|
||||
"分类片单图片": "img&&src",
|
||||
"分类片单副标题": ".BrowseList_lastChapter__dkL54&&Text",
|
||||
"分类片单链接加前缀": "https://www.kuaikaw.cn",
|
||||
"分类片单链接加后缀": "",
|
||||
"搜索请求头参数": "User-Agent$MOBILE_UA",
|
||||
"搜索链接": "https://www.kuaikaw.cn/search/{SearchPg}?searchValue={wd}",
|
||||
"POST请求数据": "",
|
||||
"搜索截取模式": "1",
|
||||
"搜索列表数组规则": ".search_searchList__AvbeR&&.MTagBookList_tagBookItem__C_038",
|
||||
"搜索片单是否Jsoup写法": "是",
|
||||
"搜索片单图片": "img&&src",
|
||||
"搜索片单标题": "img&&alt",
|
||||
"搜索片单链接": "a&&href",
|
||||
"搜索片单副标题": "",
|
||||
"搜索片单链接加前缀": "https://www.kuaikaw.cn",
|
||||
"搜索片单链接加后缀": "",
|
||||
"链接是否直接播放": "否",
|
||||
"直接播放链接加前缀": "",
|
||||
"直接播放链接加后缀": "",
|
||||
"直接播放直链视频请求头": "",
|
||||
"详情是否Jsoup写法": "是",
|
||||
"类型详情": "",
|
||||
"年代详情": "",
|
||||
"地区详情": "",
|
||||
"演员详情": "",
|
||||
"简介详情": ".introduction_introBox__t4Bbz&&Text",
|
||||
"线路列表数组规则": "",
|
||||
"线路标题": "Text",
|
||||
"播放列表数组规则": "body&&.CatalogList_swiperBox__5kdPs",
|
||||
"选集列表数组规则": "a:not(:has(img))",
|
||||
"选集标题链接是否Jsoup写法": "是",
|
||||
"选集标题": "a&&Text",
|
||||
"选集链接": "a&&href",
|
||||
"是否反转选集序列": "否",
|
||||
"选集链接加前缀": "https://www.kuaikaw.cn",
|
||||
"选集链接加后缀": "",
|
||||
"分析MacPlayer": "否",
|
||||
"是否开启手动嗅探": "否",
|
||||
"手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos",
|
||||
"手动嗅探视频链接过滤词": ".html#=http"
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
{
|
||||
"规则名": "爱你短剧",
|
||||
"规则作者": "香雅情",
|
||||
"请求头参数": "MOBILE_UA",
|
||||
"网页编码格式": "UTF-8",
|
||||
"图片是否需要代理": "否",
|
||||
"是否开启获取首页数据": "是",
|
||||
"首页推荐链接": "https://ainidj.com/",
|
||||
"首页列表数组规则": "body&&.module-items",
|
||||
"首页片单列表数组规则": ".module-item:lt(12)",
|
||||
"首页片单是否Jsoup写法": "1",
|
||||
"分类起始页码": "1",
|
||||
"分类链接": "https://ainidj.com/vodshwo/{cateId}--------{catePg}---.html",
|
||||
"分类名称": "穿越&战神&重生&爱情&萌娃&神医&古代&玄幻&言情",
|
||||
"分类名称替换词": "fenle&fenlei2&fenlei3&fenlei4&guda&shenyi&gudai&xuanhuan&yanqing",
|
||||
"筛选数据": {},
|
||||
//"筛选数据": "ext",
|
||||
//{cateId}
|
||||
"筛选子分类名称": "",
|
||||
"筛选子分类替换词": "",
|
||||
//{class}
|
||||
"筛选类型名称": "",
|
||||
"筛选类型替换词": "*",
|
||||
//{area}
|
||||
"筛选地区名称": "",
|
||||
"筛选地区替换词": "*",
|
||||
//{year}
|
||||
"筛选年份名称": "",
|
||||
"筛选年份替换词": "*",
|
||||
//{lang}
|
||||
"筛选语言名称": "",
|
||||
"筛选语言替换词": "*",
|
||||
//{by}
|
||||
"筛选排序名称": "时间&人气&评分",
|
||||
"筛选排序替换词": "time&hits&score",
|
||||
"分类截取模式": "1",
|
||||
"分类列表数组规则": ".module-items&&.module-item",
|
||||
"分类片单是否Jsoup写法": "是",
|
||||
"分类片单标题": ".video-name&&Text",
|
||||
"分类片单链接": "a&&href",
|
||||
"分类片单图片": ".lazy&&data-src",
|
||||
"分类片单副标题": ".module-item-text&&Text",
|
||||
"分类片单链接加前缀": "https://ainidj.com",
|
||||
"分类片单链接加后缀": "",
|
||||
"搜索请求头参数": "User-Agent$MOBILE_UA",
|
||||
"搜索链接": "https://ainidj.com/vodsearch/{wd}----------{SearchPg}---.html",
|
||||
"POST请求数据": "",
|
||||
"搜索截取模式": "1",
|
||||
"搜索列表数组规则": ".module-items&&.module-search-item",
|
||||
"搜索片单是否Jsoup写法": "是",
|
||||
"搜索片单图片": ".lazyload&&data-src",
|
||||
"搜索片单标题": ".video-info&&h3&&Text",
|
||||
"搜索片单链接": "a&&href",
|
||||
"搜索片单副标题": ".video-serial&&Text",
|
||||
"搜索片单链接加前缀": "https://ainidj.com",
|
||||
"搜索片单链接加后缀": "",
|
||||
"链接是否直接播放": "否",
|
||||
"直接播放链接加前缀": "",
|
||||
"直接播放链接加后缀": "",
|
||||
"直接播放直链视频请求头": "",
|
||||
"详情是否Jsoup写法": "是",
|
||||
"类型详情": "",
|
||||
"年代详情": "",
|
||||
"地区详情": "",
|
||||
"演员详情": "",
|
||||
"简介详情": ".video-info-main&&.video-info-content&&Text",
|
||||
"线路列表数组规则": ".module-tab-items&&.module-tab-item",
|
||||
"线路标题": "Text",
|
||||
"播放列表数组规则": "body&&.module-player-list",
|
||||
"选集列表数组规则": ".scroll-content&&a",
|
||||
"选集标题链接是否Jsoup写法": "是",
|
||||
"选集标题": "a&&Text",
|
||||
"选集链接": "a&&href",
|
||||
"是否反转选集序列": "否",
|
||||
"选集链接加前缀": "https://ainidj.com",
|
||||
"选集链接加后缀": "",
|
||||
"分析MacPlayer": "否",
|
||||
"是否开启手动嗅探": "否",
|
||||
"手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos",
|
||||
"手动嗅探视频链接过滤词": ".html#=http"
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
{
|
||||
"规则名": "短剧屋",
|
||||
"规则作者": "",
|
||||
"请求头参数": "手机",
|
||||
"网页编码格式": "UTF-8",
|
||||
"图片是否需要代理": "0",
|
||||
"是否开启获取首页数据": "1",
|
||||
"首页推荐链接": "http://www.metaysw.com",
|
||||
"首页列表数组规则": "body&&.vod-vodlist",
|
||||
"首页片单列表数组规则": "li",
|
||||
"首页片单是否Jsoup写法": "1",
|
||||
"分类起始页码": "1",
|
||||
"分类链接": "http://www.metaysw.com/type/{cateId}-{catePg}.html",
|
||||
"分类名称": "短剧",
|
||||
"分类名称替换词": "lianxuju",
|
||||
"筛选数据": {},
|
||||
//"筛选数据": "ext",
|
||||
//{cateId}
|
||||
"筛选子分类名称": "",
|
||||
"筛选子分类替换词": "",
|
||||
//{class}
|
||||
"筛选类型名称": "",
|
||||
"筛选类型替换词": "*",
|
||||
//{area}
|
||||
"筛选地区名称": "",
|
||||
"筛选地区替换词": "*",
|
||||
//{year}
|
||||
"筛选年份名称": "",
|
||||
"筛选年份替换词": "*",
|
||||
//{lang}
|
||||
"筛选语言名称": "",
|
||||
"筛选语言替换词": "*",
|
||||
//{by}
|
||||
"筛选排序名称": "时间&人气&评分",
|
||||
"筛选排序替换词": "time&hits&score",
|
||||
"分类截取模式": "1",
|
||||
"分类列表数组规则": ".vod-vodlist&&li",
|
||||
"分类片单是否Jsoup写法": "1",
|
||||
"分类片单标题": ".vod-vodlist__title&&Text",
|
||||
"分类片单链接": "a&&href",
|
||||
"分类片单图片": ".lazyload&&data-original",
|
||||
"分类片单副标题": ".pic-text&&Text",
|
||||
"分类片单链接加前缀": "http://www.metaysw.com",
|
||||
"分类片单链接加后缀": "",
|
||||
"搜索请求头参数": "User-Agent$手机",
|
||||
"搜索链接": "http://www.metaysw.com/search/page/{SearchPg}/wd/{wd}.html",
|
||||
"POST请求数据": "",
|
||||
"搜索截取模式": "1",
|
||||
"搜索列表数组规则": ".vod-vodlist&&li",
|
||||
"搜索片单是否Jsoup写法": "1",
|
||||
"搜索片单图片": ".lazyload&&data-original",
|
||||
"搜索片单标题": ".vod-vodlist__title&&Text",
|
||||
"搜索片单链接": "a&&href",
|
||||
"搜索片单副标题": ".pic-text&&Text",
|
||||
"搜索片单链接加前缀": "http://www.metaysw.com",
|
||||
"搜索片单链接加后缀": "",
|
||||
"链接是否直接播放": "0",
|
||||
"直接播放链接加前缀": "https://live.52sf.ga/huya/",
|
||||
"直接播放链接加后缀": "#isVideo=true#",
|
||||
"直接播放直链视频请求头": "authority$ku.peizq.online#Referer$https://play.peizq.online",
|
||||
"详情是否Jsoup写法": "1",
|
||||
"类型详情": "",
|
||||
"年代详情": "",
|
||||
"地区详情": "",
|
||||
"演员详情": ".vod-content__detail&&p,2&&Text!主演:",
|
||||
"简介详情": "",
|
||||
"线路列表数组规则": ".dropdown-menu&&li",
|
||||
"线路标题": "a&&Text",
|
||||
"播放列表数组规则": "body&&.vod-content__playlist",
|
||||
"选集列表数组规则": "li",
|
||||
"选集标题链接是否Jsoup写法": "1",
|
||||
"选集标题": "a&&Text",
|
||||
"选集链接": "a&&href",
|
||||
"是否反转选集序列": "0",
|
||||
"选集链接加前缀": "http://www.metaysw.com",
|
||||
"选集链接加后缀": "",
|
||||
"分析MacPlayer": "0",
|
||||
"是否开启手动嗅探": "0",
|
||||
"手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos",
|
||||
"手动嗅探视频链接过滤词": ".html#=http"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
5413385930b3f95e55a36c821e3a1779
|
||||
ce7057ea0547c6dfc6cd21eabeadd1bc
|
||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
da71a187983dfd583dbbeec77a0014c3
|
||||
487dc24f27bca7a8b8df7a83b28bc85d
|
||||
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* @Author: jadehh
|
||||
* @Date: 2024-06-21 15:47:27
|
||||
* @LastEditTime: 2024-06-21 16:20:30
|
||||
* @LastEditors: jadehh
|
||||
* @Description:
|
||||
* @FilePath: \TVSpider\js\xgcartoon.js
|
||||
* @
|
||||
*/
|
||||
import * as Utils from "../lib/utils.js";
|
||||
import {_, load} from "../lib/cat.js";
|
||||
import {VodDetail, VodShort} from "../lib/vod.js";
|
||||
import {Spider} from "./spider.js";
|
||||
|
||||
|
||||
class XGCartoonSpider extends Spider {
|
||||
constructor() {
|
||||
super();
|
||||
this.siteUrl = "https://cn.xgcartoon.com/"
|
||||
this.nextObj = {}
|
||||
}
|
||||
|
||||
|
||||
getName() {
|
||||
return `🍉┃西瓜卡通┃🍉`
|
||||
}
|
||||
|
||||
getAppName() {
|
||||
return "西瓜卡通"
|
||||
}
|
||||
|
||||
|
||||
getJSName() {
|
||||
return "xgcartoon"
|
||||
}
|
||||
|
||||
getType() {
|
||||
return 3
|
||||
}
|
||||
|
||||
|
||||
async setClasses() {
|
||||
let $ = await this.getHtml(this.siteUrl)
|
||||
let navElements = $('[class="index-tab"]').find("a")
|
||||
for (const navElement of navElements){
|
||||
let type_name = $(navElement).text()
|
||||
let type_id = navElement.attribs.href
|
||||
this.classes.push(this.getTypeDic(type_name,type_id))
|
||||
}
|
||||
let x = 0
|
||||
}
|
||||
|
||||
|
||||
async parseVodShortListFromJson(obj) {
|
||||
let vod_list = []
|
||||
for (const data of obj) {
|
||||
let vodShort = new VodShort()
|
||||
vodShort.vod_id = data["vodId"]
|
||||
vodShort.vod_name = data["vodName"]
|
||||
vodShort.vod_remarks = data["watchingCountDesc"]
|
||||
vodShort.vod_pic = data["coverImg"]
|
||||
vod_list.push(vodShort)
|
||||
}
|
||||
return vod_list
|
||||
}
|
||||
|
||||
async parseVodDetailfromJson(obj) {
|
||||
let vodDetail = new VodDetail()
|
||||
|
||||
return vodDetail
|
||||
}
|
||||
|
||||
async setHomeVod() {
|
||||
|
||||
}
|
||||
|
||||
async setCategory(tid, pg, filter, extend) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
async setDetail(id) {
|
||||
|
||||
}
|
||||
|
||||
async setPlay(flag, id, flags) {
|
||||
|
||||
}
|
||||
|
||||
async setSearch(wd, quick) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let spider = new XGCartoonSpider()
|
||||
|
||||
async function init(cfg) {
|
||||
await spider.init(cfg)
|
||||
}
|
||||
|
||||
async function home(filter) {
|
||||
return await spider.home(filter)
|
||||
}
|
||||
|
||||
async function homeVod() {
|
||||
return await spider.homeVod()
|
||||
}
|
||||
|
||||
async function category(tid, pg, filter, extend) {
|
||||
return await spider.category(tid, pg, filter, extend)
|
||||
}
|
||||
|
||||
async function detail(id) {
|
||||
return await spider.detail(id)
|
||||
}
|
||||
|
||||
async function play(flag, id, flags) {
|
||||
return await spider.play(flag, id, flags)
|
||||
}
|
||||
|
||||
async function search(wd, quick) {
|
||||
return await spider.search(wd, quick)
|
||||
}
|
||||
|
||||
async function proxy(segments, headers) {
|
||||
return await spider.proxy(segments, headers)
|
||||
}
|
||||
|
||||
export function __jsEvalReturn() {
|
||||
return {
|
||||
init: init,
|
||||
home: home,
|
||||
homeVod: homeVod,
|
||||
category: category,
|
||||
detail: detail,
|
||||
play: play,
|
||||
search: search,
|
||||
proxy: proxy
|
||||
};
|
||||
}
|
||||
export {spider}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
44bf43085a1fbd3818e0c0fd83893c2b
|
||||
13d9a625af09fa3ffd1cc1aa85cf1c1c
|
||||
|
||||
Binary file not shown.
@ -1 +1 @@
|
||||
81a8027bbbef9e390bdc51701ce81db3
|
||||
ba15a5c932fd04fbf8966755f12a7072
|
||||
|
||||
Loading…
Reference in new issue