@mr-quin/dango-manifests 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/catalog.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "packageVersion": "0.8.0",
2
+ "packageVersion": "0.8.2",
3
3
  "manifests": [
4
4
  {
5
5
  "id": "aiyifan",
@@ -18,7 +18,7 @@
18
18
  {
19
19
  "id": "bilibili",
20
20
  "name": "Bilibili",
21
- "version": "0.5.0",
21
+ "version": "0.6.0",
22
22
  "apiVersion": 1,
23
23
  "file": "src/manifests/bilibili.json"
24
24
  },
@@ -53,7 +53,7 @@
53
53
  {
54
54
  "id": "mango",
55
55
  "name": "Mango TV",
56
- "version": "0.6.0",
56
+ "version": "0.7.0",
57
57
  "apiVersion": 1,
58
58
  "file": "src/manifests/mango.json"
59
59
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mr-quin/dango-manifests",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Built-in dango manifests for danmaku sources",
5
5
  "author": "Mr-Quin",
6
6
  "license": "MIT",
@@ -8,10 +8,12 @@
8
8
  "name": "B站",
9
9
  "configSchema.properties.danmakuFormat.title": "弹幕格式",
10
10
  "configSchema.properties.danmakuFormat.description": "xml 是旧版接口,最多约 3000 条弹幕;protobuf 分页返回全部弹幕",
11
- "cookieSet.title": "登录B站"
11
+ "cookieSet.title": "登录B站",
12
+ "configSchema.properties.includeUserUploads.title": "包含用户投稿",
13
+ "configSchema.properties.includeUserUploads.description": "搜索时一并返回用户投稿(UGC)视频,而不仅是官方番剧库。默认关闭:UGC 结果较杂,且多为切片。"
12
14
  }
13
15
  },
14
- "version": "0.5.0",
16
+ "version": "0.6.0",
15
17
  "hosts": ["api.bilibili.com"],
16
18
  "urlMatch": [
17
19
  {
@@ -21,6 +23,14 @@
21
23
  {
22
24
  "host": "www.bilibili.com",
23
25
  "path": "^/bangumi/play/ep(?<epid>\\d+)"
26
+ },
27
+ {
28
+ "host": "www.bilibili.com",
29
+ "path": "^/video/(?<bvid>BV[0-9A-Za-z]+)"
30
+ },
31
+ {
32
+ "host": "www.bilibili.com",
33
+ "path": "^/video/[aA][vV](?<aid>\\d+)"
24
34
  }
25
35
  ],
26
36
  "configSchema": {
@@ -32,6 +42,12 @@
32
42
  "default": "protobuf",
33
43
  "title": "Danmaku format",
34
44
  "description": "xml is the legacy endpoint capped at ~3000 comments; protobuf paginates and returns everything"
45
+ },
46
+ "includeUserUploads": {
47
+ "type": "boolean",
48
+ "default": false,
49
+ "title": "Include user uploads",
50
+ "description": "Also search user-uploaded (UGC) videos, not just the official bangumi catalogue. Off by default: UGC results are noisier and often clips."
35
51
  }
36
52
  }
37
53
  },
@@ -69,7 +85,8 @@
69
85
  "id": "params",
70
86
  "values": {
71
87
  "bangumi": "($p := { 'keyword': q, 'search_type': 'media_bangumi', 'wts': wbi.wts }; $merge([$p, { 'w_rid': $md5($sortedQueryString($p) & wbi.mixinKey) }]))",
72
- "ft": "($p := { 'keyword': q, 'search_type': 'media_ft', 'wts': wbi.wts }; $merge([$p, { 'w_rid': $md5($sortedQueryString($p) & wbi.mixinKey) }]))"
88
+ "ft": "($p := { 'keyword': q, 'search_type': 'media_ft', 'wts': wbi.wts }; $merge([$p, { 'w_rid': $md5($sortedQueryString($p) & wbi.mixinKey) }]))",
89
+ "video": "($p := { 'keyword': q, 'search_type': 'video', 'wts': wbi.wts }; $merge([$p, { 'w_rid': $md5($sortedQueryString($p) & wbi.mixinKey) }]))"
73
90
  }
