diff --git a/prevails/bgmlist_integrator.user.js b/prevails/bgmlist_integrator.user.js
index 1d0e1cc7..05c3d3ee 100644
--- a/prevails/bgmlist_integrator.user.js
+++ b/prevails/bgmlist_integrator.user.js
@@ -26,6 +26,8 @@ const addOnSources = {
////////////////////////////////////////////////////////////////
};
+const DEBUG = false;
+const CACHE_VERSION = 1;
const TIME_ZONE = 'CN';
// valid value: 'CN', 'JP'
@@ -65,7 +67,7 @@ class Bangumi {
this.bgm = bgmlist[this.id];
this.a = a;
if (addOnSources && addOnSources[this.id]) {
- this.bgm.onAirSite = addOnSources[this.id].concat(this.bgm.onAirSite);
+ this.bgm.onAirSite = addOnSources[this.id].map(url => ({ title: url.replace(/https?:\/\/.+?\./, '').split('/')[0], url: url })).concat(this.bgm.onAirSite);
}
}
getTime() {
@@ -84,9 +86,9 @@ class Bangumi {
}
get$Html() {
const $re = $(this.a).clone();
- $re.find('img').removeAttr('class');
+ $re.find('img').removeAttr('class').attr('width', 48);
$re.find('span').remove();
- $re.attr('title', this.bgm.titleCN + '\n'+ this.bgm.titleJP + '\n播放时间:\n' + this.getTime());
+ $re.attr('title', this.bgm.titleCN + '\n' + this.bgm.titleJP + '\n播放时间:\n' + this.getTime());
$re.attr('alt', this.bgm.titleCN + '
' + this.bgm.titleJP);
$re.data('onAirSite', this.bgm.onAirSite);
return $re;
@@ -114,7 +116,7 @@ class Bangumi {
}
const myBangumis = $('#prgSubjectList > [subject_type=2] > .thumbTip')
- .toArray().map(i => new Bangumi(i.getAttribute('subject_id'), i)).filter(i => i.bgm);
+ .toArray().map(i => new Bangumi(i.getAttribute('subject_id'), i)).filter(i => i.bgm);
$('.tooltip').hide();
$('.week:eq(1)').remove();
@@ -137,7 +139,7 @@ $week.each(function () {
$div.html('');
const weekDay = WEEK_DAY.indexOf(this.classList[2]); //
myBangumis.filter(i => i.bgm['weekDay' + TIME_ZONE] === weekDay && i.isInRange(lastWeekRange))
- .forEach(i => $div.append(i.get$Html()));
+ .forEach(i => $div.append(i.get$Html()));
});
function rmTbWindow() {
@@ -165,14 +167,14 @@ $week.find('.thumbTip').click(function () {
${onAirSite.map((v, i) => `
-
-
+
`.trim()).join('')}
`, style);
return false;
});
-GM_addStyle('#TB_window.userscript_bgmlist_integrator{display:block;width:' + TB_WINDOW_WIDTH + 'px;}');
+GM_addStyle('#TB_window.userscript_bgmlist_integrator{display:block;width:' + TB_WINDOW_WIDTH + 'px;padding:8px;}');
const CHECK_UPDATE_INTERVAL = 1000 * 60 * 60 * 8; // 8h
@@ -184,64 +186,134 @@ function getLast(obj) {
return obj[last];
}
-function createIndexOnBgmId(bgmlistOriginJson) {
- const origin = JSON.parse(bgmlistOriginJson);
- const bgmlist = {};
- for (let i in origin) {
- bgmlist[origin[i].bgmId] = origin[i];
- }
- return bgmlist;
+const LANG_TO_REGIONS = {
+ 'ja': ['JP'],
+ 'zh-Hans': ['CN'],
+ 'zh-Hant': ['TW', 'MO', 'HK'],
+ 'en': [],
}
-function update({path, version}) {
- GM_xmlhttpRequest({
- method: 'GET',
- url: path,
- data: {"__t": Date.now()},
- onload: function(response) {
- if (response.status === 200) {
- GM_setValue('bgmlist', createIndexOnBgmId(response.responseText));
- GM_setValue('path', path);
- GM_setValue('version', version);
- showTbWindow('bgmlist 数据更新成功! 请刷新页面
',
- 'left:80%;top:20px;width:18%;');
- setTimeout(rmTbWindow, 5000);
- } else {
- showTbWindow(`Error, status code: ${response.status}
`,
- 'left:80%;top:20px;width:18%;');
- setTimeout(rmTbWindow, 5000);
+async function update({ paths, version }) {
+ const items = (await Promise.all(paths.split(',').map(path => request(path)))).reduce((r, it) => r.concat(it.items), []);
+
+ const siteInfoMap = await request('https://bgmlist.com/api/v1/bangumi/site');
+ // 不需要bangumi的站点信息, 删掉它
+ delete siteInfoMap.bangumi;
+
+ const bgmlist = {};
+ for (let item of items) {
+ for (const site of item.sites) {
+ if (site.site == 'bangumi') {
+ const titleTranslate = {
+ [item.lang]: [item.title],
+ ...item.titleTranslate,
+ }
+ const allSites = [
+ ...item.sites
+ .filter(it => it.site !== 'bangumi')
+ .map((site) => ({
+ site: site.site,
+ id: site.id,
+ url: site.url,
+ begin: site.begin,
+ end: site.end ?? '',
+ broadcast: site.broadcast,
+ regions: site.regions ?? siteInfoMap[site.site]?.regions ?? [],
+ })),
+ {
+ site: 'origin',
+ id: undefined,
+ url: undefined,
+ begin: item.begin,
+ end: item.end ?? '',
+ broadcast: item.broadcast,
+ // 为空的regions是特殊值, 表示该site支持所有区域
+ regions: LANG_TO_REGIONS[item.lang] ?? [],
+ },
+ ]
+ const cnSites = allSites.filter(it => it.regions.length == 0 || it.regions.some(r => ['CN', 'TW', 'MO', 'HK'].includes(r)));
+ const jpSites = allSites.filter(it => it.regions.length == 0 || it.regions.includes('JP'));
+ const getBeginDate = (sites) => sites.filter(it => it.broadcast || it.begin).map(it => new Date(it.broadcast?.split('/')[1] ?? it.begin)).sort((a, b) => a - b)[0];
+ const cnDate = getBeginDate(cnSites);
+ const jpDate = getBeginDate(jpSites);
+ const getWeek = (date) => WEEK_DAY.indexOf(date.toDateString().substr(0, 3))
+ const getTime = (date) => `${date.getHours().toString().padStart(2, '0')}${date.getMinutes().toString().padStart(2, '0')}`;
+
+ // 将新的播放信息转换成旧的播放信息...
+ // 参考: https://github.com/bangumi-data/bangumi-data/blob/master/CONTRIBUTING.md/#%E7%95%AA%E7%BB%84%E6%95%B0%E6%8D%AE
+ bgmlist[site.id] = {
+ _source: DEBUG ? item : undefined,
+ titleCN: [...(titleTranslate['zh-Hans'] ?? []), ...(titleTranslate['zh-Hant'] ?? [])]?.join('/') ?? '',
+ titleJP: titleTranslate['ja']?.join('/') ?? '',
+ titleEn: titleTranslate['en']?.join('/') ?? '',
+ weekDayJP: getWeek(jpDate),
+ weekDayCN: getWeek(cnDate ?? jpDate),
+ timeJP: getTime(jpDate),
+ timeCN: cnDate != null ? getTime(cnDate) : '',
+ onAirSite: item.sites.map((site) => ({
+ title: siteInfoMap[site.site]?.title ?? site.site,
+ url: site.url ?? siteInfoMap[site.site]?.urlTemplate.replace('{{id}}', site.id)
+ })).filter(it => it.url),
+ officalSite: item.officalSite,
+ bgmId: +site.id,
+ showDate: item.begin,
+ endDate: item.end,
+ newBgm: false,
+ };
+ break;
}
}
- });
+ }
+ GM_setValue('bgmlist', bgmlist);
+ GM_setValue('paths', paths);
+ GM_setValue('version', version);
+ GM_setValue('cacheVersion', CACHE_VERSION)
+
+ showTbWindow('bgmlist 数据更新成功! 请刷新页面
',
+ 'left:80%;top:20px;width:18%;');
+ setTimeout(rmTbWindow, 5000);
}
function checkUpdate() {
+ const forceUpdate = (GM_getValue('cacheVersion') || 0) !== CACHE_VERSION;
const lastCheckUpdate = GM_getValue('lastCheckUpdate') || 0;
- if (new Date().getTime() - lastCheckUpdate < CHECK_UPDATE_INTERVAL) {
+ if (new Date().getTime() - lastCheckUpdate < CHECK_UPDATE_INTERVAL && !forceUpdate && !DEBUG) {
return;
}
- GM_xmlhttpRequest({
- method: 'GET',
- url: 'https://bgmlist.com/tempapi/archive.json',
- data: {"__t": Date.now()},
- onload: function (response) {
- if (response.status === 200) {
- const archive = JSON.parse(response.responseText);
- const data = archive.data;
- const last = getLast(getLast(data));
- const oldPath = GM_getValue('path');
- const oldVersion = GM_getValue('version');
- if (!oldPath || !oldVersion || last.path > oldPath || last.version > oldVersion) {
- update(last);
- }
- GM_setValue('lastCheckUpdate', new Date().getTime());
- } else {
- showTbWindow(`Error, status code: ${response.status}
`,
- 'left:80%;top:20px;width:18%;');
- setTimeout(rmTbWindow, 5000);
+ request('https://bgmlist.com/api/v1/bangumi/season/?start=2020q1')
+ .then((archive) => {
+ const version = archive.version
+
+ // 拉取最近两年的数据
+ const paths = archive.items.slice(-8).map(it => `https://bgmlist.com/api/v1/bangumi/archive/${it}`).join(',');
+ const oldPaths = GM_getValue('paths');
+ const oldVersion = GM_getValue('version');
+ if (!oldPaths || !oldVersion || paths != oldPaths || version != oldVersion || forceUpdate || DEBUG) {
+ update({ paths: paths, version: version });
}
- }
- });
+ GM_setValue('lastCheckUpdate', new Date().getTime());
+ })
}
setTimeout(checkUpdate, 500);
+
+function request(url, { showError = true } = {}) {
+ return new Promise((resolve, reject) => {
+ GM_xmlhttpRequest({
+ method: 'GET',
+ url: url,
+ onload: function (response) {
+ if (response.status === 200) {
+ resolve(JSON.parse(response.responseText));
+ } else {
+ if (showError) {
+ showTbWindow(`Error, status code: ${response.status}
`,
+ 'left:80%;top:20px;width:18%;');
+ setTimeout(rmTbWindow, 5000);
+ }
+ reject(response);
+ }
+ }
+ });
+ });
+}