adds status and server time indicators. fixes checkboxes
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from flask import Flask
|
||||
from flask_bootstrap import Bootstrap5
|
||||
from datetime import datetime
|
||||
@@ -12,6 +13,8 @@ from app.logging_config import init_logger
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
|
||||
os.environ['TZ'] = 'UTC'
|
||||
|
||||
config = load_config()
|
||||
|
||||
app.config['SECRET_KEY'] = config['DEFAULT']['SECRET_KEY']
|
||||
|
||||
@@ -1,6 +1,75 @@
|
||||
class Common {
|
||||
constructor() {
|
||||
this.activityIndicator = document.getElementById('activity_indicator');
|
||||
this.endTimeElement = document.getElementById('end_time');
|
||||
this.serverTimeElement = document.getElementById('server_time');
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.updateServerTime();
|
||||
setInterval(() => this.updateServerTime(), 60000); // Update every minute
|
||||
this.checkScrapingStatus();
|
||||
}
|
||||
|
||||
async fetchEndTime() {
|
||||
try {
|
||||
const response = await fetch('/scraping_get_end_time');
|
||||
const data = await response.json();
|
||||
if (data.end_time) {
|
||||
const endTime = new Date(data.end_time);
|
||||
const localEndTime = endTime.toLocaleString();
|
||||
this.endTimeElement.textContent = `End Time: ${endTime} TCT`;
|
||||
}
|
||||
} catch (error) {
|
||||
this.endTimeElement.textContent = 'Error fetching end time';
|
||||
console.error('Error fetching end time:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async updateServerTime() {
|
||||
try {
|
||||
const response = await fetch('/server_time');
|
||||
const data = await response.json();
|
||||
this.serverTimeElement.textContent = `Server Time (UTC): ${data.server_time}`;
|
||||
} catch (error) {
|
||||
console.error('Error fetching server time:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async checkScrapingStatus() {
|
||||
try {
|
||||
const response = await fetch('/scraping_status');
|
||||
const data = await response.json();
|
||||
if (data.scraping_active) {
|
||||
this.activityIndicator.classList.remove('text-bg-danger');
|
||||
this.activityIndicator.classList.add('text-bg-success');
|
||||
this.activityIndicator.textContent = 'Active';
|
||||
|
||||
this.endTimeElement.classList.remove('d-none');
|
||||
this.endTimeElement.textContent = data.end_time;
|
||||
await this.fetchEndTime();
|
||||
} else {
|
||||
this.activityIndicator.classList.remove('text-bg-success');
|
||||
this.activityIndicator.classList.add('text-bg-danger');
|
||||
this.activityIndicator.textContent = 'Inactive';
|
||||
|
||||
this.endTimeElement.textContent = '';
|
||||
this.endTimeElement.classList.add('d-none');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking scraping status:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new Common();
|
||||
});
|
||||
|
||||
function checkAllCheckboxes(tableId, checkAllCheckboxId) {
|
||||
const table = document.getElementById(tableId);
|
||||
const checkboxes = table.querySelectorAll('input[type="checkbox"]');
|
||||
const checkboxes = table.querySelectorAll('input[type="checkbox"]:not(:disabled)');
|
||||
const checkAllCheckbox = document.getElementById(checkAllCheckboxId);
|
||||
|
||||
checkboxes.forEach(checkbox => checkbox.checked = checkAllCheckbox.checked);
|
||||
|
||||
@@ -9,52 +9,26 @@ class ScraperApp {
|
||||
}
|
||||
|
||||
init() {
|
||||
this.checkScrapingStatus();
|
||||
this.checkScrapingStatusIndex();
|
||||
this.addEventListeners();
|
||||
}
|
||||
|
||||
async checkScrapingStatus() {
|
||||
async checkScrapingStatusIndex() {
|
||||
try {
|
||||
const response = await fetch('/scraping_status');
|
||||
const data = await response.json();
|
||||
if (data.scraping_active) {
|
||||
this.startButton.disabled = true;
|
||||
this.stopButton.disabled = false;
|
||||
this.activityIndicator.classList.remove('text-bg-danger');
|
||||
this.activityIndicator.classList.add('text-bg-success');
|
||||
this.activityIndicator.textContent = 'Active';
|
||||
|
||||
this.endTimeElement.classList.remove('d-none');
|
||||
this.endTimeElement.textContent = data.end_time;
|
||||
await this.fetchEndTime();
|
||||
} else {
|
||||
this.startButton.disabled = false;
|
||||
this.stopButton.disabled = true;
|
||||
this.activityIndicator.classList.remove('text-bg-success');
|
||||
this.activityIndicator.classList.add('text-bg-danger');
|
||||
this.activityIndicator.textContent = 'Inactive';
|
||||
|
||||
this.endTimeElement.textContent = '';
|
||||
this.endTimeElement.classList.add('d-none');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking scraping status:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async fetchEndTime() {
|
||||
try {
|
||||
const response = await fetch('/scraping_get_end_time');
|
||||
const data = await response.json();
|
||||
if (data.end_time) {
|
||||
this.endTimeElement.textContent = `Track until: ${data.end_time}`;
|
||||
}
|
||||
} catch (error) {
|
||||
this.endTimeElement.textContent = 'Error fetching end time';
|
||||
console.error('Error fetching end time:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async startScraping(event) {
|
||||
event.preventDefault(); // Prevent the default form submission
|
||||
const formData = new FormData(this.form);
|
||||
@@ -65,7 +39,7 @@ class ScraperApp {
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.status === "Scraping started") {
|
||||
this.checkScrapingStatus();
|
||||
this.checkScrapingStatusIndex();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error starting scraping:', error);
|
||||
@@ -79,7 +53,7 @@ class ScraperApp {
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data.status === "Scraping stopped") {
|
||||
this.checkScrapingStatus();
|
||||
this.checkScrapingStatusIndex();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error stopping scraping:', error);
|
||||
@@ -93,4 +67,6 @@ class ScraperApp {
|
||||
}
|
||||
|
||||
// Initialize the application when DOM is fully loaded
|
||||
document.addEventListener('DOMContentLoaded', () => new ScraperApp());
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
new ScraperApp();
|
||||
});
|
||||
@@ -1,4 +1,3 @@
|
||||
<!-- app/templates/includes/navigation.html -->
|
||||
<nav class="navbar navbar-nav navbar-expand-md bg-primary">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">Torn User Activity Scraper</a>
|
||||
@@ -14,4 +13,11 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</nav>
|
||||
<div id="status_container" class="container-fluid d-flex justify-content-center">
|
||||
<div class="d-flex m-2" id="navbarNav">
|
||||
<div id="activity_indicator" class="badge text-bg-danger fw-bold m-1">Inactive</div>
|
||||
<div id="server_time" class="badge text-bg-secondary m-1"></div>
|
||||
<div id="end_time" class="badge text-bg-info d-none m-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -7,8 +7,6 @@
|
||||
<h2>Scraper</h2>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<span id="end_time" class="badge text-bg-info d-none"></span>
|
||||
<span id="activity_indicator" class="badge text-bg-danger fw-bold">Inactive</span>
|
||||
</div>
|
||||
</div>
|
||||
<form id="scrapingForm" method="POST" action="{{ url_for('start_scraping') }}">
|
||||
|
||||
@@ -9,6 +9,8 @@ from app.api import scraper as scraper
|
||||
|
||||
from app.analysis import load_data, load_analysis_modules
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
views_bp = Blueprint("views", __name__)
|
||||
|
||||
def register_views(app):
|
||||
@@ -115,4 +117,10 @@ def register_views(app):
|
||||
context["results"] = results
|
||||
|
||||
return render_template("analyze.html", **context)
|
||||
|
||||
@views_bp.route('/server_time')
|
||||
def server_time():
|
||||
current_time = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
|
||||
return {'server_time': current_time}
|
||||
|
||||
app.register_blueprint(views_bp)
|
||||
|
||||
Reference in New Issue
Block a user