Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,4 +1,95 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import os, re, json, sqlite3, logging
|
| 3 |
|
| 4 |
app = Flask(__name__)
|
|
@@ -463,6 +554,7 @@ body{margin:0;font-family:Nunito,sans-serif;background:#f6f8fb;}
|
|
| 463 |
.form-group{margin-bottom:15px;}
|
| 464 |
.form-group label{display:block;margin-bottom:5px;font-weight:600;}
|
| 465 |
.form-control{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;}
|
|
|
|
| 466 |
.btn{padding:8px 15px;border:none;border-radius:4px;cursor:pointer;font-weight:600;}
|
| 467 |
.btn-primary{background:#4a6dd8;color:white;}
|
| 468 |
.btn-danger{background:#e53e3e;color:white;}
|
|
@@ -727,11 +819,23 @@ function loadManage() {
|
|
| 727 |
<div class="manage-panel">
|
| 728 |
<h2>Add New URL</h2>
|
| 729 |
<div class="form-group">
|
| 730 |
-
<label for="new-url">URL</label>
|
| 731 |
<input type="text" id="new-url" class="form-control" placeholder="https://example.com">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 732 |
</div>
|
| 733 |
-
<button onclick="addUrl()" class="btn btn-primary">Add URL</button>
|
| 734 |
<div id="add-status" class="status"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 735 |
|
| 736 |
<h2>Manage Saved URLs</h2>
|
| 737 |
<div id="url-list" class="url-list">Loading...</div>
|
|
|
|
| 1 |
+
function addBatchUrls() {
|
| 2 |
+
const textarea = document.getElementById('batch-urls');
|
| 3 |
+
const text = textarea.value.trim();
|
| 4 |
+
|
| 5 |
+
if (!text) {
|
| 6 |
+
showStatus('add-status', 'Please enter at least one URL', false);
|
| 7 |
+
return;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
// Split by newlines and filter out empty lines
|
| 11 |
+
let urls = text.split(/\r?\n/).filter(url => url.trim() !== '');
|
| 12 |
+
|
| 13 |
+
// Limit to 100 URLs
|
| 14 |
+
if (urls.length > 100) {
|
| 15 |
+
showStatus('add-status', 'Too many URLs. Limited to 100 at once.', false);
|
| 16 |
+
urls = urls.slice(0, 100);
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
if (urls.length === 0) {
|
| 20 |
+
showStatus('add-status', 'No valid URLs found', false);
|
| 21 |
+
return;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
// Show progress bar
|
| 25 |
+
const progressBar = document.getElementById('progress-bar');
|
| 26 |
+
const progressFill = document.getElementById('progress-fill');
|
| 27 |
+
const progressText = document.getElementById('progress-text');
|
| 28 |
+
progressBar.style.display = 'block';
|
| 29 |
+
progressFill.style.width = '0%';
|
| 30 |
+
progressText.textContent = '0%';
|
| 31 |
+
|
| 32 |
+
// Add URLs one by one
|
| 33 |
+
let processed = 0;
|
| 34 |
+
let succeeded = 0;
|
| 35 |
+
|
| 36 |
+
function updateProgress() {
|
| 37 |
+
const percentage = Math.round((processed / urls.length) * 100);
|
| 38 |
+
progressFill.style.width = percentage + '%';
|
| 39 |
+
progressText.textContent = `${processed}/${urls.length} (${percentage}%)`;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
function addNextUrl(index) {
|
| 43 |
+
if (index >= urls.length) {
|
| 44 |
+
// All done
|
| 45 |
+
setTimeout(() => {
|
| 46 |
+
progressBar.style.display = 'none';
|
| 47 |
+
textarea.value = '';
|
| 48 |
+
showStatus('add-status', `Added ${succeeded} of ${urls.length} URLs successfully`, true);
|
| 49 |
+
|
| 50 |
+
// Reload URL list and favorites
|
| 51 |
+
loadUrlList();
|
| 52 |
+
if (active === 'Favorites') {
|
| 53 |
+
loadFavorites(currentPage);
|
| 54 |
+
}
|
| 55 |
+
}, 500);
|
| 56 |
+
return;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
const url = urls[index].trim();
|
| 60 |
+
if (!url) {
|
| 61 |
+
// Skip empty URLs
|
| 62 |
+
processed++;
|
| 63 |
+
updateProgress();
|
| 64 |
+
addNextUrl(index + 1);
|
| 65 |
+
return;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
const formData = new FormData();
|
| 69 |
+
formData.append('url', url);
|
| 70 |
+
|
| 71 |
+
makeRequest('/api/url/add', 'POST', formData, function(data) {
|
| 72 |
+
processed++;
|
| 73 |
+
|
| 74 |
+
if (data.success) {
|
| 75 |
+
succeeded++;
|
| 76 |
+
|
| 77 |
+
// Update localStorage
|
| 78 |
+
const localUrls = loadFromLocalStorage() || [];
|
| 79 |
+
if (!localUrls.includes(url)) {
|
| 80 |
+
localUrls.unshift(url);
|
| 81 |
+
saveToLocalStorage(localUrls);
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
updateProgress();
|
| 86 |
+
addNextUrl(index + 1);
|
| 87 |
+
});
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
// Start adding URLs
|
| 91 |
+
addNextUrl(0);
|
| 92 |
+
}from flask import Flask, render_template, request, jsonify
|
| 93 |
import os, re, json, sqlite3, logging
|
| 94 |
|
| 95 |
app = Flask(__name__)
|
|
|
|
| 554 |
.form-group{margin-bottom:15px;}
|
| 555 |
.form-group label{display:block;margin-bottom:5px;font-weight:600;}
|
| 556 |
.form-control{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px;box-sizing:border-box;}
|
| 557 |
+
textarea.form-control{min-height:100px;font-family:monospace;resize:vertical;}
|
| 558 |
.btn{padding:8px 15px;border:none;border-radius:4px;cursor:pointer;font-weight:600;}
|
| 559 |
.btn-primary{background:#4a6dd8;color:white;}
|
| 560 |
.btn-danger{background:#e53e3e;color:white;}
|
|
|
|
| 819 |
<div class="manage-panel">
|
| 820 |
<h2>Add New URL</h2>
|
| 821 |
<div class="form-group">
|
| 822 |
+
<label for="new-url">Single URL</label>
|
| 823 |
<input type="text" id="new-url" class="form-control" placeholder="https://example.com">
|
| 824 |
+
<button onclick="addUrl()" class="btn btn-primary" style="margin-top:10px">Add URL</button>
|
| 825 |
+
</div>
|
| 826 |
+
|
| 827 |
+
<div class="form-group" style="margin-top:20px">
|
| 828 |
+
<label for="batch-urls">Multiple URLs (up to 100 URLs, one per line)</label>
|
| 829 |
+
<textarea id="batch-urls" class="form-control" rows="8" placeholder="https://example1.com https://example2.com https://example3.com"></textarea>
|
| 830 |
+
<button onclick="addBatchUrls()" class="btn btn-primary" style="margin-top:10px">Add All URLs</button>
|
| 831 |
</div>
|
|
|
|
| 832 |
<div id="add-status" class="status"></div>
|
| 833 |
+
<div id="progress-bar" style="display:none; margin:15px 0;">
|
| 834 |
+
<div style="height:20px; background-color:#f0f0f0; border-radius:4px; overflow:hidden;">
|
| 835 |
+
<div id="progress-fill" style="height:100%; width:0%; background-color:#4a6dd8; transition:width 0.3s;"></div>
|
| 836 |
+
</div>
|
| 837 |
+
<div id="progress-text" style="text-align:center; margin-top:5px; font-size:14px;">0%</div>
|
| 838 |
+
</div>
|
| 839 |
|
| 840 |
<h2>Manage Saved URLs</h2>
|
| 841 |
<div id="url-list" class="url-list">Loading...</div>
|