Import Export Data

Import and export data using localForage in Tampermonkey script

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Import Export Data
// @namespace    https://github.com/Adachi-Git
// @version      1.01
// @description  Import and export data using localForage in Tampermonkey script
// @author       Adachi
// @match        https://u2.dmhy.org/offers.php
// @match        https://u2.dmhy.org/torrents.php*
// @include      /^https?://(bangumi\.tv|bgm\.tv|chii\.in)/.*
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 设置并发操作的上限
    const MAX_CONCURRENT_OPERATIONS = 5;

    // 创建导入按钮
    const importButton = document.createElement('input');
    importButton.type = 'file';
    importButton.style.position = 'fixed';
    importButton.style.top = '10px';
    importButton.style.left = '10px';
    document.body.appendChild(importButton);

    // 创建导出按钮
    const exportButton = document.createElement('button');
    exportButton.textContent = 'Export Data';
    exportButton.style.position = 'fixed';
    exportButton.style.top = '40px';
    exportButton.style.left = '10px';
    document.body.appendChild(exportButton);

    // 点击导入按钮时触发事件
    importButton.addEventListener('change', async function(event) {
        const file = event.target.files[0];
        if (!file) return;

        try {
            const data = await readFile(file);
            await importDataConcurrently(data);
            alert('Data imported successfully!');
        } catch (error) {
            console.error('Error importing data:', error);
            alert('Error importing data. See console for details.');
        }
    });

    // 点击导出按钮时触发事件
    exportButton.addEventListener('click', async function() {
        try {
            const data = await exportData();
            downloadData(data);
        } catch (error) {
            console.error('Error exporting data:', error);
            alert('Error exporting data. See console for details.');
        }
    });

    // 读取文件并返回数据
    function readFile(file) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = () => resolve(reader.result);
            reader.onerror = error => reject(error);
            reader.readAsText(file);
        });
    }

    // 并发导入数据到 IndexedDB
    async function importDataConcurrently(data) {
        const jsonData = JSON.parse(data);
        const keys = Object.keys(jsonData);

        // 切割任务,以 MAX_CONCURRENT_OPERATIONS 为一组进行并发操作
        const chunks = [];
        for (let i = 0; i < keys.length; i += MAX_CONCURRENT_OPERATIONS) {
            chunks.push(keys.slice(i, i + MAX_CONCURRENT_OPERATIONS));
        }

        // 对每个组进行并发操作
        for (const chunk of chunks) {
            await Promise.all(chunk.map(async (key) => {
                await localforage.setItem(key, jsonData[key]);
            }));
        }
    }

    // 导出数据
    async function exportData() {
        const keys = await localforage.keys();
        const data = {};
        for (const key of keys) {
            data[key] = await localforage.getItem(key);
        }
        return JSON.stringify(data, null, 2);
    }

    // 下载数据为 JSON 文件
    function downloadData(data) {
        const blob = new Blob([data], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = 'indexedDB_data.json';
        link.click();
    }
})();