NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Download all files (one-click) from Tsinghua seafile sharing link // @description Files from Tsinghua seafile cloud sharing link may not be downloaded with one click because the file directory exceeds the limit. This script overcomes this shortcoming and realizes one-click download. // @copyright 2023, lixc21 (https://github.com/lixc21/) // @license MIT // @homepageURL https://github.com/lixc21/Seafile-Sharing-Link-Downloader // @supportURL https://github.com/lixc21/Seafile-Sharing-Link-Downloader // @contributionURL https://github.com/lixc21/Seafile-Sharing-Link-Downloader // @version 1 // @namespace https://github.com/lixc21/ // @updateURL https://openuserjs.org/meta/lixc21/My_Script.meta.js // @author lixc21 // @include https://cloud.tsinghua.edu.cn/d/* // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js // @grant none // ==/UserScript== (function () { 'use strict'; // global variables var cloudDomain = "https://cloud.tsinghua.edu.cn"; var sharingLinkID = window.shared.pageOptions.token; var filePath = []; var dirMain = window.shared.pageOptions.dirName; var dirPath = []; var zip = new JSZip(); var info = document.getElementsByClassName("shared-dir-view-main")[0]; // get file and dir list, then download all and save function getList(path) { var url = cloudDomain + "/api/v2.1/share-links/" + sharingLinkID + "/dirents/?path=" + encodeURIComponent(path); console.log('request: ' + url); var xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.open('GET', url); xmlHttpRequest.onreadystatechange = function () { if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) { var rec = JSON.parse(xmlHttpRequest.responseText)["dirent_list"]; filePath = filePath.concat(rec); console.log('request completed. length: ' + rec.length); // next file for (var index = filePath.length - 1; index >= 0; index--) { if (filePath[index]["is_dir"] == true) { var nextPath = filePath[index]["folder_path"]; dirPath = dirPath.concat(filePath[index]["folder_path"]); filePath.splice(index, 1); getList(nextPath); return; } } // list completed, then start download console.log(filePath); console.log(dirPath); for (var index = dirPath.length - 1; index >= 0; index--) { zip.folder(dirMain + dirPath[index]) infoMsg("CREATE FOLDER: " + dirMain + dirPath[index]); } if (filePath.length > 0) { var fileMeta = filePath.pop(); saveFileZip(fileMeta); } else { zip.generateAsync({ type: "blob" }) .then(function (blob) { saveAs(blob, dirMain + ".zip"); }); } } }; xmlHttpRequest.send(); } // download one file in zip function saveFileZip(fileMeta) { var xmlHttpRequest = new XMLHttpRequest(); var path = fileMeta["file_path"]; console.log(fileMeta); var url = cloudDomain + "/d/" + sharingLinkID + "/files/?p=" + encodeURIComponent(path) + "&dl=1"; xmlHttpRequest.open('GET', url); xmlHttpRequest.responseType = 'blob'; xmlHttpRequest.onload = function () { var data = xmlHttpRequest.response; zip.file(dirMain + path, data, { binary: true }); infoMsg("CREATE FILE: " + dirMain + path); // next file if (filePath.length > 0) { var fileMeta = filePath.pop(); saveFileZip(fileMeta); } else { zip.generateAsync({ type: "blob" }) .then(function (blob) { saveAs(blob, dirMain + ".zip"); }); infoMsg("DONE! DONELOAD *.ZIP FILE."); } }; xmlHttpRequest.send(); } // info function infoMsg(msg, color = "#777") { var div = document.createElement('div'); div.style = "color: " + color + "; font-size: 10px"; div.textContent = "[" + Date().toString() + "] " + msg; info.prepend(div) } // add button var button = document.createElement('button'); button.type = 'button'; button.innerHTML = 'Super Download'; button.className = 'ml-2 shared-dir-op-btn btn btn-success'; button.onclick = function () { getList(window.shared.pageOptions.relativePath); }; document.getElementsByClassName("d-flex justify-content-between align-items-center op-bar")[0] .appendChild(button); // init info var div = document.createElement('div'); div.style = "color: #FFF; font-size: 10px; font-weight:bold;"; div.textContent = "#"; info.prepend(div) var div = document.createElement('div'); div.style = "color: #00F; font-size: 10px; font-weight:bold;"; div.textContent = "NOTICE: This script temporarily stores files in memory."; info.prepend(div) var div = document.createElement('div'); div.style = "color: #00F; font-size: 10px; font-weight:bold;"; div.textContent = "Click \"Super Download\" to download all the files in this path."; info.prepend(div) var div = document.createElement('div'); div.style = "color: #FFF; font-size: 10px; font-weight:bold;"; div.textContent = "#"; info.prepend(div) })();