// ==UserScript== // @name Zlib2WebDAV上传助手 发布版本 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 在Z-lib网站的图书详情页 上传图书至WebDAV 可从脚本设置修改WebDAV设置 // @author StreamL // @match https://zlib.by/* // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @grant GM_notification // @grant GM_registerMenuCommand // ==/UserScript== (function() { 'use strict'; // 默认配置 const defaultConfig = { webdav: { endpoint: ' ', id: ' ', password: ' ', directory: '' } }; // 获取配置 function getConfig() { const saved = GM_getValue('webdav_config'); return saved ? JSON.parse(saved) : defaultConfig; } // 保存配置 function saveConfig(config) { GM_setValue('webdav_config', JSON.stringify(config)); } // 创建浮动按钮 function createFloatingButton() { const buttonContainer = document.createElement('div'); buttonContainer.innerHTML = `
WebDAV
`; document.body.appendChild(buttonContainer); const btn = document.getElementById('webdav-btn'); // 添加悬停效果 btn.addEventListener('mouseenter', () => { btn.style.background = '#0056b3'; btn.style.transform = 'translateY(-50%) scale(1.05)'; btn.style.boxShadow = '0 6px 16px rgba(0,123,255,0.4)'; }); btn.addEventListener('mouseleave', () => { btn.style.background = '#007bff'; btn.style.transform = 'translateY(-50%) scale(1)'; btn.style.boxShadow = '0 4px 12px rgba(0,123,255,0.3)'; }); btn.addEventListener('click', handleButtonClick); } // 获取下载链接 function getDownloadLink() { const selector = 'body > div.container > div > div > div:nth-child(4) > section > div > div.book-actions-buttons > div:nth-child(4) > div > a'; const downloadBtn = document.querySelector(selector); return downloadBtn ? downloadBtn.href : null; } // 处理按钮点击 function handleButtonClick() { const downloadUrl = getDownloadLink(); if (!downloadUrl) { alert('未找到下载按钮'); return; } // 设置按钮为等待状态 setButtonLoading(true); // 显示进度提示 showNotification(`正在请求 ${downloadUrl} 的内容...`); // 发送请求获取文件 GM_xmlhttpRequest({ method: 'GET', url: downloadUrl, responseType: 'blob', onload: function(response) { setButtonLoading(false); handleDownloadResponse(response); }, onerror: function(error) { setButtonLoading(false); showNotification('下载失败: ' + error.statusText, 'error'); } }); } // 处理下载响应 function handleDownloadResponse(response) { if (response.status === 200) { // 尝试从响应头获取文件名 const contentDisposition = response.responseHeaders.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); let filename = ''; if (contentDisposition) { filename = contentDisposition[1].replace(/['"]/g, ''); } // 检查文件扩展名 const validExtensions = ['txt', 'epub', 'mobi', 'azw3', 'pdf']; const fileExt = filename.split('.').pop().toLowerCase(); if (!validExtensions.includes(fileExt)) { showNotification('无法获取有效的电子书文件', 'error'); return; } // 显示确认对话框 showConfirmDialog(filename, response.response); } else { showNotification('无法获取文件内容', 'error'); } } // 显示确认对话框 function showConfirmDialog(filename, fileBlob) { const dialog = document.createElement('div'); dialog.innerHTML = `

确认上传

文件名: ${filename}

`; document.body.appendChild(dialog); // 添加按钮悬停效果 const cancelBtn = document.getElementById('cancel-btn'); const confirmBtn = document.getElementById('confirm-btn'); cancelBtn.addEventListener('mouseenter', () => { cancelBtn.style.borderColor = '#bbb'; cancelBtn.style.color = '#333'; }); cancelBtn.addEventListener('mouseleave', () => { cancelBtn.style.borderColor = '#ddd'; cancelBtn.style.color = '#666'; }); confirmBtn.addEventListener('mouseenter', () => { confirmBtn.style.background = '#0056b3'; }); confirmBtn.addEventListener('mouseleave', () => { confirmBtn.style.background = '#007bff'; }); // 绑定事件 cancelBtn.addEventListener('click', () => { document.body.removeChild(dialog); }); confirmBtn.addEventListener('click', () => { document.body.removeChild(dialog); uploadToWebDAV(filename, fileBlob); }); } // 上传到WebDAV function uploadToWebDAV(filename, fileBlob) { const config = getConfig(); const webdav = config.webdav; const uploadUrl = webdav.endpoint + webdav.directory + filename; // 设置按钮为等待状态 setButtonLoading(true); showNotification('正在上传文件...'); GM_xmlhttpRequest({ method: 'PUT', url: uploadUrl, data: fileBlob, headers: { 'Authorization': 'Basic ' + btoa(webdav.id + ':' + webdav.password) }, onload: function(response) { setButtonLoading(false); if (response.status >= 200 && response.status < 300) { showNotification('文件已成功上传到WebDAV', 'success'); } else { showNotification('上传失败: ' + response.statusText, 'error'); } }, onerror: function(error) { setButtonLoading(false); showNotification('上传错误: ' + error.statusText, 'error'); } }); } // 显示通知 function showNotification(message, type = 'info') { const notification = document.createElement('div'); const bgColor = type === 'success' ? '#28a745' : type === 'error' ? '#dc3545' : '#007bff'; notification.innerHTML = `
${message}
`; document.body.appendChild(notification); // 3秒后自动移除 setTimeout(() => { if (notification.parentNode) { document.body.removeChild(notification); } }, 3000); } // 显示设置对话框 function showSettingsDialog() { const config = getConfig(); const dialog = document.createElement('div'); dialog.innerHTML = `

