Greasy Fork

Greasy Fork is available in English.

阿里云盘批量重命名

对某个剧集里面的内容进行批量重命名

当前为 2023-09-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         阿里云盘批量重命名
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  对某个剧集里面的内容进行批量重命名
// @author       You
// @match        https://www.aliyundrive.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=aliyundrive.com
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js
// @grant        GM_addStyle
// @license		 GPL
// ==/UserScript==

(function (open) {
    'use strict';

    let obj = {};
    let list = [];
    let sortedOriginalArray = [];
    let nextMarker = '';
    let parent_file_id = '';
    let token = '';
    let loading = false;
    let fileName = '';
    XMLHttpRequest.prototype.open = function () {
        this.addEventListener(
            'readystatechange',
            function () {
                if (this.readyState == 4 && this.status == 200) {
                    // 列表
                    if (this.responseURL.indexOf('adrive/v3/file/list') > -1) {
                        let { items, next_marker } = JSON.parse(this.response);
                        nextMarker = next_marker;
                        token = this._header_.Authorization;
                        let i = 0;
                        let len = items.length;
                        for (; i < len; i++) {
                            const item = items[i];
                            parent_file_id = item.parent_file_id;
                            obj[item.file_id] = item;
                        }
                        list = Object.values(obj);
                        list = list.filter(
                            item => item.parent_file_id == parent_file_id
                        );
                    }
                    // 文件夹
                    if (
                        this.responseURL.indexOf('adrive/v1/file/get_path') > -1
                    ) {
                        let { items } = JSON.parse(this.response);
                        if (items.length) {
                            let { parent_file_id, name } = items[0];
                            if (parent_file_id !== 'root') {
                                fileName = name;
                            }
                        }
                    }
                }
            },
            false
        );
        open.apply(this, arguments);
    };

    function initRenameBox() {
        $('#rename-box').css({
            top: 0
        });
        $('#rename-wrap').css({
            top: 0
        });
        $('.box-modal').css({
            top: 0
        });
        let indexHtml = '';
        let contentHtml = '';
        list = list.sort(compareEpisodes);
        list = list.map((item, index) => {
            return {
                ...item,
                sortId: index
            };
        });
        sortedOriginalArray = list;
        for (let i = 0; i < list.length; i++) {
            const item = list[i];
            indexHtml +=
                `
                <span>
                ` +
                (i + 1) +
                `</span>
            `;
            contentHtml +=
                `
                <div class="item">
                ` +
                item.name +
                `
                </div>
            `;
        }
        let html =
            `
            <div class="index-wrap">
            ` +
            indexHtml +
            `
            </div>
            <div class="list-wrap">
            ` +
            contentHtml +
            `
            </div>
        `;
        $('.sort-wrap').html(html);
        $('.list-wrap').sortable({
            // 可选参数:如果需要在拖拽结束后执行一些操作,可以使用 stop 回调函数
            update: function (event, ui) {
                $(this)
                    .children('.item')
                    .each(function () {
                        const originalIndex = $(this).data('original-index');
                        sortedOriginalArray.push(list[originalIndex]);
                    });
            }
        });
        $('.list-wrap .item').each(function (index) {
            $(this).data('original-index', index);
        });
        $('.list-wrap').disableSelection();

        $('#cancelSort').click(() => {
            $('#rename-box').remove();
        });
        $('#confirmSort').click(() => {
            $('.confirm-modal').css({
                top: 0
            });
            $('#input-wrap').css({
                top: 0
            });
            // 默认赋值文件夹名称
            if (fileName) {
                $('#prefix').val(fileName);
            }
        });
        $('#cancelRename').click(() => {
            if (loading) {
                return;
            }
            $('.confirm-modal').css({
                top: '-9999px'
            });
            $('#input-wrap').css({
                top: '-9999px'
            });
        });
        $('#confirmRename').click(async () => {
            if (loading) {
                return;
            }
            loading = true;
            let index = $('#indexNumber').val();
            // 用户设定序号
            if (index && index != 0) {
                if (!/^[0-9]*$/.test(index)) {
                    alert('序号格式不正确');
                    loading = false;
                    return;
                } else {
                    reNameFun(parseInt(index));
                }
            } else {
                reNameFun(1);
            }
        });
    }
    async function reNameFun(index) {
        $('#confirmRename').text('重命名中,请不要关闭或刷新页面');
        $('#confirmRename').css({
            color: '#999',
            background: '#ccc',
            cursor: 'not-allowed'
        });
        let prefix = $('#prefix').val();
        let suffix = $('#suffix').val();
        let k = 0;
        const len = sortedOriginalArray.length;
        for (let i = 0; i < len; i++) {
            const item = sortedOriginalArray[i];
            let name = `${prefix}${(index + i)
                .toString()
                .padStart(2, '0')}${suffix}.${item.file_extension}`;
            let body = `{"drive_id":"${item.drive_id}","file_id":"${item.file_id}","name":"${name}","check_name_mode":"refuse"}`;
            const res = await rename(body);
            if (res) {
                k++;
            }
        }
        if (k == len) {
            alert('重命名完成');
        } else {
            alert(`有 ${len - k} 个重命名失败`);
        }
        window.location.reload();
    }
    function compareEpisodes(a, b) {
        const nameA = a.name;
        const nameB = b.name;
        return nameA.localeCompare(nameB, undefined, {
            numeric: true,
            sensitivity: 'base'
        });
    }
    function init() {
        let css = ` 
            .batchRename {
                border-radius: 20px;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                padding: 8px 16px;
                background: #637dff;
                font-size: 12px;
                font-weight: 500;
                line-height: 14px;
                color: #fff;
                cursor: pointer;
                flex: 1;
            }
            .batchRename.cancel {
                background: #dedede;
                color: #999;
            }
            #rename-box {
                width: 70vw;
                height: 80vh;
                left: 0;
                top: -9999px;
                bottom: 0;
                right: 0;
                margin: auto;
                position: fixed;
            }
            #rename-box .box-modal {
                position: fixed;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.4);
                left: 0;
                top: -9999px;
            }
            #rename-box .confirm-modal {
                position: fixed;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.4);
                left: 0;
                top: -9999px;
            }
            #rename-box .btn-wrap {
                display: flex;
                margin-top: 20px;
            }
            #rename-box .btn-wrap span + span {
                margin-left: 20px;
            }
            #rename-box #rename-wrap {
                position: absolute;
                background: #fff;
                padding: 20px;
                left: 0;
                top: 0;
                width: 100%;
                box-shadow: 0 0 5px #dedede;
                height: 100%;
                border-radius: 10px;
                display: flex;
                flex-direction: column;
                box-sizing: border-box;
            }
            #rename-box #rename-wrap p {
                padding-bottom: 20px;
                font-size: 14px;
            }
            #rename-box #rename-wrap p span {
                color: red;
            }
            #rename-box #rename-wrap .sort-wrap {
                padding-right: 16px;
                flex: 1;
                overflow-y: scroll;
                display: flex;
                line-height: 30px;
            }
            #rename-box #rename-wrap .sort-wrap .index-wrap {
                display: flex;
                flex-direction: column;
                margin-right: 10px;
            }
            #rename-box #rename-wrap .sort-wrap .index-wrap span {
                width: 30px;
                height: 30px;
                font-size: 13px;
            }
            #rename-box #rename-wrap .sort-wrap .list-wrap {
                flex: 1;
            }
            #rename-box #rename-wrap .sort-wrap .list-wrap .item {
                height: 30px;
                cursor: pointer;
                user-select: none;
                margin: 0;
                font-size: 13px;
                border-bottom: 1px dashed #999;
            }
            #rename-box #rename-wrap > .batchRename {
                margin-top: 20px;
                margin-left: 0;
            }
            #rename-box #input-wrap {
                position: absolute;
                background: #fff;
                padding: 20px;
                z-index: 10;
                left: 0;
                top: -9999px;
                bottom: 0;
                right: 0;
                margin: auto;
                width: 60%;
                height: 50%;
                border-radius: 10px;
                display: flex;
                flex-direction: column;
                justify-content: space-between;
                font-size: 13px;
                color: #666;
            }
            #rename-box #input-wrap .name-wrap {
                display: flex;
                align-items: center;
                justify-content: space-between;
            }
            #rename-box #input-wrap .name-wrap #indexNumber {
                width: 60px;
                text-align: center;
                margin: 0 10px;
            }
            #rename-box #input-wrap .name-wrap .prefix {
                height: 40px;
                margin: 0;
                padding: 0;
                outline: none;
                border: 0;
                border-bottom: 1px solid #dedede;
                flex: 1;
            }
            #rename-box #input-wrap .tip {
                margin-top: 20px;
            }
            #batchBtn {
                position: fixed;
                bottom: 120px;
                right: 48px;
                font-size: 14px;
                background: #637dff;
                border-radius: 100px;
                display: -ms-flexbox;
                display: flex;
                -ms-flex-align: center;
                align-items: center;
                -ms-flex-pack: center;
                justify-content: center;
                color: #fff;
                cursor: pointer;
                -webkit-transition: all 0.3s ease;
                -o-transition: all 0.3s ease;
                transition: all 0.3s ease;
                -webkit-box-shadow: 0px 3px 8px 0px rgba(28, 28, 32, 0.12), 0px 3px 5px 0px rgba(28, 28, 32, 0.04);
                box-shadow: 0px 3px 8px 0px rgba(28, 28, 32, 0.12), 0px 3px 5px 0px rgba(28, 28, 32, 0.04);
            }
            `;
        let box = `
            <div id="rename-box">
                <div class="box-modal"></div>
                <div id="rename-wrap">
                    <p>
                        文件已自动排序,如顺序不对,请手动拖动排序,然后点击确定
                        <span>(请务必确保排序正确!!)</span>
                    </p>
                    <div class="sort-wrap">
                        <div class="index-wrap"></div>
                        <div class="list-wrap"></div>
                    </div>
                    <div class="btn-wrap">
                        <span id="cancelSort" class="batchRename cancel">取消</span>
                        <span id="confirmSort" class="batchRename">确定</span>
                    </div>
                </div>
                <div class="confirm-modal"></div>
                <div id="input-wrap">
                    <div>
                        <div class="name-wrap">
                            <input id="prefix" class="prefix" type="text" placeholder="前缀" />
                            <input id="indexNumber" class="prefix" type="text" placeholder="序号" />
                            <input id="suffix" class="prefix" type="text" placeholder="后缀" />
                        </div>
                        <div class="tip">
                            <p>序号不填默认从 01 开始,也可以自定义</p>
                            <p>前缀、后缀都可不填</p>
                            <p>例:琅琊榜第 + 01 + 集 => 琅琊榜第01集.mp4</p>
                        </div>
                    </div>
                    <div class="btn-wrap">
                        <span id="cancelRename" class="batchRename cancel">取消</span>
                        <span id="confirmRename" class="batchRename">确定</span>
                    </div>
                </div>
            </div>
            `;
        let btn = "<span id='batchBtn' class='batchRename'>批量重命名</span>";
        GM_addStyle(css);
        $('body').append(btn);
        $('#batchBtn').click(() => {
            if (nextMarker) {
                alert('当前目录还有未加载完的文件,请滚动页面加载');
            } else {
                $('body').append(box);
            }
            initRenameBox();
        });
    }

    init();

    async function rename(body) {
        try {
            const res = await fetch(
                'https://api.aliyundrive.com/v3/file/update',
                {
                    headers: {
                        accept: 'application/json, text/plain, */*',
                        'accept-language': 'zh-CN,zh;q=0.9',
                        authorization: token,
                        'cache-control': 'no-cache',
                        'content-type': 'application/json',
                        pragma: 'no-cache',
                        'sec-ch-ua':
                            '"Not/A)Brand";v="99", "Google Chrome";v="115", "Chromium";v="115"',
                        'sec-ch-ua-mobile': '?0',
                        'sec-ch-ua-platform': '"macOS"',
                        'sec-fetch-dest': 'empty',
                        'sec-fetch-mode': 'cors',
                        'sec-fetch-site': 'same-site',
                        'x-canary': 'client=web,app=adrive,version=v4.9.0',
                        'x-device-id': 'a4c5a51d-2fd5-4919-abdd-1d15e3fbdbbd',
                        'x-signature':
                            '30ef6ffed7e9513dfe692c9064fe1fdf7ca97941d11ab610b1dff75476ef811c6e9b746c658eb38e146bbfee148005d2ddf1c771ca485dd0ee72e3c1a03e4e3c01',
                        Referer: 'https://www.aliyundrive.com/',
                        'Referrer-Policy': 'origin'
                    },
                    body,
                    method: 'POST'
                }
            );
            return Promise.resolve(res.ok);
        } catch (error) {
            return Promise.resolve(false);
        }
    }
})(XMLHttpRequest.prototype.open);