// ==UserScript==
// @name bilibili favlist backup
// @name:zh-CN 哔哩哔哩(B站|Bilibili)收藏夹Fix (备份视频信息)
// @name:zh-TW 嗶哩嗶哩(B站|Bilibili)收藏夾Fix (備份影片資訊)
// @namespace http://tampermonkey.net/
// @version 1
// @description automatically backup info of videos in favlist
// @description:zh-CN 自动备份视频信息至本地和第三方网站, 失效视频信息回显
// @description:zh-TW 自動備份影片資訊至本地和第三方網站, 失效影片資訊回顯
// @author YTB0710
// @match https://space.bilibili.com/*
// @connect bbdownloader.com
// @connect bilibili.com
// @connect biliplus.com
// @connect jijidown.com
// @connect xbeibeix.com
// @grant GM_openInTab
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function () {
'use strict';
const localizedText = {
'UPDATES': {
'zh-CN': '',
'zh-TW': ''
},
'DROPDOWN_COVER': {
'zh-CN': '封面原图',
'zh-TW': '封面原圖'
},
'DROPDOWN_LOCAL': {
'zh-CN': '本地备份数据',
'zh-TW': '本地備份資料'
},
'DROPDOWN_JUMP': {
'zh-CN': '跳转至BJX',
'zh-TW': '跳轉至BJX'
},
'DROPDOWN_RESET': {
'zh-CN': '重置备份数据',
'zh-TW': '重置備份資料'
},
'ONLY_PROCESS_DISABLED': {
'zh-CN': '仅处理失效视频',
'zh-TW': '僅處理失效影片'
},
'AUTO_NEXT_PAGE': {
'zh-CN': '自动点击下一页',
'zh-TW': '自動點擊下一頁'
},
'ENABLE_DEBUG': {
'zh-CN': '控制台输出日志',
'zh-TW': '控制台輸出日誌'
},
'AV': {
'zh-CN': 'AV号',
'zh-TW': 'AV號'
},
'BV': {
'zh-CN': 'BV号',
'zh-TW': 'BV號'
},
'TITLE': {
'zh-CN': '标题',
'zh-TW': '標題'
},
// 'POSITION_ON_THIS_PAGE': {
// 'zh-CN': '在本页的位置',
// 'zh-TW': '在本頁的位置'
// },
// 'POSITION_ON_THIS_PAGE_WITH_PROMPT': {
// 'zh-CN': '在本页的位置(从1开始)',
// 'zh-TW': '在本頁的位置(從1開始)'
// },
'FID_NOT_FOUND_ERROR': {
'zh-CN': '无法获取当前收藏夹的fid, 刷新页面可能有帮助',
'zh-TW': '無法獲取當前收藏夾的fid, 重新載入頁面可能有幫助'
},
'REQUEST_TIMEOUT_ERROR': {
'zh-CN': '请求超时',
'zh-TW': '請求逾時'
},
'REQUEST_FAILED_ERROR': {
'zh-CN': '请求失败',
'zh-TW': '請求失敗'
},
'MULTIPLE_DROPDOWN_FOUND_ERROR': {
'zh-CN': '同时发现了多个下拉列表开关, 无法确定下拉列表所对应的视频, 刷新页面可能有帮助',
'zh-TW': '同時發現了多個下拉列表開關, 無法確定下拉列表所對應的影片, 重新載入頁面可能有幫助'
},
'TARGET_VIDEO_NOT_FOUND_ERROR': {
'zh-CN': '无法确定下拉列表所对应的视频, 请反馈该问题',
'zh-TW': '無法確定下拉列表所對應的影片, 請反饋該問題'
},
'UNKNOWN_ERROR': {
'zh-CN': '发生未知错误, 请反馈该问题',
'zh-TW': '發生未知錯誤, 請反饋該問題'
},
};
const currentVersion = 1;
const preferredLanguage = getPreferredLanguage();
const settings = GM_getValue('settings', {
version: 0,
onlyProcessDisabled: false,
// alwaysGetIntroFromVideoPage: false,
enableDebug: false,
usageCount: 0,
usageCountNewFreshSpace: 0,
});
const favlistURLRegex = /https:\/\/space\.bilibili\.com\/\d+\/favlist.*/;
const fidFromURLRegex = /fid=(\d+)/;
const BVFromURLRegex = /video\/(\w{12})/;
const httpsFromURLRegex = /^https?:\/\//;
const jsonFromBiliplusRegex = /window\.addEventListener\('DOMContentLoaded',function\(\){view\((.+)\);}\);/;
let AVBVs;
let fidOfAVBVs;
let onFavlistPage = false;
let autoNextPage = false;
let newFreshSpace;
let videosPerPage;
let displayPrompt;
let processing;
// let mutations_count = 0;
// let mutation_count = 0;
// let first = true;
let divMessage;
let activeControllers = new Set();
const favlistObserver = new MutationObserver((mutations, observer) => {
if (settings.enableDebug) console.warn('callback favlistObserver');
if (document.querySelector('div.items')) {
if (settings.enableDebug) console.warn('disconnect favlistObserver');
observer.disconnect();
newFreshSpace = true;
videosPerPage = window.innerWidth < 1760 ? 40 : 36;
addControls();
main();
if (settings.enableDebug) console.warn('observe itemsObserver');
itemsObserver.observe(document.querySelector('div.items'), { childList: true, attributes: false, characterData: false });
if (settings.enableDebug) console.warn('observe bodyChildListObserver');
bodyChildListObserver.observe(document.body, { childList: true, attributes: false, characterData: false });
return;
}
if (document.querySelector('div.fav-content.section')) {
if (settings.enableDebug) console.warn('disconnect favlistObserver');
observer.disconnect();
newFreshSpace = false;
videosPerPage = 20;
addControls();
if (settings.enableDebug) console.warn('observe favContentSectionObserver');
favContentSectionObserver.observe(document.querySelector('div.fav-content.section'), { characterData: false, attributeFilter: ['class'] });
return;
}
});
const itemsObserver = new MutationObserver(async (mutations) => {
stopAll();
if (settings.enableDebug) console.warn('callback itemsObserver');
await delay(100);
// mainNewFreshSpace();
// mainNewFreshSpace(mutations);
main();
});
const bodyChildListObserver = new MutationObserver(mutations => {
if (settings.enableDebug) console.warn('callback bodyChildListObserver');
if (settings.enableDebug) console.log(mutations);
for (const mutation of mutations) {
for (const addedNode of mutation.addedNodes) {
if (addedNode.nodeType === 1 && addedNode.classList.contains('bili-card-dropdown-popper')) {
addDropdown(addedNode);
// return;
}
if (addedNode.nodeType === 1 && addedNode.classList.contains('vui_toast--wrapper')) {
stopAll();
if (settings.enableDebug) console.warn('disconncet itemsObserver');
itemsObserver.disconnect();
// return;
}
}
for (const removedNode of mutation.removedNodes) {
if (removedNode.nodeType === 1 && removedNode.classList.contains('vui_toast--wrapper')) {
stopAll();
// mainNewFreshSpace();
main();
if (settings.enableDebug) console.warn('observe itemsObserver');
itemsObserver.observe(document.querySelector('div.items'), { childList: true, attributes: false, characterData: false });
// return;
}
}
}
});
const favContentSectionObserver = new MutationObserver(mutations => {
if (settings.enableDebug) console.warn('callback favContentSectionObserver');
for (const mutation of mutations) {
if (!mutation.target.classList.contains('loading')) {
stopAll();
main();
return;
}
}
});
checkURL();
const originalPushState = history.pushState;
history.pushState = function (...args) {
originalPushState.apply(this, args);
checkURL();
};
const originalReplaceState = history.replaceState;
history.replaceState = function (...args) {
originalReplaceState.apply(this, args);
checkURL();
};
window.addEventListener('popstate', checkURL);
function checkURL() {
if (settings.enableDebug) console.warn('checkURL');
if (favlistURLRegex.test(location.href)) {
if (!onFavlistPage) {
onFavlistPage = true;
if (settings.enableDebug) console.warn('observe favlistObserver');
favlistObserver.observe(document.body, { subtree: true, childList: true, attributes: false, characterData: false });
}
} else {
if (onFavlistPage) {
stopAll();
onFavlistPage = false;
if (settings.enableDebug) console.warn('disconnect favlistObserver');
favlistObserver.disconnect();
if (settings.enableDebug) console.warn('disconncet itemsObserver');
itemsObserver.disconnect();
if (settings.enableDebug) console.warn('disconncet bodyChildListObserver');
bodyChildListObserver.disconnect();
if (settings.enableDebug) console.warn('disconncet favContentSectionObserver');
favContentSectionObserver.disconnect();
}
}
}
function getPreferredLanguage() {
const languages = navigator.languages || [navigator.language];
for (const lang of languages) {
if (lang === 'zh-CN') {
return 'zh-CN';
}
if (lang === 'zh-TW') {
return 'zh-TW';
}
if (lang === 'zh-HK') {
return 'zh-TW';
}
}
return 'zh-CN';
}
function getLocalizedText(key) {
return localizedText[key][preferredLanguage];
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function getCurrentTs() {
return Math.floor(Date.now() / 1000);
}
function stopAll() {
for (const controller of activeControllers) {
controller.abort();
}
}
async function main() {
if (settings.enableDebug) console.warn('============main============');
let processing;
let controller;
try {
processing = true;
controller = new AbortController();
activeControllers.add(controller);
let fid;
if (newFreshSpace) {
const fidFromURLMatch = location.href.match(fidFromURLRegex);
if (fidFromURLMatch) {
fid = fidFromURLMatch[1];
} else {
// addMessage('-----------------------------');
addMessage(getLocalizedText('FID_NOT_FOUND_ERROR'));
return;
}
} else {
fid = document.querySelector('.fav-item.cur').getAttribute('fid');
}
let pn;
if (newFreshSpace) {
const pagenation = document.querySelector('button.vui_pagenation--btn-num.vui_button--active');
if (!pagenation) {
pn = 1;
} else {
pn = parseInt(pagenation.innerText, 10);
}
} else {
pn = parseInt(document.querySelector('li.be-pager-item-active > a').innerText, 10);
}
let videos;
if (newFreshSpace) {
videos = document.querySelectorAll('div.items__item');
} else {
videos = document.querySelectorAll('li.small-item');
}
if (fid !== fidOfAVBVs || !AVBVs) {
if (controller.signal.aborted) {
// throw Error();
throw new DOMException('', 'AbortError');
}
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://api.bilibili.com/x/v3/fav/resource/ids?media_id=${fid}`,
timeout: 5000,
responseType: 'json',
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
if (settings.enableDebug) console.warn(`update AVBVs, fid: ${fid}`);
fidOfAVBVs = fid;
AVBVs = response.response.data;
}
const _AVBVs = structuredClone(AVBVs);
let apiDetails = {};
// for (const video of videos) {
for (const [index, video] of videos.entries()) {
let as;
let AV;
let BV;
let title;
try {
if (controller.signal.aborted) {
// throw Error();
throw new DOMException('', 'AbortError');
}
let disabled = false;
if (newFreshSpace && !video.querySelector('.bili-cover-card__stats')) {
disabled = true;
} else if (video.classList.contains('disabled')) {
disabled = true;
}
if (settings.onlyProcessDisabled && !disabled) {
continue;
}
as = video.querySelectorAll('a');
const divTitleNewFreshSpace = video.querySelector('.bili-video-card__title');
if (controller.signal.aborted) {
// throw Error();
throw new DOMException('', 'AbortError');
}
if (newFreshSpace) {
BV = as[0].getAttribute('href').match(BVFromURLRegex)[1];
} else {
BV = video.getAttribute('data-aid');
}
AV = _AVBVs.find(_AVBV => _AVBV.bvid === BV).id;
title = as[1].innerText;
if (settings.enableDebug) console.warn('============video============');
if (settings.enableDebug) console.log(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('log', AV, BV, title);
let spanFavTime;
let divTCABJX;
if (newFreshSpace) {
const divSubtitle = document.createElement('div');
divSubtitle.classList.add('bili-video-card__subtitle');
video.querySelector('div.bili-video-card__details').appendChild(divSubtitle);
spanFavTime = document.createElement('span');
spanFavTime.innerText = `收藏于:`;
divSubtitle.appendChild(spanFavTime);
divTCABJX = document.createElement('div');
divTCABJX.style.marginLeft = 'auto';
divTCABJX.style.display = 'block';
divSubtitle.appendChild(divTCABJX);
} else {
const divMetaPubdate = video.querySelector('div.meta.pubdate');
const metaText = divMetaPubdate.innerText;
divMetaPubdate.innerHTML = null;
spanFavTime = document.createElement('span');
// spanPubdate.innerText = metaText;
// spanPubdate.innerText = metaText.replace(': ',': ');
spanFavTime.innerText = metaText.replace(': ', ':');
spanFavTime.style.width = 'auto';
divMetaPubdate.appendChild(spanFavTime);
// divTCABJX = document.createElement('div');
// divTCABJX.style.marginLeft = 'auto';
// // divTCABJX.style.display = 'block';
// divMetaPubdate.appendChild(divTCABJX);
divTCABJX = divMetaPubdate;
}
const spanX = document.createElement('span');
spanX.innerText = 'X';
if (!newFreshSpace) {
// spanX.style.marginRight = '11px';
spanX.style.marginRight = '9px';
}
spanX.style.float = 'right';
spanX.style.fontWeight = 'bold';
spanX.style.cursor = 'pointer';
spanX.addEventListener('click', () => {
try {
GM_openInTab(`https://xbeibeix.com/video/${BV}`, { active: true, insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanX);
const spanJ = document.createElement('span');
spanJ.innerText = 'J';
spanJ.style.marginRight = '3px';
spanJ.style.float = 'right';
spanJ.style.fontWeight = 'bold';
spanJ.style.cursor = 'pointer';
spanJ.addEventListener('click', () => {
try {
GM_openInTab(`https://www.jijidown.com/video/${BV}`, { active: true, insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanJ);
const spanB = document.createElement('span');
spanB.innerText = 'B';
spanB.style.marginRight = '3px';
spanB.style.float = 'right';
spanB.style.fontWeight = 'bold';
spanB.style.cursor = 'pointer';
spanB.addEventListener('click', () => {
try {
GM_openInTab(`https://www.biliplus.com/video/${BV}`, { active: true, insert: false, setParent: true });
GM_openInTab(`https://www.biliplus.com/video/av${AV}`, { insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanB);
const spanA = document.createElement('span');
spanA.innerText = 'A';
spanA.style.marginRight = '3px';
spanA.style.float = 'right';
spanA.style.fontWeight = 'bold';
spanA.style.cursor = 'pointer';
spanA.addEventListener('click', () => {
try {
// GM_openInTab(`https://api.bilibili.com/x/v3/fav/resource/list?media_id=${fid}&pn=${pn}&ps=${videosPerPage}&keyword=&order=mtime&type=0&tid=0&platform=web`, { active: true, insert: false, setParent: true });
GM_openInTab(`https://api.bilibili.com/x/v3/fav/resource/list?media_id=${fid}&pn=${(pn - 1) * videosPerPage + index + 1}&ps=1&order=mtime`, { active: true, insert: false, setParent: true });
GM_openInTab(`https://api.bilibili.com/x/v3/fav/resource/infos?resources=${AV}%3A2&folder_id=${fid}`, { insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanA);
let backup = GM_getValue(BV, {
AV: null,
BV: null,
title: null,
intro: null,
cover: null,
upperUid: null,
upperName: null,
upperAvatar: null,
timeUpload: null,
timePublish: null,
timeFavorite: null,
firstFrame: null,
api: null,
biliplus: null,
jijidown: null,
xbeibeix: null,
preferredTitle: null,
preferredCover: null
});
let functions = [];
try {
if (!backup.api
|| (backup.api.value === false && getCurrentTs() - backup.api.ts > 3600 * 1)
|| (backup.api.value === true && getCurrentTs() - backup.api.ts > 3600 * 1)) {
await getFromApi(AV, BV, title, backup, spanA, apiDetails, fid, pn, disabled, spanFavTime);
} else {
spanA.style.color = backup.api.value ? '#00ff00' : '#ff0000';
if (backup.timeFavorite) {
const target = backup.timeFavorite.find(i => i.fid === fid);
if (target) {
// spanFavTime.innerText = `收藏于: ${new Date(target.value * 1000).toLocaleString()}`;
// spanFavTime.innerText = `收藏于: ${formatTimeFavorite1(target.value)}`;
// spanFavTime.innerText = `收藏于: ${formatTimeFavorite2(new Date(target.value * 1000))}`;
spanFavTime.innerText = `收藏于:${formatTimeFavorite2(new Date(target.value * 1000))}`;
// spanFavTime.innerText = `收藏于: ${formatTimeFavorite3(target.value)}`;
}
}
}
if (!backup.jijidown
|| (backup.jijidown.value === false && getCurrentTs() - backup.jijidown.ts > 3600 * 24 * 30)
|| (backup.jijidown.value === true && getCurrentTs() - backup.jijidown.ts > 3600 * 24 * 30)) {
functions.push(getFromJijidown(AV, BV, title, backup, spanJ));
} else {
spanJ.style.color = backup.jijidown.value ? '#00ff00' : '#ff0000';
}
if (!backup.xbeibeix
|| (backup.xbeibeix.value === false && getCurrentTs() - backup.xbeibeix.ts > 3600 * 24 * 30)
|| (backup.xbeibeix.value === true && getCurrentTs() - backup.xbeibeix.ts > 3600 * 24 * 30)) {
functions.push(getFromXbeibeix(AV, BV, title, backup, spanX));
} else {
spanX.style.color = backup.xbeibeix.value ? '#00ff00' : '#ff0000';
}
if (!backup.biliplus
|| (backup.biliplus.value === false && getCurrentTs() - backup.biliplus.ts > 3600 * 24 * 30)
|| (backup.biliplus.value === true && getCurrentTs() - backup.biliplus.ts > 3600 * 24 * 30)) {
functions.push(getFromBiliplus(AV, BV, title, backup, spanB));
} else {
spanB.style.color = backup.biliplus.value ? '#00ff00' : '#ff0000';
}
if (functions.length) {
if (controller.signal.aborted) {
// throw Error();
throw new DOMException('', 'AbortError');
}
await Promise.all(functions);
if (settings.enableDebug) console.warn('GM_setValue BJX');
if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(backup);
GM_setValue(BV, backup);
}
} catch (error) {
// if (controller.signal.aborted) {
if (error.name === 'AbortError') {
throw error;
} else {
// addMessage('-----------------------------');
addMessage(getLocalizedText('UNKNOWN_ERROR'));
// addMessage(`fid: ${fid} pn: ${pn} index: ${index + 1}`, true);
// addMessage(`${getLocalizedText('POSITION_ON_THIS_PAGE' + displayPrompt)}: ${index + 1}`, true);
addMessageAVBVTitle(AV, BV, title);
// addMessage(error.message, true);
addMessage(error.stack, true);
// console.error(`fid: ${fid} pn: ${pn} index: ${index + 1}`);
console.error(`index: ${index + 1}`);
consoleAVBVTitle('error', AV, BV, title);
console.error(error);
if (as[1]) {
as[1].style.color = '#ff0000';
}
}
}
// let mutiOther = 0;
// if (backup.intro && backup.intro.length > 1) {
// mutiOther = 1;
// }
// if (backup.timeUpload && backup.timeUpload.length > 1) {
// mutiOther = 2;
// }
// if (backup.timePublish && backup.timePublish.length > 1) {
// mutiOther = 2;
// }
let picture;
let avifSource;
let webpSource;
let imgElement;
if (newFreshSpace) {
imgElement = video.querySelector('img');
} else {
picture = video.querySelector('picture');
avifSource = picture.querySelector('source[type="image/avif"]');
webpSource = picture.querySelector('source[type="image/webp"]');
imgElement = picture.querySelector('img');
}
if (disabled) {
if (newFreshSpace) {
if (backup.cover) {
imgElement.setAttribute('src', `//${backup.cover[backup.cover.length - 1].value}@672w_378h_1c.avif`);
}
} else {
video.classList.remove('disabled');
as[0].classList.remove('disabled');
// spanPubdate.style.textDecoration = 'line-through';
if (backup.cover) {
avifSource.setAttribute('srcset', `//${backup.cover[backup.cover.length - 1].value}@320w_200h_1c_!web-space-favlist-video.avif`);
webpSource.setAttribute('srcset', `//${backup.cover[backup.cover.length - 1].value}@320w_200h_1c_!web-space-favlist-video.webp`);
imgElement.setAttribute('src', `//${backup.cover[backup.cover.length - 1].value}@320w_200h_1c_!web-space-favlist-video.webp`);
}
}
as[1].style.textDecoration = 'line-through';
if (backup.title) {
as[1].textContent = backup.title[backup.title.length - 1].value;
if (newFreshSpace) {
divTitleNewFreshSpace.setAttribute('title', backup.title[backup.title.length - 1].value);
} else {
as[1].setAttribute('title', backup.title[backup.title.length - 1].value);
}
// } else {
// as[1].textContent = '/////////////////////////////';
// as[1].textContent = '';
}
}
if (backup.cover && backup.cover.length > 1) {
const spanC = document.createElement('span');
spanC.innerText = 'C';
spanC.style.marginRight = '3px';
spanC.style.float = 'right';
spanC.style.fontWeight = 'bold';
spanC.style.cursor = 'pointer';
spanC.style.color = '#000000';
let i = backup.cover.length - 2;
spanC.addEventListener('click', () => {
try {
if (i < 0) {
i = backup.cover.length - 1;
}
if (newFreshSpace) {
imgElement.setAttribute('src', `//${backup.cover[i].value}@672w_378h_1c.avif`);
} else {
avifSource.setAttribute('srcset', `//${backup.cover[i].value}@320w_200h_1c_!web-space-favlist-video.avif`);
webpSource.setAttribute('srcset', `//${backup.cover[i].value}@320w_200h_1c_!web-space-favlist-video.webp`);
imgElement.setAttribute('src', `//${backup.cover[i].value}@320w_200h_1c_!web-space-favlist-video.webp`);
}
if (i !== backup.cover.length - 1) {
spanC.style.color = '#999999';
} else {
spanC.style.color = '#000000';
}
i--;
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanC);
}
if (backup.title && backup.title.length > 1) {
const spanT = document.createElement('span');
spanT.innerText = 'T';
spanT.style.marginRight = '3px';
spanT.style.float = 'right';
spanT.style.fontWeight = 'bold';
spanT.style.cursor = 'pointer';
spanT.style.color = '#000000';
let i = backup.title.length - 2;
spanT.addEventListener('click', () => {
try {
if (i < 0) {
i = backup.title.length - 1;
}
as[1].textContent = backup.title[i].value;
if (newFreshSpace) {
divTitleNewFreshSpace.setAttribute('title', backup.title[i].value);
} else {
as[1].setAttribute('title', backup.title[i].value);
}
if (i !== backup.title.length - 1) {
spanT.style.color = '#999999';
} else {
spanT.style.color = '#000000';
}
i--;
} catch (error) {
catchUnknownError(error);
}
});
divTCABJX.appendChild(spanT);
}
// if (mutiOther) {
// const spanO = document.createElement('span');
// spanO.innerText = 'O';
// spanO.style.marginRight = '3px';
// spanO.style.float = 'right';
// spanO.style.fontWeight = 'bold';
// spanO.style.cursor = 'pointer';
// spanO.style.color = mutiOther === 1 ? '#000000' : '#ff0000';
// spanO.addEventListener('click', () => {
// try {
// const data = GM_getValue(BV, {});
// // const json = JSON.stringify(data, null, 8);
// const json = JSON.stringify(data);
// // GM_openInTab('data:text/plain;charset=utf-8,' + encodeURIComponent(json), { active: true, insert: false, setParent: true });
// GM_openInTab('data:application/json;charset=utf-8,' + encodeURIComponent(json), { active: true, insert: false, setParent: true });
// } catch (error) {
// catchUnknownError(error);
// }
// });
// divTCABJX.appendChild(spanO);
// }
if (controller.signal.aborted) {
// throw Error();
throw new DOMException('', 'AbortError');
}
if (!newFreshSpace) {
const ul = video.querySelector('ul.be-dropdown-menu');
addDropdown(ul, AV, BV);
}
if (functions.length === 1) {
await delay(300);
}
} catch (error) {
// if (controller.signal.aborted) {
if (error.name === 'AbortError') {
throw error;
} else {
// addMessage('-----------------------------');
addMessage(getLocalizedText('UNKNOWN_ERROR'));
// addMessage(`fid: ${fid} pn: ${pn} index: ${index + 1}`, true);
// addMessage(`${getLocalizedText('POSITION_ON_THIS_PAGE' + displayPrompt)}: ${index + 1}`, true);
addMessageAVBVTitle(AV, BV, title);
// addMessage(error.message, true);
addMessage(error.stack, true);
// console.error(`fid: ${fid} pn: ${pn} index: ${index + 1}`);
console.error(`index: ${index + 1}`);
consoleAVBVTitle('error', AV, BV, title);
console.error(error);
if (as[1]) {
as[1].style.color = '#ff0000';
}
}
}
}
if (autoNextPage) {
await clickNextPage();
}
} catch (error) {
// if (!controller.signal.aborted) {
if (error.name !== 'AbortError') {
catchUnknownError(error);
}
} finally {
processing = false;
activeControllers.delete(controller);
}
}
function formatTimeFavorite1(t) {
let e = Math.floor(+new Date / 1e3) - t;
let n = (new Date).getFullYear();
let i = new Date(1e3 * t).getFullYear();
let r = new Date(1e3 * t).getMonth() + 1;
let o = new Date(1e3 * t).getDate();
return e < 60 ? "刚刚"
: e >= 60 && e < 3600 ? Math.floor(e / 60) + "分钟前"
: e >= 3600 && e < 86400 ? Math.floor(e / 60 / 60) + "小时前"
: 86400 === e ? "昨天"
: e > 86400 && i === n ? r + "-" + o
: i < n ? i + "-" + r + "-" + o
: void 0;
}
function formatTimeFavorite2(t) {
let e = new Date();
let n = e.getTime();
let r = t.getTime();
let o = n - r;
return o < 6e4 ? "刚刚"
: o < 36e5 ? Math.floor(o / 6e4) + "分钟前"
: o < 864e5 ? Math.floor(o / 36e5) + "小时前"
: r >= new Date(e.getFullYear(), e.getMonth(), e.getDate() - 1).getTime() ? "昨天"
: r >= new Date(e.getFullYear(), 0, 1).getTime() ? (t.getMonth() + 1) + "-" + t.getDate()
// : o < 63072e6 ? t.getFullYear() + "-" + (t.getMonth() + 1) + "-" + t.getDate()
// : "2年前";
: t.getFullYear() + "-" + (t.getMonth() + 1) + "-" + t.getDate();
}
function formatTimeFavorite3(t) {
const date = new Date(t * 1000);
const year = String(date.getFullYear()).slice(2);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// function decodeHTMLEntities(str) {
// return str.replace(/&[a-zA-Z]+;/g, match => {
// const textarea = document.createElement('textarea');
// textarea.innerHTML = match;
// return textarea.value;
// });
// }
function decodeHTMLEntities(str) {
return new DOMParser().parseFromString(`<!doctype html><body>${str}`, 'text/html').body.textContent;
}
function addMessage(msg, smallFontSize) {
let px;
if (smallFontSize) {
px = newFreshSpace ? 11 : 10;
} else {
px = newFreshSpace ? 13 : 12;
}
const p = document.createElement('p');
p.innerHTML = msg;
p.style.fontSize = `${px}px`;
divMessage.appendChild(p);
p.scrollIntoView({ behavior: 'instant', block: 'nearest' });
}
function clearMessage() {
while (divMessage.firstChild) {
divMessage.removeChild(divMessage.firstChild);
}
}
function addControls() {
const newFreshSpaceAppend = newFreshSpace ? '-newFreshSpace' : '';
let displayUpdate = false;
if (settings.version !== currentVersion) {
if (settings.version) {
displayUpdate = true;
}
settings.version = currentVersion;
GM_setValue('settings', settings);
}
const usageCount = settings[newFreshSpace ? 'usageCountNewFreshSpace' : 'usageCount'];
displayPrompt = usageCount < 10 ? '_WITH_PROMPT' : '';
if (displayPrompt) {
settings[newFreshSpace ? 'usageCountNewFreshSpace' : 'usageCount']++;
GM_setValue('settings', settings);
}
const style = document.createElement('style');
style.textContent = `
.fix-div {
padding: 2px;
}
.fix-div-newFreshSpace {
padding: 2px 0;
}
.fix-divControls {
border-top: 1px solid #e4e9f0;
}
.fix-labelA, .fix-labelA-newFreshSpace {
line-height: 1;
}
.fix-divMessage {
line-height: 1.5;
}
`;
document.head.appendChild(style);
const divSide = document.querySelector(newFreshSpace ? 'div.favlist-aside' : 'div.fav-sidenav');
if (!newFreshSpace && divSide.querySelector('a.watch-later')) {
divSide.querySelector('a.watch-later').style.borderBottom = '1px solid #eeeeee';
}
const divControls = document.createElement('div');
divControls.classList.add('fix-div' + newFreshSpaceAppend);
if (!newFreshSpace) {
divControls.classList.add('fix-divControls');
}
divSide.appendChild(divControls);
const divLabelA = document.createElement('div');
divLabelA.classList.add('fix-div' + newFreshSpaceAppend);
divControls.appendChild(divLabelA);
const labelA = document.createElement('label');
labelA.classList.add('fix-labelA' + newFreshSpaceAppend);
labelA.innerText = getLocalizedText('ONLY_PROCESS_DISABLED');
divLabelA.appendChild(labelA);
const checkboxA = document.createElement('input');
checkboxA.type = 'checkbox';
checkboxA.checked = settings.onlyProcessDisabled;
checkboxA.addEventListener('change', () => {
try {
settings.onlyProcessDisabled = checkboxA.checked;
GM_setValue('settings', settings);
} catch (error) {
catchUnknownError(error);
}
});
labelA.insertAdjacentElement('afterbegin', checkboxA);
const divLabelB = document.createElement('div');
divLabelB.classList.add('fix-div' + newFreshSpaceAppend);
divControls.appendChild(divLabelB);
const labelB = document.createElement('label');
labelB.classList.add('fix-labelA' + newFreshSpaceAppend);
labelB.innerText = getLocalizedText('AUTO_NEXT_PAGE');
divLabelB.appendChild(labelB);
const checkboxB = document.createElement('input');
checkboxB.type = 'checkbox';
checkboxB.checked = autoNextPage;
checkboxB.addEventListener('change', () => {
try {
autoNextPage = checkboxB.checked;
if (autoNextPage && !processing) {
clickNextPage();
}
} catch (error) {
catchUnknownError(error);
}
});
labelB.insertAdjacentElement('afterbegin', checkboxB);
const divLabelC = document.createElement('div');
divLabelC.classList.add('fix-div' + newFreshSpaceAppend);
divControls.appendChild(divLabelC);
const labelC = document.createElement('label');
labelC.classList.add('fix-labelA' + newFreshSpaceAppend);
labelC.innerText = getLocalizedText('ENABLE_DEBUG');
divLabelC.appendChild(labelC);
const checkboxC = document.createElement('input');
checkboxC.type = 'checkbox';
checkboxC.checked = settings.enableDebug;
checkboxC.addEventListener('change', () => {
try {
settings.enableDebug = checkboxC.checked;
GM_setValue('settings', settings);
} catch (error) {
catchUnknownError(error);
}
});
labelC.insertAdjacentElement('afterbegin', checkboxC);
divMessage = document.createElement('div');
divMessage.classList.add('fix-div' + newFreshSpaceAppend);
divMessage.classList.add('fix-divMessage');
divControls.appendChild(divMessage);
if (displayUpdate) {
setTimeout(() => {
addMessage(getLocalizedText('UPDATES'));
}, 300);
}
}
function addDropdown(dropdownContainer, AV, BV) {
if (settings.enableDebug) console.warn('========addDropdown========');
try {
if (newFreshSpace) {
const biliCardDropdownVisible = document.querySelectorAll('.bili-card-dropdown--visible');
if (biliCardDropdownVisible.length !== 1) {
// addMessage('-----------------------------');
addMessage(getLocalizedText('MULTIPLE_DROPDOWN_FOUND_ERROR'));
return;
}
let divTargetVideo;
try {
divTargetVideo = document.querySelector('div.items__item:has(.bili-card-dropdown--visible)');
} catch {
const items = document.querySelectorAll('div.items__item');
for (const item of items) {
if (item.contains(biliCardDropdownVisible[0])) {
divTargetVideo = item;
break;
}
}
}
if (!divTargetVideo) {
// addMessage('-----------------------------');
addMessage(getLocalizedText('TARGET_VIDEO_NOT_FOUND_ERROR'));
return;
}
if (settings.onlyProcessDisabled && divTargetVideo.querySelector('.bili-cover-card__stats')) {
return;
}
BV = biliCardDropdownVisible[0].parentNode.querySelector('a').getAttribute('href').match(BVFromURLRegex)[1];
AV = AVBVs.find(AVBV => AVBV.bvid === BV).id;
} else {
if (dropdownContainer.lastElementChild.classList.contains('backup')) {
return;
}
}
if (!newFreshSpace) {
dropdownContainer.lastElementChild.classList.add('be-dropdown-item-delimiter');
}
const backup = GM_getValue(BV, {});
if (backup.cover) {
const dropdownCover = document.createElement(newFreshSpace ? 'div' : 'li');
dropdownCover.classList.add(newFreshSpace ? 'bili-card-dropdown-popper__item' : 'be-dropdown-item');
if (!newFreshSpace) {
dropdownCover.classList.add('backup');
}
dropdownCover.textContent = getLocalizedText('DROPDOWN_COVER');
dropdownCover.addEventListener('click', () => {
try {
if (newFreshSpace) {
dropdownContainer.classList.remove('visible');
}
GM_openInTab(`https://${backup.cover[backup.cover.length - 1].value}`, { active: true, insert: true, setParent: true });
for (let i = backup.cover.length - 2; i >= 0; i--) {
GM_openInTab(`https://${backup.cover[i].value}`, { insert: false, setParent: true });
}
} catch (error) {
catchUnknownError(error);
}
});
dropdownContainer.appendChild(dropdownCover);
}
const dropdownLocal = document.createElement('div');
dropdownLocal.classList.add(newFreshSpace ? 'bili-card-dropdown-popper__item' : 'be-dropdown-item');
if (!newFreshSpace) {
dropdownLocal.classList.add('backup');
}
dropdownLocal.textContent = getLocalizedText('DROPDOWN_LOCAL');
dropdownLocal.addEventListener('click', () => {
try {
if (newFreshSpace) {
dropdownContainer.classList.remove('visible');
}
const data = GM_getValue(BV, {});
// const json = JSON.stringify(data, null, 8);
const json = JSON.stringify(data);
// GM_openInTab('data:text/plain;charset=utf-8,' + encodeURIComponent(json), { active: true, insert: false, setParent: true });
GM_openInTab('data:application/json;charset=utf-8,' + encodeURIComponent(json), { active: true, insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
dropdownContainer.appendChild(dropdownLocal);
const dropdownJump = document.createElement('div');
dropdownJump.classList.add(newFreshSpace ? 'bili-card-dropdown-popper__item' : 'be-dropdown-item');
if (!newFreshSpace) {
dropdownJump.classList.add('backup');
}
dropdownJump.textContent = getLocalizedText('DROPDOWN_JUMP');
dropdownJump.addEventListener('click', () => {
try {
if (newFreshSpace) {
dropdownContainer.classList.remove('visible');
}
GM_openInTab(`https://www.biliplus.com/video/${BV}`, { active: true, insert: false, setParent: true });
GM_openInTab(`https://www.biliplus.com/video/av${AV}`, { insert: false, setParent: true });
GM_openInTab(`https://www.jijidown.com/video/${BV}`, { insert: false, setParent: true });
GM_openInTab(`https://xbeibeix.com/video/${BV}`, { insert: false, setParent: true });
} catch (error) {
catchUnknownError(error);
}
});
dropdownContainer.appendChild(dropdownJump);
const dropdownReset = document.createElement('div');
dropdownReset.classList.add(newFreshSpace ? 'bili-card-dropdown-popper__item' : 'be-dropdown-item');
if (!newFreshSpace) {
dropdownReset.classList.add('backup');
}
dropdownReset.textContent = getLocalizedText('DROPDOWN_RESET');
dropdownReset.addEventListener('click', () => {
try {
if (newFreshSpace) {
dropdownContainer.classList.remove('visible');
}
GM_deleteValue(BV);
} catch (error) {
catchUnknownError(error);
}
});
dropdownContainer.appendChild(dropdownReset);
} catch (error) {
catchUnknownError(error);
}
}
async function clickNextPage() {
if (newFreshSpace) {
const pager = Array.from(document.querySelectorAll('button.vui_pagenation--btn-side')).find(b => b.innerText === '下一页');
if (pager && !pager.classList.contains('vui_button--disabled')) {
await delay(5000);
if (autoNextPage) {
pager.click();
}
}
} else {
const pager = document.querySelector('li.be-pager-next');
if (pager && !pager.classList.contains('be-pager-disabled')) {
await delay(5000);
if (autoNextPage) {
pager.click();
}
}
}
}
function updateStoreArray(_backup, _key, _value, _ts = 0, _from) {
if (!_backup[_key]) {
_backup[_key] = [];
const data = { value: _value, ts: _ts, from: _from };
if (settings.enableDebug) console.log(`init ${_key}`);
if (settings.enableDebug) console.log(data);
_backup[_key].push(data);
} else {
const target = _backup[_key].find(i => i.value === _value);
if (target) {
if (settings.enableDebug) console.log(`${_key} exists`);
if (target.ts === 0 && _ts) {
target.ts = _ts;
target.from = _from;
if (settings.enableDebug) console.warn(`overwrite ${_key} ts`);
}
} else {
const data = { value: _value, ts: _ts, from: _from };
if (settings.enableDebug) console.log(`new ${_key}`);
if (settings.enableDebug) console.log(data);
_backup[_key].push(data);
_backup[_key].sort((a, b) => a.ts - b.ts);
}
}
}
async function getFromApi(AV, BV, title, backup, spanA, apiDetails, fid, pn, disabled, spanFavTime) {
if (!backup.AV) {
backup.AV = AV;
}
if (!backup.BV) {
backup.BV = BV;
}
if (!apiDetails.value) {
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://api.bilibili.com/x/v3/fav/resource/list?media_id=${fid}&pn=${pn}&ps=${videosPerPage}&keyword=&order=mtime&type=0&tid=0&platform=web`,
timeout: 5000,
responseType: 'json',
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
apiDetails.value = response.response.data.medias;
}
const apiDetail = apiDetails.value.find(a => a.bvid === BV);
if (!apiDetail) {
throw Error('apiDetail not found in apidetails');
}
if (disabled) {
if (!backup.api || backup.api.value === false) {
backup.api = { value: false, ts: getCurrentTs() };
spanA.style.color = '#ff0000';
}
} else {
backup.api = { value: true, ts: getCurrentTs() };
spanA.style.color = '#00ff00';
}
if (settings.enableDebug) console.warn('getFromApi');
// if (settings.enableDebug) console.log(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('log', AV, BV, title);
if (settings.enableDebug) console.log(apiDetail);
if (!disabled) {
updateStoreArray(backup, 'title', apiDetail.title, getCurrentTs(), 'api');
updateStoreArray(backup, 'cover', apiDetail.cover.replace(httpsFromURLRegex, ''), getCurrentTs(), 'api');
}
// if (settings.alwaysGetIntroFromVideoPage) {
// const response = await new Promise((resolve, reject) => {
// GM.xmlHttpRequest({
// method: 'GET',
// url: `https://www.bilibili.com/video/${BV}`,
// timeout: 5000,
// onload: (res) => resolve(res),
// onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
// ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
// });
// });
// if (settings.enableDebug) console.log(response);
// // if (settings.enableDebug) console.warn('innerHTML');
// // if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').innerHTML);
// // if (settings.enableDebug) console.warn('innerText');
// // if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').innerText);
// // if (settings.enableDebug) console.warn('textContent');
// // if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').textContent);
// // if (settings.enableDebug) console.warn(decodeHTMLEntities(response.responseXML.querySelector('span.desc-info-text').innerHTML) === response.responseXML.querySelector('span.desc-info-text').innerText);
// // if (settings.enableDebug) console.warn(response.responseXML.querySelector('span.desc-info-text').textContent === response.responseXML.querySelector('span.desc-info-text').innerText);
// // if (settings.enableDebug) console.warn(response.responseXML.querySelector('span.desc-info-text').textContent === decodeHTMLEntities(response.responseXML.querySelector('span.desc-info-text').innerHTML));
// if (response.responseXML.querySelector('div.basic-desc-info')) {
// updateStoreArray(backup, 'intro', response.responseXML.querySelector('div.basic-desc-info').innerText, getCurrentTs(), 'videoPage');
// if (!response.responseXML.querySelector('div.basic-desc-info').innerText.includes(apiDetail.intro)) {
// // addMessage('-----------------------------');
// addMessage(getLocalizedText('UNKNOWN_ERROR'));
// // addMessage(`${getLocalizedText('POSITION_ON_THIS_PAGE' + displayPrompt)}: ${index + 1}`, true);
// addMessageAVBVTitle(AV, BV, title);
// addMessage('intro from video page conflicts with apiDetail', true);
// addMessage('getFromApi', true);
// // console.error(`index: ${index + 1}`);
// consoleAVBVTitle('error', AV, BV, title);
// console.error('intro from video page conflicts with apiDetail');
// console.error('getFromApi');
// updateStoreArray(backup, 'intro', apiDetail.intro, getCurrentTs(), 'api');
// }
// } else {
// updateStoreArray(backup, 'intro', apiDetail.intro, getCurrentTs(), 'api');
// }
// } else {
if (!disabled && apiDetail.intro.length >= 250) {
if (settings.enableDebug) console.log('apiDetail.intro.length >= 250');
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://www.bilibili.com/video/${BV}`,
timeout: 5000,
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
if (settings.enableDebug) console.log(response);
// if (settings.enableDebug) console.warn('innerHTML');
// if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').innerHTML);
// if (settings.enableDebug) console.warn('innerText');
// if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').innerText);
// if (settings.enableDebug) console.warn('textContent');
// if (settings.enableDebug) console.warn(response.responseXML.querySelector('div.basic-desc-info').textContent);
// if (settings.enableDebug) console.warn(decodeHTMLEntities(response.responseXML.querySelector('span.desc-info-text').innerHTML) === response.responseXML.querySelector('span.desc-info-text').innerText);
// if (settings.enableDebug) console.warn(response.responseXML.querySelector('span.desc-info-text').textContent === response.responseXML.querySelector('span.desc-info-text').innerText);
// if (settings.enableDebug) console.warn(response.responseXML.querySelector('span.desc-info-text').textContent === decodeHTMLEntities(response.responseXML.querySelector('span.desc-info-text').innerHTML));
if (response.responseXML.querySelector('div.basic-desc-info')) {
updateStoreArray(backup, 'intro', response.responseXML.querySelector('div.basic-desc-info').innerText, getCurrentTs(), 'videoPage');
if (!response.responseXML.querySelector('div.basic-desc-info').innerText.includes(apiDetail.intro)) {
// // addMessage('-----------------------------');
// addMessage(getLocalizedText('UNKNOWN_ERROR'));
// // addMessage(`${getLocalizedText('POSITION_ON_THIS_PAGE' + displayPrompt)}: ${index + 1}`, true);
// addMessageAVBVTitle(AV, BV, title);
// addMessage('intro from video page conflicts with apiDetail', true);
// addMessage('getFromApi', true);
// // console.error(`index: ${index + 1}`);
// consoleAVBVTitle('error', AV, BV, title);
// console.error('intro from video page conflicts with apiDetail');
// console.error('getFromApi');
updateStoreArray(backup, 'intro', apiDetail.intro, getCurrentTs(), 'api');
}
} else {
updateStoreArray(backup, 'intro', apiDetail.intro, getCurrentTs(), 'api');
}
} else {
updateStoreArray(backup, 'intro', apiDetail.intro, getCurrentTs(), 'api');
}
// }
if (!backup.upperUid) {
backup.upperUid = apiDetail.upper.mid;
}
updateStoreArray(backup, 'upperName', apiDetail.upper.name, getCurrentTs(), 'api');
updateStoreArray(backup, 'upperAvatar', apiDetail.upper.face.replace(httpsFromURLRegex, ''), getCurrentTs(), 'api');
// if (!backup.timeUpload) {
// backup.timeUpload = apiDetail.ctime;
// }
// if (!backup.timePublish) {
// backup.timePublish = apiDetail.pubtime;
// }
updateStoreArray(backup, 'timeUpload', apiDetail.ctime, getCurrentTs(), 'api');
updateStoreArray(backup, 'timePublish', apiDetail.pubtime, getCurrentTs(), 'api');
if (!backup.timeFavorite) {
backup.timeFavorite = [];
const data = { value: apiDetail.fav_time, fid: fid };
if (settings.enableDebug) console.log('init timeFavorite');
if (settings.enableDebug) console.log(data);
backup.timeFavorite.push(data);
} else {
const target = backup.timeFavorite.find(i => i.fid === fid);
if (target) {
if (target.value !== apiDetail.fav_time) {
if (settings.enableDebug) console.warn('update timeFavorite');
target.value = apiDetail.fav_time;
}
} else {
const data = { value: apiDetail.fav_time, fid: fid };
if (settings.enableDebug) console.log('new timeFavorite');
if (settings.enableDebug) console.log(data);
backup.timeFavorite.push(data);
backup.timeFavorite.sort((a, b) => a.value - b.value);
}
}
spanFavTime.innerText = `收藏于:${formatTimeFavorite2(new Date(apiDetail.fav_time * 1000))}`;
if (settings.enableDebug) console.warn('GM_setValue Api');
// if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(backup);
GM_setValue(BV, backup);
}
async function getFromBiliplus(AV, BV, title, backup, spanB) {
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://www.biliplus.com/video/av${AV}`,
timeout: 5000,
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
const json = JSON.parse(response.response.match(jsonFromBiliplusRegex)[1]);
if (json.title) {
backup.biliplus = { value: true, ts: getCurrentTs() };
spanB.style.color = '#00ff00';
if (settings.enableDebug) console.warn('getFromBiliplus');
// if (settings.enableDebug) console.log(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('log', AV, BV, title);
if (settings.enableDebug) console.log(json);
updateStoreArray(backup, 'title', json.title, json.lastupdatets, 'biliplus');
updateStoreArray(backup, 'cover', json.pic.replace(httpsFromURLRegex, ''), json.lastupdatets, 'biliplus');
updateStoreArray(backup, 'intro', json.description, json.lastupdatets, 'biliplus');
updateStoreArray(backup, 'upperName', json.author, json.lastupdatets, 'biliplus');
updateStoreArray(backup, 'timePublish', json.created, json.lastupdatets, 'biliplus');
if (json.v2_app_api) {
updateStoreArray(backup, 'title', json.v2_app_api.title, json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'cover', json.v2_app_api.pic.replace(httpsFromURLRegex, ''), json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'intro', json.v2_app_api.desc, json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'upperName', json.v2_app_api.owner.name, json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'upperAvatar', json.v2_app_api.owner.face.replace(httpsFromURLRegex, ''), json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'timeUpload', json.v2_app_api.ctime, json.lastupdatets, 'biliplusV2');
updateStoreArray(backup, 'timePublish', json.v2_app_api.pubdate, json.lastupdatets, 'biliplusV2');
if (json.v2_app_api.first_frame) {
updateStoreArray(backup, 'firstFrame', json.v2_app_api.first_frame.replace(httpsFromURLRegex, ''), json.lastupdatets, 'biliplusV2');
}
}
} else {
backup.biliplus = { value: false, ts: getCurrentTs() };
spanB.style.color = '#ff0000';
if (settings.enableDebug) console.warn('getFromBiliplus');
// if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(json);
}
}
async function getFromJijidown(AV, BV, title, backup, spanJ) {
let retryCount = 0;
while (true) {
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://www.jijidown.com/api/v1/video_bv/get_info?id=${BV.slice(2)}`,
timeout: 5000,
responseType: 'json',
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
const json = response.response;
if (json.upid > 0) {
backup.jijidown = { value: true, ts: getCurrentTs() };
spanJ.style.color = '#00ff00';
if (settings.enableDebug) console.warn('getFromJijidown');
// if (settings.enableDebug) console.log(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('log', AV, BV, title);
if (settings.enableDebug) console.log(json);
updateStoreArray(backup, 'title', json.title, json.ltime, 'jijidown');
updateStoreArray(backup, 'cover', json.img.replace(httpsFromURLRegex, ''), json.ltime, 'jijidown');
updateStoreArray(backup, 'intro', decodeHTMLEntities(json.desc.replaceAll('<br/>', '\n')), json.ltime, 'jijidown');
if (json.up.id > 0) {
updateStoreArray(backup, 'upperName', json.up.author, json.ltime, 'jijidown');
updateStoreArray(backup, 'upperAvatar', json.up.avatar.replace(httpsFromURLRegex, ''), json.ltime, 'jijidown');
}
return;
} else if (json.msg === 'loading') {
retryCount++;
if (settings.enableDebug) console.warn('getFromJijidown');
// if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(`retryCount: ${retryCount}`);
if (settings.enableDebug) console.warn(json);
if (retryCount > 4) {
// addMessage('-----------------------------');
addMessageAVBVTitle(AV, BV, title);
addMessage('retryCount > 4', true);
addMessage('getFromJijidown', true);
// console.error(`index: ${index + 1}`);
consoleAVBVTitle('error', AV, BV, title);
console.error('retryCount > 4');
console.error('getFromJijidown');
return;
}
} else {
backup.jijidown = { value: false, ts: getCurrentTs() };
spanJ.style.color = '#ff0000';
if (settings.enableDebug) console.warn('getFromJijidown');
// if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(json);
return;
}
await delay(600);
}
}
async function getFromXbeibeix(AV, BV, title, backup, spanX) {
const response = await new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: 'GET',
url: `https://xbeibeix.com/video/${BV}`,
timeout: 5000,
onload: (res) => resolve(res),
onerror: () => reject(Error(getLocalizedText('REQUEST_FAILED_ERROR'))),
ontimeout: () => reject(Error(getLocalizedText('REQUEST_TIMEOUT_ERROR')))
});
});
if (response.finalUrl !== 'https://xbeibeix.com/') {
backup.xbeibeix = { value: true, ts: getCurrentTs() };
spanX.style.color = '#00ff00';
if (settings.enableDebug) console.warn('getFromXbeibeix');
// if (settings.enableDebug) console.log(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('log', AV, BV, title);
if (settings.enableDebug) console.log(response);
updateStoreArray(backup, 'title', response.responseXML.querySelector('h5.fw-bold').innerText, undefined, 'xbeibeix');
updateStoreArray(backup, 'cover', response.responseXML.querySelector('div.col-4 > img').getAttribute('src').replace(httpsFromURLRegex, ''), undefined, 'xbeibeix');
updateStoreArray(backup, 'intro', decodeHTMLEntities(response.responseXML.querySelector('div.col-8 > textarea').innerText), undefined, 'xbeibeix');
updateStoreArray(backup, 'upperName', response.responseXML.querySelector('div.input-group.mb-2 > input').value, undefined, 'xbeibeix');
} else {
backup.xbeibeix = { value: false, ts: getCurrentTs() };
spanX.style.color = '#ff0000';
if (settings.enableDebug) console.warn('getFromXbeibeix');
// if (settings.enableDebug) console.warn(`index: ${index + 1}`);
if (settings.enableDebug) consoleAVBVTitle('warn', AV, BV, title);
if (settings.enableDebug) console.warn(response);
}
}
function consoleAVBVTitle(type, AV, BV, title) {
switch (type) {
case 'log':
console.log(`AV: ${AV}`);
console.log(`BV: ${BV}`);
console.log(`title: ${title.slice(0, 13)}`);
break;
case 'warn':
console.warn(`AV: ${AV}`);
console.warn(`BV: ${BV}`);
console.warn(`title: ${title.slice(0, 13)}`);
break;
case 'error':
console.error(`AV: ${AV}`);
console.error(`BV: ${BV}`);
if (title) {
console.error(`title: ${title.slice(0, 13)}`);
}
break;
default:
throw Error('invalid type');
}
}
function addMessageAVBVTitle(AV, BV, title) {
addMessage(`${getLocalizedText('AV')}: ${AV}`, true);
addMessage(`${getLocalizedText('BV')}: ${BV}`, true);
if (title) {
addMessage(`${getLocalizedText('TITLE')}: ${title.slice(0, 13)}`, true);
}
}
function catchUnknownError(error) {
// addMessage('-----------------------------');
addMessage(getLocalizedText('UNKNOWN_ERROR'));
// addMessage(error.message, true);
addMessage(error.stack, true);
console.error(error);
}
// async function mainNewFreshSpace(mutations) {
async function mainNewFreshSpace() {
// mutations_count++;
// console.error('mutations_count' + mutations_count);
// for (const mutation of mutations) {
// mutation_count++;
// console.warn('mutation_count' + mutation_count);
// console.log(mutation);
// }
// if (first) {
// first = false;
// } else {
// mutations = mutations.reverse();
// }
// for (const mutation of mutations) {
// if (mutation.addedNodes.length) {
// const items = document.querySelectorAll('.items__item');
// for (const item of items) {
// console.log(mutation.addedNodes[0].querySelectorAll('a'));
// console.log(mutation.addedNodes[0].querySelectorAll('a')[1].innerText);
// mutation.addedNodes[0].querySelectorAll('a')[1].style.color = 'red';
// }
}
})();