WebDAV设置

目录路径应以 / 结尾,留空则为根目录
`; document.body.appendChild(dialog); // 添加输入框焦点效果 const inputs = dialog.querySelectorAll('input, textarea'); inputs.forEach(input => { input.addEventListener('focus', () => { input.style.borderColor = '#007bff'; input.style.boxShadow = '0 0 0 3px rgba(0,123,255,0.1)'; }); input.addEventListener('blur', () => { input.style.borderColor = '#e1e5e9'; input.style.boxShadow = 'none'; }); }); // 绑定事件 document.getElementById('cancel-settings-btn').addEventListener('click', () => { document.body.removeChild(dialog); }); document.getElementById('save-settings-btn').addEventListener('click', () => { saveSettings(dialog); }); document.getElementById('reset-settings-btn').addEventListener('click', () => { if (confirm('确定要重置所有设置到默认值吗?')) { resetSettings(dialog); } }); } // 保存设置 function saveSettings(dialog) { const endpoint = document.getElementById('endpoint-input').value.trim(); const username = document.getElementById('username-input').value.trim(); const password = document.getElementById('password-input').value; let directory = document.getElementById('directory-input').value.trim(); // 确保目录路径以 / 结尾(如果不为空) if (directory && !directory.endsWith('/')) { directory += '/'; } if (!endpoint || !username || !password) { showNotification('请填写完整的WebDAV配置', 'error'); return; } const newConfig = { webdav: { endpoint: endpoint, id: username, password: password, directory: directory } }; saveConfig(newConfig); showNotification('设置已保存', 'success'); document.body.removeChild(dialog); } // 重置设置 function resetSettings(dialog) { document.getElementById('endpoint-input').value = defaultConfig.webdav.endpoint; document.getElementById('username-input').value = defaultConfig.webdav.id; document.getElementById('password-input').value = defaultConfig.webdav.password; document.getElementById('directory-input').value = defaultConfig.webdav.directory; showNotification('设置已重置为默认值', 'info'); } // 测试WebDAV连接 function testWebDAVConnection() { const endpoint = document.getElementById('endpoint-input').value.trim(); const username = document.getElementById('username-input').value.trim(); const password = document.getElementById('password-input').value; if (!endpoint || !username || !password) { showNotification('请先填写完整的WebDAV配置', 'error'); return; } showNotification('正在测试连接...', 'info'); GM_xmlhttpRequest({ method: 'PROPFIND', url: endpoint, headers: { 'Authorization': 'Basic ' + btoa(username + ':' + password), 'Depth': '0' }, onload: function(response) { if (response.status >= 200 && response.status < 300) { showNotification('连接测试成功!', 'success'); } else { showNotification(`连接失败: ${response.status} ${response.statusText}`, 'error'); } }, onerror: function(error) { showNotification('连接测试失败: ' + error.statusText, 'error'); } }); } // 设置按钮加载状态 function setButtonLoading(isLoading) { const btn = document.getElementById('webdav-btn'); if (!btn) return; if (isLoading) { btn.innerHTML = '处理中...'; btn.style.background = '#6c757d'; btn.style.cursor = 'not-allowed'; btn.style.opacity = '0.7'; btn.disabled = true; // 移除悬停效果 btn.onmouseenter = null; btn.onmouseleave = null; } else { btn.innerHTML = 'WebDAV'; btn.style.background = '#007bff'; btn.style.cursor = 'pointer'; btn.style.opacity = '1'; btn.disabled = false; // 重新添加悬停效果 btn.addEventListener('mouseenter', () => { if (!btn.disabled) { btn.style.background = '#0056b3'; btn.style.transform = 'translateY(-50%) scale(1.05)'; btn.style.boxShadow = '0 6px 16px rgba(0,123,255,0.4)'; } }); btn.addEventListener('mouseleave', () => { if (!btn.disabled) { btn.style.background = '#007bff'; btn.style.transform = 'translateY(-50%) scale(1)'; btn.style.boxShadow = '0 4px 12px rgba(0,123,255,0.3)'; } }); } } // 初始化 function init() { createFloatingButton(); // 注册脚本菜单命令 GM_registerMenuCommand('WebDAV配置', showSettingsDialog); } // 页面加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();