74
91
  },
75
92
  {
@@ -93,44 +110,98 @@
93
110
  "credentials": "include",
94
111
  "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
95
112
  }
96
- }
97
- ],
98
- "output": "[[media_bangumi.data.result, media_ft.data.result].{ 'providerIds': { 'seasonId': season_id, 'mediaId': media_id }, 'indexedId': $string(season_id), 'title': $replace(title, /<[^>]+>/, ''), 'type': season_type_name, 'typeDescription': season_type_name, 'imageUrl': cover, 'episodeCount': ep_size, 'year': pubtime > 0 ? $number($substring($string($fromMillis(pubtime * 1000)), 0, 4)) : undefined }]"
99
- },
100
- "episodes": {
101
- "inputs": ["seasonId"],
102
- "steps": [
113
+ },
103
114
  {
104
- "type": "http",
105
- "id": "season",
115
+ "type": "forEach",
116
+ "id": "ugc",
117
+ "in": "includeUserUploads = true ? ['video'] : []",
118
+ "as": "searchType",
106
119
  "request": {
107
120
  "method": "GET",
108
- "url": "'https://api.bilibili.com/pgc/view/web/season'",
109
- "query": "{ 'season_id': $string(seasonId) }",
121
+ "url": "'https://api.bilibili.com/x/web-interface/wbi/search/type'",
122
+ "query": "$lookup(params, searchType)",
110
123
  "credentials": "include",
111
124
  "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
112
- }
125
+ },
126
+ "collect": "[data.result]"
113
127
  }
114
128
  ],
115
- "output": "[season.result.episodes[$not($contains(badge ? badge : '', '预告'))].{ 'providerIds': { 'cid': cid, 'aid': aid, 'bvid': bvid, 'epid': id }, 'indexedId': $string(cid), 'title': long_title and long_title != '' ? long_title : show_title, 'episodeNumber': $match(title, /^\\d+$/) ? $number(title) : (title and title != '' ? title : undefined), 'imageUrl': cover, 'alternativeTitle': share_copy and share_copy != '' ? [share_copy] : undefined }]"
129
+ "output": "[[media_bangumi.data.result, media_ft.data.result].{ 'providerIds': { 'seasonId': season_id, 'mediaId': media_id }, 'indexedId': $string(season_id), 'title': $replace(title, /<[^>]+>/, ''), 'type': season_type_name, 'typeDescription': season_type_name, 'imageUrl': cover, 'episodeCount': ep_size, 'year': pubtime > 0 ? $number($substring($string($fromMillis(pubtime * 1000)), 0, 4)) : undefined }, ugc.{ 'providerIds': { 'bvid': bvid, 'aid': aid }, 'indexedId': bvid, 'title': $replace(title, /<[^>]+>/, ''), 'type': typename, 'typeDescription': typename, 'imageUrl': 'https:' & $replace(pic, /^https?:/, ''), 'year': pubdate > 0 ? $number($substring($string($fromMillis(pubdate * 1000)), 0, 4)) : undefined }]"
116
130
  },
