Greasy Fork

Greasy Fork is available in English.

哔哩哔哩(B站|Bilibili)收藏夹Fix

修复 哔哩哔哩(B站|Bilibili) 失效的收藏。(可查看av号、标题、封面)

当前为 2019-05-20 提交的版本,查看 最新版本

// ==UserScript==
// @name         哔哩哔哩(B站|Bilibili)收藏夹Fix
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  修复 哔哩哔哩(B站|Bilibili) 失效的收藏。(可查看av号、标题、封面)
// @author       Mr.Po
// @match        https://space.bilibili.com/*
// @require      http://code.jquery.com/jquery-1.11.0.min.js
// @connect      biliplus.com
// @grant        GM_xmlhttpRequest
// ==/UserScript==

// 是否启用调试模式
var isDebug = false;

// 重试延迟[秒]
var retryDelay = 5;

// 失效收藏标题颜色(默认为灰色)
var invalTitleColor = "#999";

// 收藏夹地址正则
var favlistRegex = /https:\/\/space\.bilibili\.com\/\d+\/favlist.*/;

(function() {
    'use strict';

    var space = 2000;

    setInterval(updateFav, space);
})();

// 修改收藏
function updateFav() {

    var flag = favlistRegex.test(window.location.href);

    //console.log(flag);

    if (flag) {

        var $lis = $("ul.fav-video-list.content li.small-item.disabled");

        if ($lis.size() > 0) {

            console.info($lis.size() + "个收藏待修复...");

            $lis.each(function(i, it) {

                var aid = $(it).attr("data-aid");
                var $as = $(it).find("a");

                $as.attr("href", "https://www.biliplus.com/video/av" + aid + "/");
                $as.attr("target", "_blank");

                fixTitleAndPic($(it), $($as[1]), aid);

                $(it).removeClass("disabled");
                $as.removeClass("disabled");
            });

            showDetail($lis);
        }
    }
}

// 标记失效
function signInval($it, $a) {

    // 收藏时间
    var $pubdate = $it.find("div.meta.pubdate");
    $pubdate.attr("style", "text-decoration:line-through");

    $a.attr("style", "text-decoration:line-through;color:"+invalTitleColor+";");
}

// 绑定重新加载
function bindReload($a, fun) {

    $a.text("->手动加载<-");

    $a.click(function() {

        $(this).unbind("click");

        $a.text("Loading...");

        fun();
    });
}

// 再次尝试加载
function retryLoad($a, aid, retry, fun) {

    console.warn("查询:av" + aid + ",请求过快!");

    if (retry) { // 手动重试

        $a.text("请求过快,请稍后[" + retryDelay + "]s再试!");

        setTimeout(bindReload, retryDelay * 1000,$a, fun);

        countdown($a, retryDelay);

    } else { // 首次

        $a.attr("href", "javascript:void(0);");

        bindReload($a, fun);
    }
}

// 加载倒计时
function countdown($a, second) {

    if ($a.text().indexOf("请求过快") === 0) {

        $a.text("请求过快,请稍后[" + second + "]s再试!");

        if (second > 1) {
            setTimeout(countdown, 1000,$a, second - 1);
        }
    }
}

// 修复成功
function fixSuccess($it, $a, aid, title, pic, history) {

    // 设置标题
    $a.text(title);
    $a.attr("title", $a.text());

    var $as = $it.find("a");
    $as.attr("href", "https://www.biliplus.com/" + history + "video/av" + aid + "/");

    signInval($it,$a);

    isLoad(pic, function() {
        var $img = $it.find("img");
        $img.attr("src", pic);
    });
}

// 修复标题和海报
function fixTitleAndPic($it, $a, aid) {

    if (isDebug) {
        console.log("fixTitleAndPic");
    }

    $a.text("Loading...");

    fixTitleAndPicEnhance3($it, $a, aid);
}

// 修复标题和海报 增强 - 0
function fixTitleAndPicEnhance0($it, $a, aid, retry) {

    if (isDebug) {
        console.log("fixTitleAndPicEnhance0");
    }

    GM_xmlhttpRequest({
        method: 'GET',
        url: "https://www.biliplus.com/api/view?id=" + aid,
        responseType: "json",
        onload: function(response) {

            var res = response.response;

            if (isDebug) {
                console.log("0---->:");
                console.log(res);
            }

            // 找到了
            if (res.title) {

                fixSuccess($it, $a, aid, res.title, res.pic, "");

            } else if (res.code == -503) { // 请求过快

                retryLoad($a, aid, retry, function() {
                    fixTitleAndPicEnhance0($it, $a, aid, true);
                });

            } else { // 未找到

                fixTitleAndPicEnhance1($it, $a, aid);
            }
        },
        onerror: function(e) {
            console.log("出错啦");
            console.log(e);
        }
    });
}

