Skip to content

Commit 0211426

Browse files
committed
update: 增加点歌功能
1 parent dc89688 commit 0211426

11 files changed

+372
-5
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,4 @@ dist
142142
/index.json
143143
/vod_cache/
144144
/jx/芒果关姐.js
145+
/data/mv/

Diff for: config/map.txt

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
采集之王[合]@?type=url&params=../json/采集2024静态.json$1$@采王2024
99
UC分享@?type=url&params=../json/UC分享.json@UC分享[盘]
1010
16wMV[听]@?type=url&params=../json/十六万歌曲.txt
11+
点歌欢唱[B]@?type=url&params=../json/十六万歌曲.txt

Diff for: controllers/decoder.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import {getOriginalJs, jsDecoder} from '../libs/drpyS.js';
2-
import {readFileSync, existsSync} from 'fs';
2+
import {readFileSync, writeFileSync, existsSync} from 'fs';
33
import path from "path";
44

5+
// 检测命令行参数
6+
const args = process.argv.slice(2);
7+
8+
if (args.length > 0) {
9+
// 如果有参数,读取文件并打印内容
10+
const filePath = args[0]; // 第一个参数作为文件路径
11+
let content = readFileSync(filePath, 'utf8');
12+
console.log(`文件 ${filePath} 的内容长度为:${content.length}`);
13+
writeFileSync(filePath.replace(/\.gz$/, '.ugz'), jsDecoder.ungzip(content), 'utf-8');
14+
}
15+
516
// 仅仅支持json post 如: {"code":"xxx"}
617
export default (fastify, options, done) => {
718
// 注册 POST 路由

Diff for: controllers/encoder.js

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
import {jsEncoder} from '../libs/drpyS.js';
2+
import {readFileSync, writeFileSync} from 'fs';
3+
4+
// 检测命令行参数
5+
const args = process.argv.slice(2);
6+
7+
if (args.length > 0) {
8+
// 如果有参数,读取文件并打印内容
9+
const filePath = args[0]; // 第一个参数作为文件路径
10+
let content = readFileSync(filePath, 'utf8');
11+
console.log(`文件 ${filePath} 的内容长度为:${content.length}`);
12+
writeFileSync(filePath + '.gz', jsEncoder.gzip(content), 'utf-8');
13+
}
214

315
// 仅仅支持json post 如: {"type":"gzip","code":"xxx"}
416
export default (fastify, options, done) => {

Diff for: index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const {fastify} = fastlogger;
1212
// 获取当前路径
1313
const __dirname = path.dirname(fileURLToPath(import.meta.url));
1414
const PORT = 5757;
15-
const MAX_TEXT_SIZE = 100 * 1024; // 设置最大文本大小为 100 KB
15+
const MAX_TEXT_SIZE = 0.1 * 1024 * 1024; // 设置最大文本大小为 0.1 MB
1616

1717
// 静态资源
1818
fastify.register(fastifyStatic, {

Diff for: js/点歌欢唱[B].js

+338
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
var mv_list = [];
2+
var authors = [];
3+
var authorsPy = {};
4+
const hots = '周华健,周杰伦,张信哲,陈奕迅,队长,林俊杰,王靖雯,时代少年团,薛之谦,周深,邓寓君,叶泽浩,莫文蔚,小阿七,邓紫棋,郭顶,蓝心羽,李荣浩,程响,蔡健雅,任然,许嵩,张杰,汪苏泷,一颗狼星,王忻辰,王菲,李宇春,不是花火呀,毛不易,王小帅,半吨兄弟,刘至佳,苏星婕,徐佳莹,郁可唯,张碧晨,王力宏,杨丞琳,五月天,周星星,刘大壮,张学友,刘梦妤,旺仔小乔,戴羽彤,陈慧娴,张韶涵,王唯乐,黄龄,易烊千玺,来一碗老于,周传雄,告五人,白小白,李克勤,虎二,黄霄雲,曲肖冰,张靓颖,魏晗,刘德华,房东的猫,孙燕姿,张信哲,大籽,音阙诗听,刘若英,王贰浪,庄心妍,赵雷,小鬼,王以太,方大同,杨宗纬,蒋雪儿,单依纯,林宥嘉,梁静茹,阿肆,陈粒,朴树,许巍,谭咏麟,金志文,蔡依林,李玉刚,马嘉祺,张远,姚六一,王杰,宋亚轩,司南,杨千嬅';
5+
const starAuthors = '周杰伦,汪苏泷,李荣浩,蔡依林,筷子兄弟,凤凰传奇,程响';
6+
const alphabetList = Array.from({length: 26}, (_, index) => {
7+
const uppercase = String.fromCharCode(65 + index); // 大写字母 A-Z
8+
const lowercase = String.fromCharCode(97 + index); // 小写字母 a-z
9+
// return {n: uppercase, v: lowercase};
10+
return {n: uppercase, v: uppercase};
11+
});
12+
alphabetList.unshift({n: '全部', v: ''});
13+
var rule = {
14+
类型: '搜索',
15+
title: '点歌欢唱[B]',
16+
alias: '点歌欢唱搜索引擎',
17+
desc: '仅搜索源纯js写法',
18+
logo: 'https://tva1.sinaimg.cn/crop.6.7.378.378.1024/a22d2331jw8f6hs4xrb4kj20ay0ayacy.jpg',
19+
host: 'hiker://empty',
20+
url: '',
21+
searchUrl: 'hiker://empty',
22+
headers: {
23+
'User-Agent': 'PC_UA',
24+
},
25+
searchable: 1,
26+
quickSearch: 0,
27+
filterable: 1,
28+
double: true,
29+
play_parse: true,
30+
limit: 100,
31+
// class_name: '歌手&歌名&全名',
32+
// class_url: 'author&name&all',
33+
filter: {
34+
author: [
35+
{key: 'letters', name: '首字母', value: alphabetList}
36+
]
37+
},
38+
// 推荐样式
39+
hikerListCol: 'icon_round_2',
40+
// 分类列表样式
41+
hikerClassListCol: 'avatar',
42+
home_flag: '3-11-S',
43+
// class_flag: '[CFS][CFPY]1',
44+
预处理: async function () {
45+
let t1 = (new Date()).getTime();
46+
let _url = rule.params;
47+
log(`传入参数:${_url}`);
48+
let _init = getItem('init');
49+
if (_init === '1') {
50+
mv_list = JSON.parse(pathLib.readFile('./mv/十六万歌曲.json'));
51+
authors = JSON.parse(pathLib.readFile('./mv/十六万歌曲作者.json'));
52+
authorsPy = JSON.parse(pathLib.readFile('./mv/十六万歌曲作者拼音.json'));
53+
} else {
54+
mv_list = (await request(_url)).split('\n').map((it) => {
55+
it = it.trim();
56+
let _tt = it.split(',')[0];
57+
let _uu = it.split(',')[1];
58+
let _aa, _nn;
59+
if (/.+-.+/.test(_tt)) {
60+
_aa = _tt.split('-')[0].trim() || '未知';
61+
_nn = _tt.split('-')[1].trim();
62+
} else {
63+
_aa = '未知';
64+
_nn = _tt.trim();
65+
}
66+
return {
67+
title: _tt,
68+
url: _uu,
69+
author: _aa,
70+
name: _nn,
71+
title_py: getFirstLetter(_tt),
72+
author_py: getFirstLetter(_aa),
73+
name_py: getFirstLetter(_nn)
74+
}
75+
});
76+
authors = [...new Set(mv_list.filter(it => /[\u4e00-\u9fa5]{2,}/.test(it.author)).map(it => {
77+
const author = it.author.trim();
78+
authorsPy[author] = it.author_py;
79+
return author;
80+
}))];
81+
authors = authors.sort((a, b) => a.localeCompare(b, 'zh-CN', {numeric: true, sensitivity: 'base'}));
82+
pathLib.writeFile('./mv/十六万歌曲.json', JSON.stringify(mv_list));
83+
pathLib.writeFile('./mv/十六万歌曲作者.json', JSON.stringify(authors));
84+
pathLib.writeFile('./mv/十六万歌曲作者拼音.json', JSON.stringify(authorsPy));
85+
setItem('init', '1');
86+
}
87+
let t2 = (new Date()).getTime();
88+
log(`读取文件并转json耗时:${t2 - t1}毫秒`);
89+
},
90+
lazy: async function () {
91+
},
92+
proxy_rule: async function (params) {
93+
let {input, proxyPath, getProxyUrl} = this;
94+
let resp_not_found = [404, 'text/plain', 'not found'];
95+
return resp_not_found
96+
},
97+
action: async function (action, value) {
98+
if (action === 'only_search') {
99+
return '此源为纯搜索源,你直接全局搜索这个源或者使用此页面的源内搜索就好了'
100+
}
101+
if (action === '源内搜索') {
102+
let content = JSON.parse(value);
103+
return JSON.stringify({
104+
action: {
105+
actionId: '__self_search__',
106+
skey: '', //目标源key,可选,未设置或为空则使用当前源
107+
name: '搜索: ' + content.wd,
108+
tid: content.wd,
109+
flag: '1',
110+
msg: '源内搜索'
111+
}
112+
});
113+
}
114+
return `没有动作:${action}的可执行逻辑`
115+
},
116+
class_parse: async () => {
117+
let classes = [{
118+
type_id: 'hot',
119+
type_name: '热门',
120+
type_flag: '1'
121+
}, {
122+
type_id: 'author',
123+
type_name: '歌手',
124+
type_flag: '[CFS][CFPY]1'
125+
}, {
126+
type_id: 'name',
127+
type_name: '歌名',
128+
type_flag: '[CFS][CFPY]1-11'
129+
}, {
130+
type_id: 'all',
131+
type_name: '全名',
132+
type_flag: '[CFS][CFPY]1-11'
133+
}, {
134+
type_id: '华语歌手-1',
135+
type_name: '男歌手',
136+
type_flag: '[CFPY][PY1]2-00-S'
137+
}, {
138+
type_id: '华语歌手-2',
139+
type_name: '女歌手',
140+
type_flag: '[CFPY][PY1]2-00-S'
141+
}, {
142+
type_id: '华语歌手-3',
143+
type_name: '组合歌手',
144+
type_flag: '[CFPY][PY1]2-00-S'
145+
}];
146+
return {
147+
class: classes
148+
};
149+
},
150+
推荐: async function () {
151+
let {publicUrl} = this;
152+
let searchIcon = urljoin(publicUrl, './images/icon_cookie/搜索.jpg');
153+
let selectData = starAuthors.split(',').map(it => `${it}:=${it}`).join(',');
154+
return [{
155+
vod_id: 'only_search',
156+
vod_name: '这是个纯搜索源哦',
157+
vod_pic: 'https://t8.baidu.com/it/u=102347688,62200072&fm=193',
158+
vod_remarks: `歌手数量:${authors.length}`,
159+
vod_tag: 'action'
160+
},
161+
{
162+
vod_id: JSON.stringify({
163+
actionId: '源内搜索',
164+
id: 'wd',
165+
type: 'input',
166+
title: '源内搜索',
167+
tip: '请输入搜索内容',
168+
value: '',
169+
selectData: selectData
170+
}),
171+
vod_name: '源内搜索',
172+
vod_pic: searchIcon,
173+
vod_remarks: `歌曲数量:${mv_list.length}`,
174+
vod_tag: 'action',
175+
}];
176+
},
177+
一级: async function (tid, pg, filter, extend) {
178+
let {MY_FL} = this;
179+
let d = [];
180+
let _f = rule.limit * (pg - 1);
181+
let _t = rule.limit * pg;
182+
let _d = [];
183+
if (tid === 'hot') {
184+
_d = hots.split(',').slice(_f, _t);
185+
_d.forEach(it => {
186+
d.push({
187+
vod_name: it,
188+
vod_id: 'author#' + it,
189+
});
190+
});
191+
} else if (tid === 'author') {
192+
let _authors = authors;
193+
if (MY_FL.custom) {
194+
_authors = authors.filter(_author => _author.includes(MY_FL.custom));
195+
} else if (MY_FL.custom_pinyin) {
196+
_authors = authors.filter(_author => authorsPy[_author].includes(MY_FL.custom_pinyin));
197+
} else if (MY_FL.letters) {
198+
_authors = authors.filter(_author => authorsPy[_author].startsWith(MY_FL.letters));
199+
}
200+
_d = _authors.slice(_f, _t);
201+
_d.forEach(it => {
202+
d.push({
203+
vod_name: it,
204+
vod_id: 'author#' + it,
205+
});
206+
});
207+
} else if (tid === 'name') {
208+
let _data = mv_list;
209+
if (MY_FL.custom) {
210+
_data = mv_list.filter(it => it.name.includes(MY_FL.custom));
211+
} else if (MY_FL.custom_pinyin) {
212+
_data = mv_list.filter(it => it.name_py.includes(MY_FL.custom_pinyin));
213+
}
214+
_d = _data.slice(_f, _t);
215+
_d.forEach(it => {
216+
d.push({
217+
vod_name: it.title,
218+
vod_id: it.url + '#' + it.title,
219+
});
220+
});
221+
} else if (tid === 'all') {
222+
let _data = mv_list;
223+
if (MY_FL.custom) {
224+
const words = MY_FL.custom.split('-');
225+
if (words.length > 1) {
226+
_data = mv_list.filter(it => it.author.includes(words[0]) && it.name.includes(words[1]));
227+
} else {
228+
_data = mv_list.filter(it => it.title.includes(MY_FL.custom));
229+
}
230+
} else if (MY_FL.custom_pinyin) {
231+
const words = MY_FL.custom_pinyin.split('-');
232+
if (words.length > 1) {
233+
_data = mv_list.filter(it => it.author_py.includes(words[0]) && it.name_py.includes(words[1]));
234+
} else {
235+
_data = mv_list.filter(it => it.title_py.includes(MY_FL.custom_pinyin));
236+
}
237+
}
238+
_d = _data.slice(_f, _t);
239+
_d.forEach(it => {
240+
d.push({
241+
vod_name: it.title,
242+
vod_id: it.url + '#' + it.title,
243+
});
244+
});
245+
} else if (tid.startsWith('华语歌手-')) {
246+
const cate = tid.substring(5);
247+
const letter = MY_FL.custom_pinyin ? MY_FL.custom_pinyin.substring(0, 1) : '';
248+
const url = `https://wapi.kuwo.cn/api/www/artist/artistInfo?category=${cate}&prefix=${letter}&pn=${pg}&rn=60`;
249+
const data = JSON.parse(await request(url)).data.artistList;
250+
data.forEach(it => {
251+
d.push({
252+
vod_id: 'author#' + it.name,
253+
vod_name: it.name,
254+
vod_pic: it.pic
255+
});
256+
});
257+
} else {
258+
// 仅搜索作者允许翻页,其他情况只有3个固定按钮
259+
if (Number(pg) > 1) {
260+
return []
261+
}
262+
d.push({
263+
vod_name: '按歌手搜索',
264+
vod_id: 'author#' + tid,
265+
vod_remarks: '',
266+
});
267+
d.push({
268+
vod_name: '按歌名搜索',
269+
vod_id: 'name#' + tid,
270+
vod_remarks: '',
271+
});
272+
d.push({
273+
vod_name: '全名模糊搜索',
274+
vod_id: 'all#' + tid,
275+
vod_remarks: '',
276+
});
277+
}
278+
return d;
279+
},
280+
二级: async function () {
281+
let {orId} = this;
282+
283+
let _sname = '';
284+
let _vname = '';
285+
let data = [];
286+
let _stype = orId.split('#')[0];
287+
_sname = orId.split('#')[1];
288+
_vname = '';
289+
switch (_stype) {
290+
case 'author':
291+
// log('_sname:', _sname);
292+
_vname = '歌手搜索';
293+
data = mv_list.filter(it => it.author.includes(_sname));
294+
break;
295+
case 'name':
296+
_vname = '歌名搜索';
297+
data = mv_list.filter(it => it.name.includes(_sname));
298+
break;
299+
case 'all':
300+
_vname = '全名搜索';
301+
data = mv_list.filter(it => it.title.includes(_sname));
302+
break;
303+
default:
304+
_vname = '单曲';
305+
data = [{title: _sname, url: _stype}];
306+
break;
307+
}
308+
return {
309+
vod_id: orId,
310+
vod_name: `${_vname}:${_sname}`,
311+
vod_remarks: `共计${data.length}`,
312+
vod_play_from: '道长源内搜索',
313+
vod_play_url: data.map(it => it.title + '$' + it.url).join('#')
314+
}
315+
},
316+
搜索: async function (wd, quick, pg) {
317+
if (Number(pg) > 1) {
318+
return []
319+
}
320+
let d = [];
321+
d.push({
322+
vod_name: '按歌手搜索:' + wd,
323+
vod_id: 'author#' + wd,
324+
vod_remarks: '',
325+
});
326+
d.push({
327+
vod_name: '按歌名搜索:' + wd,
328+
vod_id: 'name#' + wd,
329+
vod_remarks: '',
330+
});
331+
d.push({
332+
vod_name: '全名模糊搜索:' + wd,
333+
vod_id: 'all#' + wd,
334+
vod_remarks: '',
335+
});
336+
return d
337+
}
338+
}

Diff for: json/十六万歌曲.json

+1
Large diffs are not rendered by default.

Diff for: json/十六万歌曲作者.json

+1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)