// ==UserScript== // @name NGA优化摸鱼体验-WebDAV配置同步 // @namespace https://github.com/kisshang1993/NGA-BBS-Script/tree/master/plugins/WebDAVDataSync // @version 1.0.0 // @author HLD // @description 使用WebDAV对配置进行同步,提供上传/下载配置功能 // @license MIT // @match *://bbs.nga.cn/* // @match *://ngabbs.com/* // @match *://nga.178.com/* // @match *://g.nga.cn/* // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-start // @inject-into content // @downloadURL https://update.greasyfork.icu/scripts/480026/NGA%E4%BC%98%E5%8C%96%E6%91%B8%E9%B1%BC%E4%BD%93%E9%AA%8C-WebDAV%E9%85%8D%E7%BD%AE%E5%90%8C%E6%AD%A5.user.js // @updateURL https://update.greasyfork.icu/scripts/480026/NGA%E4%BC%98%E5%8C%96%E6%91%B8%E9%B1%BC%E4%BD%93%E9%AA%8C-WebDAV%E9%85%8D%E7%BD%AE%E5%90%8C%E6%AD%A5.meta.js // ==/UserScript== (function (registerPlugin) { 'use strict'; const WebDAVDataSync = { name: 'WebDAVDataSync', title: 'WebDAV配置同步', desc: '使用WebDAV对配置进行同步,提供上传/下载配置功能', settings: [{ key: 'url', title: 'WebDAV地址', default: '' }, { key: 'username', title: 'WebDAV账号', default: '' }, { key: 'password', title: 'WebDAV密码', default: '' }, { key: 'backupCount', title: '保留备份数', default: 10 }], buttons: [{ title: '检查连接', action: 'testConnections' }, { title: '上传配置', action: 'upload' }, { title: '下载最新配置', action: 'downloadLatest' }, { title: '下载指定配置', action: 'downloadSelected' }], // 请求构造 request({method, path='', headers, ...config}) { // 获取输入框的当前的值 let url = this.pluginInputs['url'].val().trim() url[url.length - 1] !== '/' && (url += '/') const username = this.pluginInputs['username'].val().trim() const password = this.pluginInputs['password'].val().trim() const methodDict = { PROPFIND: 207, GET: 200, PUT: 201, DELETE: 204 } this.buttons.forEach(button => button.$el.attr('disabled', true)) return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method, url: url + path, headers: { authorization: 'Basic ' + btoa(`${username}:${password}`), ...headers }, ...config, onload: response => { this.buttons.forEach(button => button.$el.removeAttr('disabled')) if (response.status === methodDict[method]) { resolve(response) } else { this.mainScript.popMsg(`WebDAV请求失败! 状态码: ${response.status} ${response.statusText}`, 'err') } } }) }) }, // 获取文件列表 getFileList() { return new Promise((resolve, reject) => { this.request({ method: 'PROPFIND', headers: {depth: 1} }) .then(res => { let files = [] let path = res.responseText.match(/(?<=).*?(?=<\/d:href>)/gi) path.forEach(p => { const filename = p.split('/').pop() if (filename.startsWith('nga_bbs_script_data_') && filename.endsWith('.json')) { files.push(filename) } }) resolve(files) }) }) }, // 下载配置 downloadFile(name) { this.request({ method: 'GET', path: name }) .then(res => { this.mainScript.getModule('BackupModule').import(res.responseText, false) }) }, // 测试连通性 async testConnections() { await this.getFileList() this.mainScript.popMsg('连接成功!同步配置看起来没问题') }, // 上传配置 async upload() { const exportDataStr = this.mainScript.getModule('BackupModule').export('*', false) const exportDataSize = this.mainScript.getModule('BackupModule').calculateSize(exportDataStr.length) const filename = `nga_bbs_script_data_${this.getCurrentDate()}.json` await this.request({ method: 'PUT', path: filename, data: exportDataStr }) this.mainScript.popMsg(`配置文件[${filename}(${exportDataSize})]上传成功`) // 删除多余的备份 const backupCount = this.pluginInputs['backupCount'].val() || 10 if (backupCount > 0) { const files = await this.getFileList() if (files.length > backupCount) { const deleteFiles = files.sort().slice(0, files.length - backupCount) deleteFiles.forEach(file => { this.request({ method: 'DELETE', path: file }) }) this.mainScript.printLog(`${this.title}: 删除多余的备份文件[${deleteFiles.join(', ')}]`) } } }, // 导入最新配置 async downloadLatest() { const files = await this.getFileList() if (files) { this.downloadFile(files.pop()) } else { this.mainScript.popMsg('WebDAV上没有找到配置文件', 'err') } }, // 导入指定配置 async downloadSelected() { const files = await this.getFileList() if (files) { const filesNo = files.map((file, index) => `【${index}】 ${file}`) const selectedIndex = window.prompt(`请输入要下载的配置的【序号】\n${filesNo.join('\n')}`, files.length-1) if (selectedIndex && selectedIndex >= 0 && selectedIndex < files.length) { this.downloadFile(files[selectedIndex]) } else { this.mainScript.popMsg('输入的配置序号有误', 'err') } } else { this.mainScript.popMsg('WebDAV上没有找到配置文件', 'err') } }, // 获取当前时间 getCurrentDate() { const now = new Date() const year = now.getFullYear() const month = (now.getMonth() + 1).toString().padStart(2, '0') const day = now.getDate().toString().padStart(2, '0') const hours = now.getHours().toString().padStart(2, '0') const minutes = now.getMinutes().toString().padStart(2, '0') const seconds = now.getSeconds().toString().padStart(2, '0') return `${year}_${month}_${day}_${hours}_${minutes}_${seconds}` } } registerPlugin(WebDAVDataSync) })(function(plugin) { plugin.meta = GM_info.script unsafeWindow.ngaScriptPlugins = unsafeWindow.ngaScriptPlugins || [] unsafeWindow.ngaScriptPlugins.push(plugin) });