// 修复标题和海报 增强 - 1
function fixTitleAndPicEnhance1($it, $a, aid) {

    if (isDebug) {
        console.log("fixTitleAndPicEnhance1");
    }

    GM_xmlhttpRequest({
        method: 'GET',
        url: "https://www.biliplus.com/all/video/av" + aid + "/",
        onload: function(response) {

            //console.log("1---->:"+response.responseText);

            var params = response.responseText.match(/getjson\('(\/api\/view_all.+)'/);

            fixTitleAndPicEnhance2($it, $a, aid, params[1]);
        }
    });
}

// 修复标题和海报 增强 - 2
function fixTitleAndPicEnhance2($it, $a, aid, param, retry) {

    if (isDebug) {
        console.log("fixTitleAndPicEnhance2");
    }

    GM_xmlhttpRequest({
        method: 'GET',
        url: "https://www.biliplus.com" + param,
        responseType: "json",
        onload: function(response) {

            var res = response.response;

            if (isDebug) {
                console.log("2---->:");
                console.log(res);
            }

            // 找到了
            if (res.code === 0) {

                fixSuccess($it, $a, aid, res.data.info.title, res.data.info.pic, "all/");

            } else if (res.code == -503) { // 请求过快

                retryLoad($a, aid, retry, function() {
                    fixTitleAndPicEnhance2($it, $a, aid, param, true);
                });

            } else { // 未找到

                $a.text("已失效(" + aid + ")");
                $a.attr("title", $a.text());
            }
        }
    });
}

// 修复标题和海报 增强 - 3
function fixTitleAndPicEnhance3($it, $a, aid) {

    if (isDebug) {
        console.log("fixTitleAndPicEnhance3");
    }

    var jsonRegex;

    GM_xmlhttpRequest({
        method: 'GET',
        url: "https://www.biliplus.com/video/av" + aid + "/",
        onload: function(response) {

            try {

                if (isDebug) {
                    console.log("3---->:" + response.responseText);
                }

                jsonRegex = response.responseText.match(/window\.addEventListener\('DOMContentLoaded',function\(\){view\((.+)\);}\);/);

                if (isDebug) {
                    console.log(jsonRegex);
                }

                var jsonStr = jsonRegex[1];

                if (isDebug) {
                    console.log(jsonStr);
                }

                var res = $.parseJSON(jsonStr);

                if (res.title) { // 存在

                    fixSuccess($it, $a, aid, res.title, res.pic, "");

                } else if (res.code == -503) { // 请求过快

                    retryLoad($a, aid, null, function() {
                        fixTitleAndPicEnhance0($it, $a, aid, true);
                    });

                } else { // 不存在

                    fixTitleAndPicEnhance1($it, $a, aid);
                }

            } catch (err) {

                console.error(err);
                console.log(jsonRegex);

                // 当出现错误时,出现手动加载
                retryLoad($a, aid, null, function() {
                    fixTitleAndPicEnhance0($it, $a, aid, true);
                });
            }
        }
    });
}

// 判断一个url是否可以访问
function isLoad(url, fun) {
    $.ajax({
        url: url,
        type: 'GET',
        success: function(response) {
            fun();
        },
        error: function(e) {}
    });
}

// 显示详细
function showDetail($lis) {

    var fidRegex = window.location.href.match(/fid=(\d+)/);

    var fid;

    if (fidRegex) {
        fid = fidRegex[1];
    } else {
        fid = $("div.fav-item.cur").attr("fid");
    }

    var pn = $("ul.be-pager li.be-pager-item.be-pager-item-active").text();

    $.ajax({
        url: "https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=" + fid + "&pn=" + pn + "&ps=20&keyword=&order=mtime&type=0&tid=0&jsonp=jsonp",
        success: function(json) {

            var $medias = json.data.medias;

            $lis.each(function(i, it) {

                var aid = $(it).attr("data-aid");

                var $mediaF = $medias.filter(function(it) {
                    if (it.id == aid) {
                        return it;
                    }
                });

                var $media = $mediaF[0];

                var $a = $(it).find("a");

                var titles = "";

                if ($media.pages) {

                    var $titlesM = $media.pages.map(function(it, i, arry) {
                        return it.title;
                    });

                    titles = $titlesM.join("、");
                }

                var content = "av:" + aid + "\nP数:" + $media.page + "\n子P:" + titles + "\n简介:" + $media.intro;

                $($a[0]).attr("title", content);
            });
        }
    });
}