AutoDL 弹性部署显示 JupyterLab 链接

AutoDL 弹性部署,容器列表,每个链接后面添加 JupyterLab 链接。

// ==UserScript==
// @name         AutoDL 弹性部署显示 JupyterLab 链接
// @namespace    http://tampermonkey.net/
// @version      2025-03-19
// @description  AutoDL 弹性部署,容器列表,每个链接后面添加 JupyterLab 链接。
// @author       Ganlv
// @match        https://www.autodl.com/login*
// @match        https://www.autodl.com/subAccountLogin*
// @match        https://www.autodl.com/deploy*
// @match        https://www.autodl.com/console*
// @icon         https://www.autodl.com/favicon.png
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

    (async () => {
        while (true) {
            const matches = location.href.match(/\/deploy\/details\/([A-Za-z0-9]+?)\//);
            if (matches) {
                const deployment_uuid = matches[1];
                if (Array.from(document.querySelectorAll('tr.el-table__row > td:nth-child(7) .icon-fuzhi')).some(el => !el.parentElement.parentElement.querySelector('.jupyter-link'))) {
                    const isSubUser = Boolean(JSON.parse(localStorage.getItem('user'))?.sub_name)
                    const res = await fetch(isSubUser ? '/api/v1/sub_user/deployment/container/list': '/api/v1/deployment/container/list', {
                        method: 'POST',
                        headers: {
                            'Authorization': localStorage.getItem('token'),
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            deployment_uuid,
                            page_index: 1,
                            page_size: 100,
                        }),
                    }).then(res => res.json());
                    const serviceUrlMap = res.data.list.reduce((acc, v) => ({ ...acc, [v.uuid]: v.info.service_url }), {});
                    const jupyterUrlMap = res.data.list.reduce((acc, v) => ({ ...acc, [v.uuid]: `${v.info.service_url.replace('https://u', 'https://a')}/jupyter?token=${v.info.jupyter_token}` }), {});
                    console.log(jupyterUrlMap);
                    document.querySelectorAll('.service-link').forEach(el => el.remove());
                    document.querySelectorAll('.jupyter-link').forEach(el => el.remove());
                    document.querySelectorAll('tr.el-table__row').forEach(el => {
                        const uuid = el.querySelector('td:nth-child(1) > div.cell > div > div:nth-child(2)').textContent;
                        if (serviceUrlMap[uuid]) {
                            const a = document.createElement('a');
                            a.href = serviceUrlMap[uuid];
                            a.target = '_blank';
                            a.className = 'service-link';
                            a.textContent = '↗️';
                            a.style = 'margin-left: 8px; text-decoration: none';
                            el.querySelector('td:nth-child(7) .icon-fuzhi').parentElement.appendChild(a);
                        }
                        if (jupyterUrlMap[uuid]) {
                            const a = document.createElement('a');
                            a.href = jupyterUrlMap[uuid];
                            a.target = '_blank';
                            a.className = 'jupyter-link';
                            a.innerHTML = 'JupyterLab';
                            el.querySelector('td:nth-child(7) .icon-fuzhi').parentElement.parentElement.appendChild(a);
                        }
                    });
                }
            }
            await sleep(1000);
        }
    })();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址