Skip to content

Instantly share code, notes, and snippets.

@1574242600
Last active January 22, 2022 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1574242600/6093d1fec38a16355c8df17f084e55e9 to your computer and use it in GitHub Desktop.
Save 1574242600/6093d1fec38a16355c8df17f084e55e9 to your computer and use it in GitHub Desktop.
//该文件并没有被严格地测试过
(async () => {
const APIHOST = 'https://api.bilibili.com';
const uid = window.__BiliUser__.cache.data.mid;
function fetchJson(uri, init) {
init = Object.assign({}, { credentials: "include" }, init);
return fetch(uri, init)
.then((v) => v.json());
}
function getBangumiLastEpIndex(sid) {
return fetchJson(APIHOST + `/pgc/view/web/season/user/status?season_id=${ sid }`)
.then((v) => Number.isNaN(+(v.result?.progress?.last_ep_index))
? -1
: +(v.result.progress.last_ep_index)
//未观看的番剧没有 progress 属性
//有些番剧的 last_ep_index 是中文字符串,无法直接判断集数
)
}
function getSubscriptiveMediaList(uid, type, page = 1) {
return fetchJson(APIHOST + `/x/space/bangumi/follow/list?type=${ type }&pn=${ page }&ps=30&vmid=${ uid }`)
.then(v => v.data);
}
function getBGMData() {
return fetchJson('https://cdn.jsdelivr.net/npm/bangumi-data@0.3/dist/data.json', { credentials: "omit" })
}
function *range(start, end) {
for (let i = start; i < end; i++) {
yield i;
}
}
function save(blob) {
const a = document.createElement('a');
const event = new MouseEvent('click');
a.download = "progress.json";
a.href = URL.createObjectURL(blob, {type: 'application/json'});
a.dispatchEvent(event);
a.remove();
}
function getMediaIdToBGMSubjectId(BGMData) {
const map = new Map();
for (const item of BGMData.items) {
const site = item.sites;
const bili = site.find(v => v.site === 'bilibili');
const bangumi = site.find(v => v.site === 'bangumi');
if (bili && bangumi) {
map.set(+bili.id, +bangumi.id);
}
}
return (mid) => map.get(mid);
}
const mediaArr = await (async () => {
const mediaArr = [];
for (let type = 1; type < 3; type++) {
for (let i = 1; true; i++) {
const data = await getSubscriptiveMediaList(uid, type, i);
mediaArr.push(...data.list)
if (i * 30 > data.total) break;
}
}
return mediaArr;
})().then((v) => {
if (v.length < 1) throw new Error('似乎没有任何的订阅?')
console.log(`总共 ${ v.length } 条订阅, 正在处理中......`)
return v;
});
const mediaSeasonIdArr = mediaArr.map(v => v.season_id);
const mediaLastEpIndexArr = await (async (mediaSeasonIdArr) => {
const LastEpIndexes = [];
for (const sid of mediaSeasonIdArr) {
const lastEpIndex = await getBangumiLastEpIndex(sid);
LastEpIndexes.push(lastEpIndex)
}
return LastEpIndexes;
})(mediaSeasonIdArr);
const mediaStatusArr = ((mediaArr, mediaLastEpIndexArr) => {
return mediaArr.map((media, index) => {
const { is_finish, total_count } = media;
const lastEpIndex = mediaLastEpIndexArr[index];
if (lastEpIndex < 0) return 'on_hold';
if (!is_finish) return 'do';
if (lastEpIndex < total_count) return 'do'
return 'collect'
})
})(mediaArr, mediaLastEpIndexArr)
const progressData = await (async (mediaArr, mediaStatusArr, mediaLastEpIndexArr) => {
const toBGMSubjectId = getMediaIdToBGMSubjectId(await getBGMData());
const progress = [];
for (const index in mediaArr) {
const meida = mediaArr[index];
const mid = meida.media_id;
let id = toBGMSubjectId(mid);
if (!Number.isInteger(id)) {
const title = meida.title;
const tmp = +window.prompt(
`很抱歉,脚本无法从 bangumi-data 找到 《${ title }》(mid: ${mid}) 对应的 Bangumi.tv 条目 id \n\n` +
'您需要手动输入条目 id,如果您不明白该如何找到对应的 id,请直接点击确认即可,脚本会忽略该番剧。'
,'0');
if (Number.isInteger(tmp) && tmp > 0) { id = tmp } else { continue; };
}
const data = {
id,
status: mediaStatusArr[index]
};
const lastEpIndex = mediaLastEpIndexArr[index];
if (lastEpIndex > 0) data.watchedEps = [...range(1, lastEpIndex + 1)];
progress.push(data);
}
return progress
})(mediaArr, mediaStatusArr, mediaLastEpIndexArr)
console.debug(progressData);
console.log('处理完毕')
save(new Blob([JSON.stringify(progressData)]));
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment