| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- class DownloadTool {
- constructor() {
- this.form = document.getElementById('downloadForm');
- this.output = document.getElementById('output');
- this.loadUrlsBtn = document.getElementById('loadUrls');
- this.urlListTextarea = document.getElementById('urlList');
- this.downloadUrlBtn = document.getElementById('downloadUrl');
- this.cleanFilesBtn = document.getElementById('cleanFiles');
- this.downloadImageBtn = document.getElementById('downloadImage');
- this.checkIncompleteBtn = document.getElementById('checkIncomplete');
- this.clearOutputBtn = document.getElementById('clearOutput');
- this.proxySelect = document.getElementById('proxy');
-
- this.websocket = null;
- this.isConnected = false;
-
- this.initEvents();
- this.connectWebSocket();
- }
-
- initEvents() {
- // 读取URL按钮
- this.loadUrlsBtn.addEventListener('click', () => {
- this.loadTargetUrls();
- });
-
- // 下载URL按钮
- this.downloadUrlBtn.addEventListener('click', () => {
- this.downloadUrls()
- });
-
- // 下载图片按钮
- this.downloadImageBtn.addEventListener('click', () => {
- this.downloadImages()
- });
- // 检查未完成按钮
- this.checkIncompleteBtn.addEventListener('click', () => {
- this.checkIncomplete();
- });
- // 清理文件按钮
- this.cleanFilesBtn.addEventListener('click', () => {
- this.cleanFiles();
- });
-
- // 清除输出按钮
- this.clearOutputBtn.addEventListener('click', () => {
- this.clearOutput();
- });
- }
-
- connectWebSocket() {
- try {
- const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
- const wsUrl = `${protocol}//${window.location.host}/ws`;
- this.websocket = new WebSocket(wsUrl);
-
- this.websocket.onopen = () => {
- this.isConnected = true;
- this.showOutput('WebSocket连接已建立,可以接收实时日志', 'success');
- console.log('WebSocket连接已建立');
- };
-
- this.websocket.onmessage = (event) => {
- try {
- const logEntry = JSON.parse(event.data);
- this.appendRealtimeLog(logEntry);
- } catch (e) {
- console.error('解析WebSocket消息失败:', e);
- }
- };
-
- this.websocket.onclose = () => {
- this.isConnected = false;
- this.showOutput('WebSocket连接已断开,正在尝试重连...', 'error');
- console.log('WebSocket连接已断开');
- // 5秒后尝试重连
- setTimeout(() => this.connectWebSocket(), 5000);
- };
-
- this.websocket.onerror = (error) => {
- console.error('WebSocket错误:', error);
- this.showOutput('WebSocket连接错误', 'error');
- };
- } catch (error) {
- console.error('创建WebSocket连接失败:', error);
- this.showOutput('WebSocket连接失败', 'error');
- }
- }
-
- appendRealtimeLog(logEntry) {
- const timestamp = logEntry.time || new Date().toLocaleTimeString();
- const level = logEntry.level || 'INFO';
- const source = logEntry.source || 'system';
- const message = logEntry.message || '';
-
- const logLine = `[${timestamp}] [${level}] [${source}] ${message}`;
-
- // 追加到输出框
- if (this.output.textContent) {
- this.output.textContent += '\n' + logLine;
- } else {
- this.output.textContent = logLine;
- }
-
- // 自动滚动到底部
- this.output.scrollTop = this.output.scrollHeight;
-
- // 根据日志级别设置样式
- if (level === 'ERROR') {
- this.output.classList.add('error');
- } else if (level === 'SUCCESS') {
- this.output.classList.add('success');
- } else {
- this.output.classList.remove('error', 'success');
- }
- }
-
- async loadTargetUrls() {
- try {
- this.setLoading(true);
- this.showOutput('正在读取 targets.txt...', 'info');
-
- const response = await fetch('/load_urls', {
- method: 'POST'
- });
-
- const result = await response.json();
-
- if (result.success) {
- // 在URL列表文本框中显示读取的URL
- this.urlListTextarea.value = result.urls.join('\n');
- this.showOutput(`成功读取 ${result.urls.length} 个URL\n\nURL列表:\n${result.urls.join('\n')}`, 'success');
- } else {
- this.showOutput(`读取失败: ${result.message}`, 'error');
- }
- } catch (error) {
- this.showOutput(`读取URL时出错: ${error.message}`, 'error');
- } finally {
- this.setLoading(false);
- }
- }
-
- async clearOutput() {
- try {
- const response = await fetch('/clear', {
- method: 'POST'
- });
-
- const result = await response.json();
- if (result.success) {
- this.showOutput('', 'success');
- this.urlListTextarea.value = ''; // 同时清空URL列表
- }
- } catch (error) {
- this.showOutput(`清除失败: ${error.message}`, 'error');
- }
- }
-
- async downloadUrls() {
- try {
- const proxy = this.proxySelect.value;
-
- this.showOutput(`正在抓取画廊链接...\n代理: ${proxy}\n\n注意:此操作可能需要较长时间,请耐心等待...`, 'info');
-
- // 使用setTimeout确保UI不被阻塞
- setTimeout(async () => {
- try {
- const res = await fetch('/download_urls', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ proxy })
- });
- const data = await res.json();
- this.showOutput(data.message, data.success ? 'success' : 'error');
- } catch (error) {
- this.showOutput(`抓取画廊链接时出错: ${error.message}`, 'error');
- }
- }, 100);
-
- } catch (error) {
- this.showOutput(`抓取画廊链接时出错: ${error.message}`, 'error');
- }
- }
- async downloadImages() {
- try {
- const proxy = this.proxySelect.value;
-
- this.showOutput(`正在下载图片...\n代理: ${proxy}\n\n注意:此操作可能需要较长时间,请耐心等待...`, 'info');
-
- // 使用setTimeout确保UI不被阻塞
- setTimeout(async () => {
- try {
- const res = await fetch('/download_images', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ proxy })
- });
- const data = await res.json();
- this.showOutput(data.message, data.success ? 'success' : 'error');
- } catch (error) {
- this.showOutput(`下载图片时出错: ${error.message}`, 'error');
- }
- }, 100);
-
- } catch (error) {
- this.showOutput(`下载图片时出错: ${error.message}`, 'error');
- }
- }
- async checkIncomplete() {
- try {
- this.setLoading(true);
- this.showOutput('正在检查未完成文件...', 'info');
-
- const response = await fetch('/check_incomplete', {
- method: 'POST'
- });
-
- const result = await response.json();
-
- if (result.success) {
- let message = `检查完成!\n\n`;
- message += `${result.data}`;
- this.showOutput(message, 'success');
- } else {
- this.showOutput(`检查失败: ${result.message}`, 'error');
- }
- } catch (error) {
- this.showOutput(`检查未完成文件时出错: ${error.message}`, 'error');
- } finally {
- this.setLoading(false);
- }
- }
- async cleanFiles() {
- try {
- this.setLoading(true);
- this.showOutput('正在清理日志和JSON文件...', 'info');
-
- const response = await fetch('/clean_files', {
- method: 'POST'
- });
-
- const result = await response.json();
-
- if (result.success) {
- let message = `清理完成!成功删除 ${result.deleted_count} 个文件\n\n`;
- if (result.deleted_files && result.deleted_files.length > 0) {
- message += "已删除的文件:\n" + result.deleted_files.join('\n');
- }
- this.showOutput(message, 'success');
- } else {
- let message = `清理完成,但有 ${result.error_count} 个文件删除失败\n\n`;
- if (result.deleted_files && result.deleted_files.length > 0) {
- message += "已删除的文件:\n" + result.deleted_files.join('\n') + '\n\n';
- }
- if (result.error_files && result.error_files.length > 0) {
- message += "删除失败的文件:\n" + result.error_files.join('\n');
- }
- this.showOutput(message, 'error');
- }
- } catch (error) {
- this.showOutput(`清理文件时出错: ${error.message}`, 'error');
- } finally {
- this.setLoading(false);
- }
- }
- showOutput(message, type = '') {
- this.output.textContent = message;
- this.output.className = 'output-area';
- if (type) {
- this.output.classList.add(type);
- }
-
- // 自动滚动到底部
- this.output.scrollTop = this.output.scrollHeight;
- }
-
- setLoading(loading) {
- const buttons = this.form.querySelectorAll('button');
- buttons.forEach(button => {
- button.disabled = loading;
- });
-
- if (loading) {
- document.body.classList.add('loading');
- } else {
- document.body.classList.remove('loading');
- }
- }
- }
- // 初始化应用
- document.addEventListener('DOMContentLoaded', () => {
- new DownloadTool();
- });
|