117
- "season": {
118
- "inputs": ["seasonId"],
119
- "steps": [
120
- {
121
- "type": "http",
122
- "id": "season",
123
- "request": {
124
- "method": "GET",
125
- "url": "'https://api.bilibili.com/pgc/view/web/season'",
126
- "query": "{ 'season_id': $string(seasonId) }",
127
- "credentials": "include",
128
- "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
131
+ "episodes": [
132
+ {
133
+ "inputs": ["seasonId"],
134
+ "steps": [
135
+ {
136
+ "type": "http",
137
+ "id": "season",
138
+ "request": {
139
+ "method": "GET",
140
+ "url": "'https://api.bilibili.com/pgc/view/web/season'",
141
+ "query": "{ 'season_id': $string(seasonId) }",
142
+ "credentials": "include",
143
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
144
+ }
129
145
  }
130
- }
131
- ],
132
- "output": "season.result ? { 'providerIds': { 'seasonId': season.result.season_id, 'mediaId': season.result.media_id }, 'indexedId': $string(season.result.season_id), 'title': $replace(season.result.title, /<[^>]+>/, ''), 'type': season.result.season_type_name ? season.result.season_type_name : $string(season.result.type), 'imageUrl': season.result.cover, 'episodeCount': $count(season.result.episodes[$not($contains(badge ? badge : '', '预告'))]) } : undefined"
133
- },
146
+ ],
147
+ "output": "[season.result.episodes[$not($contains(badge ? badge : '', '预告'))].{ 'providerIds': { 'cid': cid, 'aid': aid, 'bvid': bvid, 'epid': id }, 'indexedId': $string(cid), 'title': long_title and long_title != '' ? long_title : show_title, 'episodeNumber': $match(title, /^\\d+$/) ? $number(title) : (title and title != '' ? title : undefined), 'imageUrl': cover, 'alternativeTitle': share_copy and share_copy != '' ? [share_copy] : undefined }]"
148
+ },
149
+ {
150
+ "when": "$exists(bvid) and $not($exists(seasonId))",
151
+ "inputs": ["bvid"],
152
+ "steps": [
153
+ {
154
+ "type": "http",
155
+ "id": "view",
156
+ "request": {
157
+ "method": "GET",
158
+ "url": "'https://api.bilibili.com/x/web-interface/view'",
159
+ "query": "{ 'bvid': bvid }",
160
+ "credentials": "include",
161
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
162
+ }
163
+ }
164
+ ],
165
+ "output": "($d := view.data; $exists($d.ugc_season) ? [$d.ugc_season.sections.episodes#$i.{ 'providerIds': { 'cid': cid, 'aid': aid, 'bvid': bvid }, 'indexedId': $string(cid), 'title': title, 'episodeNumber': $i + 1, 'imageUrl': 'https:' & $replace(arc.pic, /^https?:/, '') }] : [$d.pages.{ 'providerIds': { 'cid': cid, 'aid': $d.aid, 'bvid': $d.bvid }, 'indexedId': $string(cid), 'title': part, 'episodeNumber': page, 'imageUrl': 'https:' & $replace($d.pic, /^https?:/, '') }])"
166
+ }
167
+ ],
168
+ "season": [
169
+ {
170
+ "inputs": ["seasonId"],
171
+ "steps": [
172
+ {
173
+ "type": "http",
174
+ "id": "season",
175
+ "request": {
176
+ "method": "GET",
177
+ "url": "'https://api.bilibili.com/pgc/view/web/season'",
178
+ "query": "{ 'season_id': $string(seasonId) }",
179
+ "credentials": "include",
180
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
181
+ }
182
+ }
183
+ ],
184
+ "output": "season.result ? { 'providerIds': { 'seasonId': season.result.season_id, 'mediaId': season.result.media_id }, 'indexedId': $string(season.result.season_id), 'title': $replace(season.result.title, /<[^>]+>/, ''), 'type': season.result.season_type_name ? season.result.season_type_name : $string(season.result.type), 'imageUrl': season.result.cover, 'episodeCount': $count(season.result.episodes[$not($contains(badge ? badge : '', '预告'))]) } : undefined"
185
+ },
186
+ {
187
+ "when": "$exists(bvid) and $not($exists(seasonId))",
188
+ "inputs": ["bvid"],
189
+ "steps": [
190
+ {
191
+ "type": "http",
192
+ "id": "view",
193
+ "request": {
194
+ "method": "GET",
195
+ "url": "'https://api.bilibili.com/x/web-interface/view'",
196
+ "query": "{ 'bvid': bvid }",
197
+ "credentials": "include",
198
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
199
+ }
200
+ }
201
+ ],
202
+ "output": "($d := view.data; $exists($d) ? { 'providerIds': { 'bvid': $d.bvid, 'aid': $d.aid }, 'indexedId': $d.bvid, 'title': $d.title, 'type': $d.tname ? $d.tname : undefined, 'imageUrl': 'https:' & $replace($d.pic, /^https?:/, ''), 'episodeCount': $exists($d.ugc_season) ? $count($d.ugc_season.sections.episodes) : $count($d.pages) } : undefined)"
203
+ }
204
+ ],
134
205
  "danmaku": [
135
206
  {
136
207
  "when": "danmakuFormat = 'xml'",
@@ -207,28 +278,48 @@
207
278
  ],
208
279
  "output": "nav.data.isLogin = true"
209
280
  },
210
- "parseUrl": {
211
- "inputs": [],
212
- "steps": [
213
- {
214
- "type": "http",
215
- "id": "season",
216
- "request": {
217
- "method": "GET",
218
- "url": "'https://api.bilibili.com/pgc/view/web/season'",
219
- "query": "{ 'season_id': ssid ? $string(ssid) : undefined, 'ep_id': epid ? $string(epid) : undefined }",
220
- "credentials": "include",
221
- "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
281
+ "parseUrl": [
282
+ {
283
+ "inputs": [],
284
+ "steps": [
285
+ {
286
+ "type": "http",
287
+ "id": "season",
288
+ "request": {
289
+ "method": "GET",
290
+ "url": "'https://api.bilibili.com/pgc/view/web/season'",
291
+ "query": "{ 'season_id': ssid ? $string(ssid) : undefined, 'ep_id': epid ? $string(epid) : undefined }",
292
+ "credentials": "include",
293
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
294
+ }
295
+ },
296
+ {
297
+ "type": "assign",
298
+ "id": "picked",
299
+ "values": {
300
+ "ep": "epid ? ($epIdNum := $number(epid); season.result.episodes[id = $epIdNum]) : season.result.episodes[0]"
301
+ }
222
302
  }
223
- },
224
- {
225
- "type": "assign",
226
- "id": "picked",
227
- "values": {
228
- "ep": "epid ? ($epIdNum := $number(epid); season.result.episodes[id = $epIdNum]) : season.result.episodes[0]"
303
+ ],
304
+ "output": "{ 'seasonInsert': { 'providerIds': { 'seasonId': season.result.season_id }, 'indexedId': $string(season.result.season_id), 'title': $replace(season.result.title, /<[^>]+>/, ''), 'type': $string(season.result.type), 'imageUrl': season.result.cover, 'episodeCount': $count(season.result.episodes) }, 'episodeMeta': $exists(picked.ep) ? { 'providerIds': { 'cid': picked.ep.cid, 'aid': picked.ep.aid, 'bvid': picked.ep.bvid, 'epid': picked.ep.id }, 'indexedId': $string(picked.ep.cid), 'title': picked.ep.long_title and picked.ep.long_title != '' ? picked.ep.long_title : picked.ep.show_title, 'episodeNumber': $match(picked.ep.title, /^\\d+$/) ? $number(picked.ep.title) : (picked.ep.title and picked.ep.title != '' ? picked.ep.title : undefined), 'imageUrl': picked.ep.cover, 'externalLink': picked.ep.link } : undefined }"
305
+ },
306
+ {
307
+ "when": "$exists(bvid) or $exists(aid)",
308
+ "inputs": [],
309
+ "steps": [
310
+ {
311
+ "type": "http",
312
+ "id": "view",
313
+ "request": {
314
+ "method": "GET",
315
+ "url": "'https://api.bilibili.com/x/web-interface/view'",
316
+ "query": "{ 'bvid': bvid ? bvid : undefined, 'aid': aid ? $string(aid) : undefined }",
317
+ "credentials": "include",
318
+ "rewriteHeaders": { "Referer": "'https://www.bilibili.com/'" }
319
+ }
229
320
  }
230
- }
231
- ],
232
- "output": "{ 'seasonInsert': { 'providerIds': { 'seasonId': season.result.season_id }, 'indexedId': $string(season.result.season_id), 'title': $replace(season.result.title, /<[^>]+>/, ''), 'type': $string(season.result.type), 'imageUrl': season.result.cover, 'episodeCount': $count(season.result.episodes) }, 'episodeMeta': $exists(picked.ep) ? { 'providerIds': { 'cid': picked.ep.cid, 'aid': picked.ep.aid, 'bvid': picked.ep.bvid, 'epid': picked.ep.id }, 'indexedId': $string(picked.ep.cid), 'title': picked.ep.long_title and picked.ep.long_title != '' ? picked.ep.long_title : picked.ep.show_title, 'episodeNumber': $match(picked.ep.title, /^\\d+$/) ? $number(picked.ep.title) : (picked.ep.title and picked.ep.title != '' ? picked.ep.title : undefined), 'imageUrl': picked.ep.cover, 'externalLink': picked.ep.link } : undefined }"
233
- }
321
+ ],
322
+ "output": "($d := view.data; $eps := $d.ugc_season.sections.episodes; { 'seasonInsert': { 'providerIds': { 'bvid': $d.bvid, 'aid': $d.aid }, 'indexedId': $d.bvid, 'title': $d.title, 'type': $d.tname ? $d.tname : undefined, 'imageUrl': 'https:' & $replace($d.pic, /^https?:/, ''), 'episodeCount': $exists($d.ugc_season) ? $count($d.ugc_season.sections.episodes) : $count($d.pages) }, 'episodeMeta': { 'providerIds': { 'cid': $d.cid, 'aid': $d.aid, 'bvid': $d.bvid }, 'indexedId': $string($d.cid), 'title': $d.title, 'episodeNumber': $exists($eps) ? ($eps#$i[bvid = $d.bvid].($i + 1))[0] : 1, 'imageUrl': 'https:' & $replace($d.pic, /^https?:/, ''), 'externalLink': 'https://www.bilibili.com/video/' & $d.bvid } })"
323
+ }
324
+ ]
234
325
  }
@@ -8,7 +8,7 @@
8
8
  "name": "芒果TV"
9
9
  }
10
10
  },
