up
This commit is contained in:
Liu
2025-04-19 02:27:03 +08:00
parent d1d1f8d50e
commit 51664d962d
20 changed files with 87862 additions and 21880 deletions

View File

@@ -1,6 +1,7 @@
{
"spider": "./spider.jar",
"wallpaper": "https://xn--11x805d.xn--4kq62z5rby2qupq9ub.xyz/",
"wallpaper": "https://t.alcy.cc/fj",
"sites": [
{
"key": "豆豆",
@@ -247,7 +248,7 @@
"type": 3,
"quickSearch": 1,
"changeable": "0",
"api": "csp_MiSouGuard",
"api": "csp_XiaoYiGuard",
"ext": ""
},
{
@@ -290,9 +291,24 @@
"url": "影视"
},
{
"name": "自用",
"name": "巧技三",
"type": 1,
"url": ""
"url": "https://zy.qiaoji8.com/xiafan.php?url=",
"ext": {
"flag": [
"QD4K",
"iyf",
"duanju",
"gzcj",
"GTV",
"GZYS",
"weggz",
"Ace"
],
"header": {
"User-Agent": "okhttp/4.9.1"
}
}
},
{
"name": "8090g",

View File

@@ -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('&amp;')
.split('<').join('&lt;')
.split('>').join('&gt;')
.split('"').join('&quot;');
},
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 it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -4,9 +4,9 @@
"spider": "./spider.jar",
"lives": [
{
"name": "【公众号欧歌APP】测试完请删除,请勿贩卖",
"name": "【公众号光歌软件分享】永久免费,请勿演示贩卖",
"type": 0,
"url": "./lives/【公众号欧歌APP】测试完请删除,请勿贩卖.txt",
"url": "./lives/【公众号光歌软件分享】永久免费,请勿演示贩卖.txt",
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
"logo":"https://live.fanmingming.cn/tv/{name}.png",
"playerType":2,
@@ -15,7 +15,7 @@
{
"name": "胖羊直播",
"type": 3,
"api":"csp_Feiyang",
"api":"csp_Feiyang",
"url": "./lives/胖羊直播.txt",
"timeout":10,
"ua":"okhttp/3.15",
@@ -25,7 +25,7 @@
"name": "AI直播",
"type": 0,
"url": "./lives/AI直播.txt",
"epg":"http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
"epg":"http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
"logo":"https://live.fanmingming.cn/tv/{name}.png",
"playerType":2,
"timeout":10
@@ -41,41 +41,20 @@
"sites": [
{
"key": "豆瓣2",
"name": "📢【公众号欧歌APP】测试完请删除,请勿贩卖",
"name": "📢【公众号光歌软件分享】永久免费,请勿演示贩卖",
"type": 3,
"api": "csp_Douban",
"searchable": 0
},
{
"key": "豆瓣1",
"name": "📢【公众号欧歌APP】测试完请删除,请勿贩卖公告❤更新:4/14❤",
"name": "📢【公众号光歌软件分享】永久免费,请勿演示贩卖公告❤更新:4/17❤",
"type": 3,
"api": "csp_Notice",
"searchable": 0,
"changeable": 0,
"jar": "./jars/豆瓣1.jar",
"ext": "https://xn--dkw0c.v.nxog.top/m//公告.php?b=【公众号欧歌APP】测试完请删除,请勿贩卖"
},
{
"key": "config",
"name": "🐲玩欧┃配置中心",
"type": 3,
"jar": "./jars/config.jar",
"api": "csp_Config",
"searchable": 0
},
{
"key": "配置中心",
"name": "❤配置|中心",
"type": 3,
"api": "csp_Config",
"searchable": 0,
"changeable": 0,
"indexs": 0,
"style": {
"type": "rect",
"ratio": 1.597
}
"ext": "https://xn--dkw0c.v.nxog.top/m//公告.php?b=【公众号光歌软件分享】永久免费,请勿演示贩卖"
},
{
"key": "csp_woog",
@@ -92,31 +71,49 @@
],
"url_key": "woog",
"threadinfo": {
"chunksize": 400,
"chunksize": 300,
"threads": 10
}
}
},
{
"key": "csp_woog2",
"name": "🐲玩欧非会员4K",
"key": "config",
"name": "🐲玩欧┃配置",
"type": 3,
"jar": "./jars/config.jar",
"api": "csp_Config",
"searchable": 0
},
{
"key": "csp_woogkk",
"name": "🐲夸快┃非会员4K",
"type": 3,
"changeable": "0",
"api": "csp_DuopanGuard",
"api": "csp_woog",
"filterable": 1,
"jar": "./jars/csp_woog.jar",
"jar": "./jars/csp_woogkk.jar",
"ext": {
"site_urls": [
"https://woog.xn--dkw.xn--6qq986b3xl",
"https://woog.nxog.eu.org"
"hhttps://ogkk.nxog.eu.org",
"https://ogkk.xn--dkw.xn--6qq986b3xl"
],
"url_key": "woog2",
"url_key": "woogkk",
"threadinfo": {
"chunksize": 400,
"chunksize": 282,
"threads": 60
}
}
},
{
"key": "csp_欧歌123",
"name": "🐲夸快┃配置",
"type": 3,
"api": "csp_Config",
"searchable": 0,
"quickSearch": 0,
"filterable": 1,
"jar": "./jars/csp_欧歌123.jar"
},
{
"key": "欧哥",
"name": "❤欧歌4K弹幕",
@@ -128,6 +125,19 @@
"changeable": 1,
"ext": "./json/og.json?"
},
{
"key": "配置中心",
"name": "❤配置|中心",
"type": 3,
"api": "csp_Config",
"searchable": 0,
"changeable": 0,
"indexs": 0,
"style": {
"type": "rect",
"ratio": 1.597
}
},
{
"key": "荐片",
"name": "💡荐片|影视",
@@ -264,50 +274,6 @@
"quickSearch": 1,
"filterable": 1
},
{
"key": "猎手影视",
"name": "💡猎手|影视",
"type": 3,
"api": "./api/猎手影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "火车影视",
"name": "💡火车|影视",
"type": 3,
"api": "./api/火车影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "美帕影视",
"name": "💡美帕|影视",
"type": 3,
"api": "./api/美帕影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "嗨皮影视",
"name": "💡嗨皮|影视",
"type": 3,
"api": "./api/嗨皮影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "厂长影视",
"name": "💡厂长|影视",
@@ -380,17 +346,9 @@
"playerType": 2,
"ext": "https://shdy5.us"
},
{
"key": "光速",
"name": "💡光速|影视",
"type": 3,
"api": "csp_Xdai",
"playerType": 1,
"ext": "jaHR0cDovLzU5LjE1My4xNjcuMTM3Ojg4OTl8NGQ4M2I4N2M0YzVlYTExMXw0ZDgzYjg3YzRjNWVhMTExfDQ2Mg=="
},
{
"key": "现代",
"name": "💡现代|APP",
"name": "💡现代|影视",
"type": 3,
"api": "csp_Xdai",
"playerType": 1,
@@ -470,9 +428,75 @@
"api": "csp_AppFerr",
"ext": "sHR2rlsfjI4L3t4RXQMkn/M3t4AXAKTrZj3tfhm1t/gMT3dOrHqIzUNqLUEOIDMvllTbX6e1hMhB2mfpOaCmHNOL1yBB3SmxNyqXlai90EIpdnwOOgCR9Z+YwCTj6ySjzJ2VBiH3eXeOGcavcNeVRA=="
},
{
"key": "猎手影视",
"name": "🧡猎手PY影视",
"type": 3,
"api": "./api/猎手影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "火车影视",
"name": "🧡火车PY影视",
"type": 3,
"api": "./api/火车影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "嗨皮影视",
"name": "🧡嗨皮PY影视",
"type": 3,
"api": "./api/嗨皮影视.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "边缘",
"name": "🧡边缘PY影视",
"type": 3,
"api": "./api/边缘影视APP.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "若惜",
"name": "🧡若惜PY影视",
"type": 3,
"api": "./api/若惜追剧APP.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "悠悠",
"name": "🧡悠悠PY影视",
"type": 3,
"api": "./api/悠悠APP.py",
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
"filterable": 1,
"playerType": 2
},
{
"key": "csp_XYQHiker_农民影视",
"name": "🧿农民|影视",
"name": "🧿农民|XBPQ",
"type": 3,
"api": "csp_XYQHiker",
"searchable": 1,
@@ -482,7 +506,7 @@
},
{
"key": "嫖嫖嫖",
"name": "🧿嫖嫖┃影视",
"name": "🧿嫖嫖┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"ext": {
@@ -512,7 +536,7 @@
},
{
"key": "白嫖者",
"name": "🧿白嫖┃影视",
"name": "🧿白嫖┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"ext": {
@@ -524,7 +548,7 @@
},
{
"key": "656",
"name": "🧿梦想┃影视",
"name": "🧿梦想┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"searchable": 1,
@@ -564,7 +588,7 @@
},
{
"key": "8号影院",
"name": "🧿8号┃影视",
"name": "🧿8号┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"searchable": 1,
@@ -582,7 +606,7 @@
},
{
"key": "csp_红狐狸影视",
"name": "🧿狐狸┃影视",
"name": "🧿狐狸┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"ext": {
@@ -592,7 +616,7 @@
},
{
"key": "大师兄",
"name": "🧿大师┃影视",
"name": "🧿大师┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"ext": {
@@ -602,7 +626,7 @@
},
{
"key": "疯狗",
"name": "🧿疯狗┃影视",
"name": "🧿疯狗┃XBPQ",
"type": 3,
"api": "csp_XBPQ",
"ext": {

220
欧歌/api/悠悠APP.py Normal file
View File

@@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
# by @嗷呜
import re
import sys
from Crypto.Hash import MD5
sys.path.append("..")
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from urllib.parse import quote, urlparse
from base64 import b64encode, b64decode
import json
import time
from base.spider import Spider
class Spider(Spider):
def init(self, extend=""):
self.host = self.gethost()
pass
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def action(self, action):
pass
def destroy(self):
pass
def homeContent(self, filter):
data = self.getdata("/api.php/getappapi.index/initV119")
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
"sort": "排序"}
filters = {}
classes = []
json_data = data["type_list"]
homedata = data["banner_list"][8:]
for item in json_data:
if item["type_name"] == "全部":
continue
has_non_empty_field = False
jsontype_extend = json.loads(item["type_extend"])
homedata.extend(item["recommend_list"])
jsontype_extend["sort"] = "最新,最热,最赞"
classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
for key in dy:
if key in jsontype_extend and jsontype_extend[key].strip() != "":
has_non_empty_field = True
break
if has_non_empty_field:
filters[str(item["type_id"])] = []
for dkey in jsontype_extend:
if dkey in dy and jsontype_extend[dkey].strip() != "":
values = jsontype_extend[dkey].split(",")
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
value.strip() != ""]
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
result = {}
result["class"] = classes
result["filters"] = filters
result["list"] = homedata[1:]
return result
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
body = {"area": extend.get('area', '全部'), "year": extend.get('year', '全部'), "type_id": tid, "page": pg,
"sort": extend.get('sort', '最新'), "lang": extend.get('lang', '全部'),
"class": extend.get('class', '全部')}
result = {}
data = self.getdata("/api.php/getappapi.index/typeFilterVodList", body)
result["list"] = data["recommend_list"]
result["page"] = pg
result["pagecount"] = 9999
result["limit"] = 90
result["total"] = 999999
return result
def detailContent(self, ids):
body = f"vod_id={ids[0]}"
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
vod = data["vod"]
play = []
names = []
for itt in data["vod_play_list"]:
a = []
names.append(itt["player_info"]["show"])
for it in itt['urls']:
it['user_agent']=itt["player_info"].get("user_agent")
it["parse"]=itt["player_info"].get("parse")
a.append(f"{it['name']}${self.e64(json.dumps(it))}")
play.append("#".join(a))
vod["vod_play_from"] = "$$$".join(names)
vod["vod_play_url"] = "$$$".join(play)
result = {"list": [vod]}
return result
def searchContent(self, key, quick, pg="1"):
body = f"keywords={key}&type_id=0&page={pg}"
data = self.getdata("/api.php/getappapi.index/searchList", body)
result = {"list": data["search_list"], "page": pg}
return result
def playerContent(self, flag, id, vipFlags):
ids = json.loads(self.d64(id))
h = {"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
try:
if re.search(r'url=', ids['parse_api_url']):
data = self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
url = data.get('url') or data['data'].get('url')
else:
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'], True))}&token={ids.get('token')}"
b = self.getdata("/api.php/getappapi.index/vodParse", body)['json']
url = json.loads(b)['url']
if 'error' in url: raise ValueError(f"解析失败: {url}")
p = 0
except Exception as e:
print('错误信息:', e)
url, p = ids['url'], 1
if re.search(r'\.jpg|\.png|\.jpeg', url):
url = self.Mproxy(url)
result = {}
result["parse"] = p
result["url"] = url
result["header"] = h
return result
def localProxy(self, param):
return self.Mlocal(param)
def gethost(self):
headers = {
'User-Agent': 'okhttp/3.14.9'
}
host = self.fetch('http://host.yyys.news/250123.txt', headers=headers).text
return host.strip()
phend = {
'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 11; M2012K10C Build/RP1A.200720.011)',
'allowCrossProtocolRedirects': 'true'
}
def aes(self, text,b=None):
key = b"RuN9LRvwTRgpQnpK"
cipher = AES.new(key, AES.MODE_CBC, key)
if b:
ct_bytes = cipher.encrypt(pad(text.encode("utf-8"), AES.block_size))
ct = b64encode(ct_bytes).decode("utf-8")
return ct
else :
pt = unpad(cipher.decrypt(b64decode(text)), AES.block_size)
return pt.decode("utf-8")
def header(self):
t = str(int(time.time()))
header = {"Referer":self.host,
"User-Agent": "okhttp/3.14.9", "app-version-code": "547", "app-ui-mode": "light",
"app-api-verify-time": t, "app-user-device-id": self.md5(t),
"app-api-verify-sign": self.aes(t,True),
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
return header
def getdata(self, path, data=None):
vdata = self.post(f"{self.host}{path}", headers=self.header(), data=data, timeout=10).json()['data']
data1 = self.aes(vdata)
return json.loads(data1)
def Mproxy(self, url):
return f"{self.getProxyUrl()}&url={self.e64(url)}&type=m3u8"
def Mlocal(self, param,header=None):
url = self.d64(param["url"])
ydata = self.fetch(url, headers=header, allow_redirects=False)
data = ydata.content.decode('utf-8')
if ydata.headers.get('Location'):
url = ydata.headers['Location']
data = self.fetch(url, headers=header).content.decode('utf-8')
parsed_url = urlparse(url)
durl = parsed_url.scheme + "://" + parsed_url.netloc
lines = data.strip().split('\n')
for index, string in enumerate(lines):
if '#EXT' not in string and 'http' not in string:
last_slash_index = string.rfind('/')
lpath = string[:last_slash_index + 1]
lines[index] = durl + ('' if lpath.startswith('/') else '/') + lpath
data = '\n'.join(lines)
return [200, "application/vnd.apple.mpegur", data]
def e64(self, text):
try:
text_bytes = text.encode('utf-8')
encoded_bytes = b64encode(text_bytes)
return encoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64编码错误: {str(e)}")
return ""
def d64(self,encoded_text):
try:
encoded_bytes = encoded_text.encode('utf-8')
decoded_bytes = b64decode(encoded_bytes)
return decoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64解码错误: {str(e)}")
return ""
def md5(self, text):
h = MD5.new()
h.update(text.encode('utf-8'))
return h.hexdigest()

View File

@@ -1,93 +0,0 @@
# -*- coding: utf-8 -*-
# by @嗷呜
import sys
sys.path.append('..')
from base.spider import Spider
class Spider(Spider):
def getName(self):
return "mp"
def init(self, extend=""):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
host = 'https://g.c494.com'
header = {
'User-Agent': 'Dart/2.10 (dart:io)',
'platform_version': 'RP1A.200720.011',
'version': '2.2.3',
'copyright': 'xiaogui',
'platform': 'android',
'client_name': '576O5p+P5b2x6KeG',
}
def homeContent(self, filter):
data = self.fetch(f'{self.host}/api.php/app/nav?token=', headers=self.header).json()
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
"sort": "排序"}
filters = {}
classes = []
json_data = data["list"]
for item in json_data:
has_non_empty_field = False
jsontype_extend = item["type_extend"]
classes.append({"type_name": item["type_name"], "type_id": str(item["type_id"])})
for key in dy:
if key in jsontype_extend and jsontype_extend[key].strip() != "":
has_non_empty_field = True
break
if has_non_empty_field:
filters[str(item["type_id"])] = []
for dkey in jsontype_extend:
if dkey in dy and jsontype_extend[dkey].strip() != "":
values = jsontype_extend[dkey].split(",")
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
value.strip() != ""]
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
result = {}
result["class"] = classes
result["filters"] = filters
return result
def homeVideoContent(self):
rsp = self.fetch(f"{self.host}/api.php/app/index_video?token=", headers=self.header)
root = rsp.json()['list']
videos = [item for vodd in root for item in vodd['vlist']]
return {'list': videos}
def categoryContent(self, tid, pg, filter, extend):
parms = {"pg": pg, "tid": tid, "class": extend.get("class", ""), "area": extend.get("area", ""),
"lang": extend.get("lang", ""), "year": extend.get("year", ""), "token": ""}
data = self.fetch(f'{self.host}/api.php/app/video', params=parms, headers=self.header).json()
return data
def detailContent(self, ids):
parms = {"id": ids[0], "token": ""}
data = self.fetch(f'{self.host}/api.php/app/video_detail', params=parms, headers=self.header).json()
vod = data['data']
vod.pop('pause_advert_list', None)
vod.pop('init_advert_list', None)
vod.pop('vod_url_with_player', None)
return {"list": [vod]}
def searchContent(self, key, quick, pg='1'):
parms = {'pg': pg, 'text': key, 'token': ''}
data = self.fetch(f'{self.host}/api.php/app/search', params=parms, headers=self.header).json()
return data
def playerContent(self, flag, id, vipFlags):
return {"parse": 0, "url": id, "header": {'User-Agent': 'User-Agent: Lavf/58.12.100'}}
def localProxy(self, param):
pass

View File

@@ -0,0 +1,255 @@
# -*- coding: utf-8 -*-
# by @嗷呜
import re
import sys
from Crypto.Hash import MD5
sys.path.append("..")
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from urllib.parse import quote, urlparse
from base64 import b64encode, b64decode
from concurrent.futures import ThreadPoolExecutor
import json
import time
from base.spider import Spider
class Spider(Spider):
'''
sites照常配置
lives配置
{
"name": "xxxx",
"type": 3,
"api": "路径/若惜追剧APP.py",
"ext": ""
}
'''
def init(self, extend=""):
self.host = self.gethost()
pass
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def action(self, action):
pass
def destroy(self):
pass
def homeContent(self, filter):
data = self.getdata("/api.php/getappapi.index/initV119")
dy = {"class": "类型", "area": "地区", "lang": "语言", "year": "年份", "letter": "字母", "by": "排序",
"sort": "排序"}
filters = {}
classes = []
json_data = data["type_list"]
homedata = data["banner_list"][8:]
for item in json_data:
if item["type_name"] == "全部":
continue
has_non_empty_field = False
jsontype_extend = json.loads(item["type_extend"])
homedata.extend(item["recommend_list"])
jsontype_extend["sort"] = "最新,最热,最赞"
classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
for key in dy:
if key in jsontype_extend and jsontype_extend[key].strip() != "":
has_non_empty_field = True
break
if has_non_empty_field:
filters[str(item["type_id"])] = []
for dkey in jsontype_extend:
if dkey in dy and jsontype_extend[dkey].strip() != "":
values = jsontype_extend[dkey].split(",")
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
value.strip() != ""]
filters[str(item["type_id"])].append({"key": dkey, "name": dy[dkey], "value": value_array})
result = {}
result["class"] = classes
result["filters"] = filters
result["list"] = homedata[1:]
return result
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
body = {"area": extend.get('area', '全部'), "year": extend.get('year', '全部'), "type_id": tid, "page": pg,
"sort": extend.get('sort', '最新'), "lang": extend.get('lang', '全部'),
"class": extend.get('class', '全部')}
result = {}
data = self.getdata("/api.php/getappapi.index/typeFilterVodList", body)
result["list"] = data["recommend_list"]
result["page"] = pg
result["pagecount"] = 9999
result["limit"] = 90
result["total"] = 999999
return result
def detailContent(self, ids):
body = f"vod_id={ids[0]}"
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
vod = data["vod"]
play = []
names = []
for itt in data["vod_play_list"]:
a = []
names.append(itt["player_info"]["show"])
for it in itt['urls']:
it['user_agent']=itt["player_info"].get("user_agent")
it["parse"]=itt["player_info"].get("parse")
a.append(f"{it['name']}${self.e64(json.dumps(it))}")
play.append("#".join(a))
vod["vod_play_from"] = "$$$".join(names)
vod["vod_play_url"] = "$$$".join(play)
result = {"list": [vod]}
return result
def searchContent(self, key, quick, pg="1"):
body = f"keywords={key}&type_id=0&page={pg}"
data = self.getdata("/api.php/getappapi.index/searchList", body)
result = {"list": data["search_list"], "page": pg}
return result
def playerContent(self, flag, id, vipFlags):
ids = json.loads(self.d64(id))
h={"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")}
try:
if re.search(r'url=', ids['parse_api_url']):
data=self.fetch(ids['parse_api_url'], headers=h, timeout=10).json()
url=data.get('url') or data['data'].get('url')
else:
body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'],True))}&token={ids.get('token')}"
b = self.getdata("/api.php/getappapi.index/vodParse", body)['json']
url = json.loads(b)['url']
if 'error' in url:raise ValueError(f"解析失败: {url}")
p=0
except Exception as e:
print('错误信息:',e)
url, p = ids['url'], 1
if re.search(r'\.jpg|\.png|\.jpeg', url):
url = self.Mproxy(url)
result = {}
result["parse"] = p
result["url"] = url
result["header"] = h
return result
def liveContent(self, url):
id=self.homeContent(True)['class'][-1]['type_id']
vlist=self.categoryContent(id,1,False,{})['list']
results = []
with ThreadPoolExecutor(max_workers=len(vlist)) as executor:
futures = [executor.submit(self.livedetailContent, item['vod_name'], item['vod_id']) for item in vlist]
for future in futures:
try:
detail = future.result()
if detail:
results.append(detail)
except Exception as e:
print(f"处理详情数据失败: {str(e)}")
return '\n'.join(results)
def livedetailContent(self, name,id):
try:
print(f"获取直播源:{name}")
body = f"vod_id={id}"
data = self.getdata("/api.php/getappapi.index/vodDetail", body)
play = [f"{name},#genre#"]
for itt in data["vod_play_list"]:
for it in itt['urls']:
play.append(f"{it['name']}, {it['url']}")
except Exception as e:
print(f"获取直播源失败:{str(e)}")
play=[]
return '\n'.join(play)
def localProxy(self, param):
return self.Mlocal(param)
def gethost(self):
headers = {
'User-Agent': 'okhttp/3.14.9'
}
host = self.fetch('https://rxysyyds.oss-cn-chengdu.aliyuncs.com/getapp.txt', headers=headers).text
return host.strip()
def aes(self, text,b=None):
key = b"ebad3f1a58b13933"
cipher = AES.new(key, AES.MODE_CBC, key)
if b:
ct_bytes = cipher.encrypt(pad(text.encode("utf-8"), AES.block_size))
ct = b64encode(ct_bytes).decode("utf-8")
return ct
else :
pt = unpad(cipher.decrypt(b64decode(text)), AES.block_size)
return pt.decode("utf-8")
def header(self):
t = str(int(time.time()))
header = {"Referer":self.host,
"User-Agent": "okhttp/3.14.9", "app-version-code": "140", "app-ui-mode": "light",
"app-api-verify-time": t, "app-user-device-id": self.md5(t),
"app-api-verify-sign": self.aes(t,True),
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
return header
def getdata(self, path, data=None):
vdata = self.post(f"{self.host}{path}", headers=self.header(), data=data, timeout=10).json()['data']
data1 = self.aes(vdata)
return json.loads(data1)
def Mproxy(self, url):
return f"{self.getProxyUrl()}&url={self.e64(url)}&type=m3u8"
def Mlocal(self, param,header=None):
url = self.d64(param["url"])
ydata = self.fetch(url, headers=header, allow_redirects=False)
data = ydata.content.decode('utf-8')
if ydata.headers.get('Location'):
url = ydata.headers['Location']
data = self.fetch(url, headers=header).content.decode('utf-8')
parsed_url = urlparse(url)
durl = parsed_url.scheme + "://" + parsed_url.netloc
lines = data.strip().split('\n')
for index, string in enumerate(lines):
if '#EXT' not in string and 'http' not in string:
last_slash_index = string.rfind('/')
lpath = string[:last_slash_index + 1]
lines[index] = durl + ('' if lpath.startswith('/') else '/') + lpath
data = '\n'.join(lines)
return [200, "application/vnd.apple.mpegur", data]
def e64(self, text):
try:
text_bytes = text.encode('utf-8')
encoded_bytes = b64encode(text_bytes)
return encoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64编码错误: {str(e)}")
return ""
def d64(self,encoded_text):
try:
encoded_bytes = encoded_text.encode('utf-8')
decoded_bytes = b64decode(encoded_bytes)
return decoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64解码错误: {str(e)}")
return ""
def md5(self, text):
h = MD5.new()
h.update(text.encode('utf-8'))
return h.hexdigest()

View File

@@ -0,0 +1,340 @@
# -*- coding: utf-8 -*-
# by @嗷呜
import binascii
import json
import os
import re
import sys
import time
import uuid
from urllib.parse import urlparse
from concurrent.futures import ThreadPoolExecutor
sys.path.append('..')
from base.spider import Spider
from base64 import b64encode, b64decode
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_v1_5
from Crypto.Util.Padding import unpad, pad
from Crypto.Hash import MD5
class Spider(Spider):
def init(self, extend=""):
self.host = self.gethost()
pass
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
headers = {
'AppID': '534',
'app_id': '534',
'version': '1.0.3',
'package': 'com.hjmore.wallpaper',
'user_id': '3507f394e83d2424',
'user-id': '3507f394e83d2424',
'app_name': 'lanlan',
'app-name': 'lanlan',
'Content-Type': 'application/json; charset=utf-8;',
'User-Agent': 'okhttp/4.9.0'
}
def homeContent(self, filter):
hdata=self.getdata('/api.php/provide/index',self.getbody({'tid':'0'}))
vlist=hdata['data'].get('tj',[])
result = {}
classes = []
filters = {}
for i in hdata['data']['sub_data']:
id=str(i['type_id'])
classes.append({'type_id': id, 'type_name': i['type_name']})
if len(i['data']):
vlist.extend(i['data'])
with ThreadPoolExecutor(max_workers=len(classes)) as executor:
results = executor.map(self.getf, classes)
for id, ft in results:
if len(ft):filters[id] = ft
result['class'] = classes
result['filters'] = filters
result['list'] = vlist
return result
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
body={
"tid": tid,
"type": extend.get('type'),
"lang": extend.get('lang'),
"area": extend.get('area'),
"year": extend.get('year'),
"pg": pg
}
body = {k: v for k, v in body.items() if v is not None and v != ""}
data=self.getdata('/api.php/provide/nav',self.getbody(body))
result = {}
result['list'] = data['data']['data']
result['page'] = pg
result['pagecount'] = 9999
result['limit'] = 90
result['total'] = 999999
return result
pass
def detailContent(self, ids):
data=self.getdata('/api.php/provide/vod',self.getbody({'ids':ids[0]}))
vod=data['data']
plist=[]
names=[]
for i in vod['vod_play_url']:
ulist=[]
names.append(i['name'].split(' ')[0])
jdata={'parse':''}
if i.get('parse') and isinstance(i['parse'], list) and len(i['parse']):
jdata['parse']=self.e64(json.dumps(i['parse']))
for j in i['data']:
jdata['url']=j['url']
ulist.append(f'{j["name"]}${self.e64(json.dumps(jdata))}')
plist.append('#'.join(ulist))
vod['vod_play_from']='$$$'.join(names)
vod['vod_play_url']='$$$'.join(plist)
vod.pop('cover_list', None)
return {'list':[vod]}
def searchContent(self, key, quick, pg="1"):
body={"wd":key,"tid":"0","pg":pg}
data=self.getdata('/api.php/provide/search',self.getbody(body))
vlist=[]
for i in data['data']:
i.pop('vod_play_from', None)
vlist.append(i)
return {'list':vlist,'page':pg}
def playerContent(self, flag, id, vipFlags):
data=json.loads(self.d64(id))
parse=data.get('parse')
url,p,head = data.get('url'),1,''
if parse:
parse=json.loads(self.d64(parse))
if not re.search(r'\.m3u8|.mp4|\.flv', url) and parse:
for p in parse:
try:
data=self.fetch(f'{p}{url}',self.headers).json()
url=data.get('data',{}).get('url') or data.get('url')
head=data.get('data',{}).get('header') or data.get('header')
p=0
break
except:
p,url=1,data.get('url')
head = {'User-Agent': 'okhttp/4.9.0'}
return {'parse': p, 'url': url, 'header': head}
def localProxy(self, param):
pass
def getf(self, map):
ft,id =[], map['type_id']
try:
fdata = self.getdata('/api.php/provide/nav', self.getbody({'tid': id, 'pg': '1'}))
dy = ['area', 'year', 'lang', 'type']
fd = fdata['data']['type_extend']
has_non_empty_field = False
for key in dy:
if key in fd and fd[key].strip() != "":
has_non_empty_field = True
break
if has_non_empty_field:
for dkey in fd:
if dkey in dy and fd[dkey].strip() != "":
values = fd[dkey].split(",")
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
value.strip() != ""]
ft.append({"key": dkey, "name": dkey, "value": value_array})
return (id, ft)
except:
return (id, ft)
def getskey(self):
random_bytes = os.urandom(16)
return binascii.hexlify(random_bytes).decode()
def getohost(self):
url='https://bianyuan001.oss-cn-beijing.aliyuncs.com/huidu1.0.0.json'
response = self.fetch(url, headers=self.headers).json()
return response['servers'][0]
def gethost(self):
body={
"gr_rp_size": "1080*2272",
"gr_app_list": "%E5%B1%8F%E5%B9%95%E5%BD%95%E5%88%B6%EF%BC%88com.miui.screenrecorder%29%0A%E5%A4%B8%E5%85%8B%EF%BC%88com.quark.browser%29%0A%E8%BE%B9%E7%BC%98%E8%A7%86%E9%A2%91%EF%BC%88com.hjmore.wallpaper%29%0A%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%EF%BC%88tv.danmaku.bili%29%0A%E7%81%AB%E6%98%9F%E6%90%9C%E9%A2%98%EF%BC%88com.fenbi.android.souti%29%0A%E6%94%AF%E4%BB%98%E5%AE%9D%EF%BC%88com.eg.android.AlipayGphone%29%0AWPS%20Office%EF%BC%88cn.wps.moffice_eng%29",
"gr_lal": "0.0%2C0.0",
"gr_system_type": "android",
"gr_device_imei": "3507f394e83d2424",
"gr_app_version": "1.0.3",
"gr_device_model": "Xiaomi%20M2012K10C%20%28Android%20%E7%89%88%E6%9C%AC%3A%2011%2C%20SDK%E7%89%88%E6%9C%AC%3A%2030%29",
"gr_city": "%E8%B4%B5%E5%B7%9E%2C%E6%9C%AA%E7%9F%A5%2C%E6%9C%AA%E7%9F%A5",
"requestId": self.uuid(),
"timeStamp": str(int(time.time() * 1000)),
"version": "1.0.3",
"package": "com.hjmore.wallpaper",
"userLoginToken": "",
"app_id": "534",
"appName": 2131951658,
"device_id": "3507f394e83d2424",
"device-id": "3507f394e83d2424",
"oaid": "",
"imei": "",
"referer_shop": "边缘影视",
"referer-shop": "边缘影视",
"access_fine_location": 0,
"access-fine-location": 0
}
ohost = self.getohost()
data=self.getdata(f'/api.php/settings/grayscale_list',body,ohost)
parsed_url = urlparse(data['data']['grayscale']['server_url'][0])
domain = parsed_url.scheme + "://" + parsed_url.netloc
return domain
def drsa(self, encrypted_data):
private_key_pem = """-----BEGIN RSA PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDA5NWiAwRjH50/
IJY1N0zLopa4jpuWE7kWMn1Qunu6SjBgTvNRmRUoPDHn54haLfbfXIa2X+/sIaMB
/O3HhrpVsz55E5W2vpZ5fBYWh+M65bQERKTW+l72H7GR9x0yj3QPByzzfsj/QkyP
81prpwR9i8yMe7yG9TFKqUQCPE+/GrhNU1Qf6nFmV+vMnlP9DantkwAt4fPOMZn3
j4da65/1YQV+F5bYzaLenNVKbHf8U8fVYLZWIy4yk2Vpe4R2Z+JX/eHWsChE9hOu
iFm02eTW5NJLZlWUxYrSE23VXi8oXSEdON3UEOrwSdAUh4SXxLZ9U7KpNVdTwWyR
AS4GyzJ/AgMBAAECggEBAKzmcXefLLeNBu4mz30z7Go7es5DRcLoOudiqmFKRs1c
4q/xFLj3drdx/WnZZ6ctvDPKRBYFOJF4NRz7Ekfew/c9i6oLnA8KFuceCs53T37j
ltCclwT7t1L2ZbxovIsteuJdlDVOV+w2CVqez1Xfh27heKAT6ZEvBtfdkVBPr0uj
oVwa2+XlJmYZw5dHeB7ySVeAQ+69zDuADB8OWxPWsv6Del+Fhf0kTHAw4WgqcYsd
JUunCjgLdJUlDgXzH/M/Nj8NYVEuq6QpmhaktJ4fwn/F7u3lQllVCFKj5lr0Xb92
y7lvQlGqMKX1oxf+P5c5/vie1kDx1Rj4S++flIcVlUECgYEA4BuxCZ1c8oOF98bs
KTAONnnZniQ1BRt7rA+O9+++lDjxJhxkuthwjB9YzrnZtxHJtvIIie9Jv8MVfzHa
p2woDtiEh3YYwmIlgNUFvTcGe++tTiEiLDcGc/xNhpvfbLaw9QB7/HQ+LT1QCMxJ
ufdBrR98l0khIGjYqxDW3W5pV70CgYEA3Ff/9+GM2XI/EUSTYrpnwp5R5OsXz1DL
3CFFgp1EPCNk/c3YNWnrUtTkfmKAlRqWIHfphvH/jS6jpGrfRxDggPwGMtBc134b
brIM5i4KNj/EcE+w5g03HaKBf1ZihHDQ53c6wTn6IFOHJNSPRLqMNqRymfbclNyO
lBMHQmB8yOsCgYBCdZPTwRnuRTi2WQRx1nFwkEQL1Lrwb80GInsIZc2DkTtaTPNG
QadmtmkUrSK2Wo0SNsZ3eUHKn2TBmpw4KCfc9zKeJVSEWKy8fu+7xBSlLlebotHK
gOrl/H1VHOZuC+OAVItwO1yw98zDPynh/0Q3ve2pw6MSRGV0nYLKmdKdlQKBgQCJ
Ty1rw1qKhu9WS22tMIxIc3CFPxtvTeI8I1+1rVtAPq5Im2YIoyDKVXCucaO/RvoW
8aLNPTELQe0oIJFTL+k3d9ZFBCNXBncB3GK9biNe+w3nD0IlmkamaQZZ2/M4pTUJ
iPtMPlzomCS3ht5g7f9CbegcmgGLooYXMGRtsMMSUQKBgQCoj+3UciH2i+HyUla5
1FxivjH3MqSTE4Q7OdzrELb6DoLYzjgWAbpG8HIuodD4uG5xz1oR5H7vkblf1itB
hwOwDEiabyX76e/I3Q0ovwBV+9PMjM4UVU0kHoiu3Z2s90ckwNh58w3QH5fn9E0b
fqMnB6uWze+xrXWijaOzVZhIZg==
-----END RSA PRIVATE KEY-----"""
private_key = RSA.import_key(private_key_pem)
cipher = PKCS1_v1_5.new(private_key)
decrypted_data = cipher.decrypt(b64decode(encrypted_data), None)
return decrypted_data.decode('utf-8')
def ersa(self, data):
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+0QMb3WDXjNBRovRhTLH
g3d+CliZAva2tepWNNN0Pj6DgE3ZTnPR34iL/cjo9Jbd3dqAJs/YkKnFurGkDxz5
TthIqvmz244wiFcHt+FGWoJsj5ZVvrH3pPwH85ggmI1DjxSJEUhB12Z9X6FGli8D
drR9xeLe5y8vFekux8xCQ7pwH1mNQu4Wy32WVM8aLjmRjNzEWOvEMAWCRuwymEdS
zlWoH53qk1dqd6DAmOJhWU2hH6Yt2ZY9LTaDGiHrS+g0DuwajAQzhbM8eonGYMph
nP4q0UTHWEfaGR3HoILmeM32M+qF/UCGfgfR6tCMiXPoHwnD2zoxbZ2p+QlYuTZL
vQIDAQAB
-----END PUBLIC KEY-----"""
key = RSA.importKey(public_key)
cipher = PKCS1_v1_5.new(key)
encrypted = cipher.encrypt(data.encode())
return b64encode(encrypted).decode()
def eaes(self, data, key):
key = key.encode('utf-8')
cipher = AES.new(key, AES.MODE_ECB)
padded = pad(data.encode('utf-8'), AES.block_size)
encrypted = cipher.encrypt(padded)
word = b64encode(encrypted).decode('utf-8')
return word
def daes(self, encrypted_data, key):
key = key.encode('utf-8')
cipher = AES.new(key, AES.MODE_ECB)
encrypted = b64decode(encrypted_data)
decrypted = cipher.decrypt(encrypted)
unpadded = unpad(decrypted, AES.block_size)
return unpadded.decode('utf-8')
def getbody(self,params=None):
body = {
"requestId": self.uuid(),
"timeStamp": str(int(time.time()*1000)),
"version": "1.0.3",
"package": "com.hjmore.wallpaper",
"userLoginToken": "",
"app_id": "534",
"appName": 2131951658,
"device_id": "3507f394e83d2424",
"device-id": "3507f394e83d2424",
"oaid": "",
"imei": "",
"referer_shop": "边缘影视",
"referer-shop": "边缘影视",
"access_fine_location": 0,
"access-fine-location": 0
}
if params:
body.update(params)
return body
def getdata(self, path, body,host=None):
jdata=json.dumps(body)
msign = self.md5(jdata)
skey = self.getskey()
jsign={'key': skey,'sign': msign}
Sign=self.ersa(json.dumps(jsign))
header=self.headers.copy()
header['Sign']=Sign
dbody=self.eaes(jdata, skey)
response = self.post(f'{host or self.host}{path}', headers=header, data=dbody)
rdata=response.text
if response.headers.get('Sign'):
dkey=self.drsa(response.headers['Sign'])
rdata=self.daes(rdata, dkey)
return json.loads(rdata)
def e64(self, text):
try:
text_bytes = text.encode('utf-8')
encoded_bytes = b64encode(text_bytes)
return encoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64编码错误: {str(e)}")
return ""
def d64(self,encoded_text):
try:
encoded_bytes = encoded_text.encode('utf-8')
decoded_bytes = b64decode(encoded_bytes)
return decoded_bytes.decode('utf-8')
except Exception as e:
print(f"Base64解码错误: {str(e)}")
return ""
def md5(self,text):
h = MD5.new()
h.update(text.encode('utf-8'))
return h.hexdigest()
def uuid(self):
return str(uuid.uuid4())

Binary file not shown.

BIN
欧歌/jars/csp_woogkk.jar Normal file

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -628,6 +628,70 @@
"json": "./txt/bilisong.txt"
}
},
{
"key": "少儿教育",
"name": "📚少儿┃教育📚",
"type": 3,
"api": "csp_BiliGuard",
"style": {
"type": "rect",
"ratio": 1.597
},
"searchable": 0,
"quickSearch": 0,
"changeable": 0,
"ext": {
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec8251e772b"
}
},
{
"key": "小学课堂",
"name": "📚小学┃课堂📚",
"type": 3,
"api": "csp_BiliGuard",
"style": {
"type": "rect",
"ratio": 1.597
},
"searchable": 0,
"quickSearch": 0,
"changeable": 0,
"ext": {
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec82537772c"
}
},
{
"key": "初中课堂",
"name": "📚初中┃课堂📚",
"type": 3,
"api": "csp_BiliGuard",
"style": {
"type": "rect",
"ratio": 1.597
},
"searchable": 0,
"quickSearch": 0,
"changeable": 0,
"ext": {
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec824cc7729"
}
},
{
"key": "高中教育",
"name": "📚高中┃课堂📚",
"type": 3,
"api": "csp_BiliGuard",
"style": {
"type": "rect",
"ratio": 1.597
},
"searchable": 0,
"quickSearch": 0,
"changeable": 0,
"ext": {
"json": "https://im.feelec.com.cn/res/file.html?id=2c9a91099584ed4901963ec824fd772a"
}
},
{
"key": "Wexqingfengdj",
"name": "🎼舞曲┃摇头🎼",
@@ -693,38 +757,6 @@
"type": "list"
}
},
{
"key": "Wexmiso",
"name": "🎠米搜┃综合🎠",
"type": 3,
"api": "csp_WexmisoGuard",
"searchable": 1,
"changeable": 0
},
{
"key": "Wexed3000",
"name": "🎠易迪┃综合🎠",
"type": 3,
"api": "csp_Wexed3000Guard",
"searchable": 1,
"changeable": 0
},
{
"key": "易搜",
"name": "🎠易搜┃综合🎠",
"type": 3,
"api": "csp_YiSoGuard",
"searchable": 1,
"changeable": 0
},
{
"key": "Wexyingso",
"name": "🎠影子┃综合🎠",
"type": 3,
"api": "csp_WexyingsoGuard",
"searchable": 1,
"changeable": 0
},
{
"key": "WexTJso",
"name": "🎠TJ┃综合🎠",

Binary file not shown.

File diff suppressed because it is too large Load Diff