11
- "version": "0.6.0",
11
+ "version": "0.7.0",
12
12
  "hosts": [
13
13
  "mobileso.bz.mgtv.com",
14
14
  "pcweb.api.mgtv.com",
@@ -39,7 +39,7 @@
39
39
  }
40
40
  }
41
41
  ],
42
- "output": "[search.data.contents[type='mediaRebirthV2'].data[($not($exists(source)) or source = '' or source = 'imgo') and clipId != ''].($cid := $string(clipId); $descText := $type(desc) = 'array' ? desc[0] : desc; { 'providerIds': { 'collectionId': $cid }, 'indexedId': $cid, 'title': $trim($replace(title, /<[^>]+>/, '')), 'type': $trim($replace($substringBefore($descText, '/'), '类型:', '')), 'year': $number($regexExtract($descText, '([12][890][0-9][0-9])')), 'imageUrl': img, 'episodeCount': videoCount })]"
42
+ "output": "($media := search.data.contents[type='mediaRebirthV2' or type='mediaRebirthV3'].data[($not($exists(source)) or source = '' or source = 'imgo') and clipId != '']; $seen := [$map($media, function($m) { $string($m.clipId) })]; $series := search.data.contents[type='clipMerge'].data.dataList[clipId != '' and $not($string(clipId) in $seen)]; $append([$media.($cid := $string(clipId); $descText := $type(desc) = 'array' ? desc[0] : desc; { 'providerIds': { 'collectionId': $cid }, 'indexedId': $cid, 'title': $trim($replace(title, /<[^>]+>/, '')), 'type': $trim($replace($substringBefore($descText, '/'), '类型:', '')), 'year': $number($regexExtract($descText, '([12][890][0-9][0-9])')), 'imageUrl': img, 'episodeCount': videoCount })], [$series.($cid := $string(clipId); { 'providerIds': { 'collectionId': $cid }, 'indexedId': $cid, 'title': $trim($replace(title, /<[^>]+>/, '')), 'imageUrl': img })]))"
43
43
  },
44
44
  "episodes": {
45
45
  "inputs": ["collectionId"],