adds timezone config option
This commit is contained in:
parent
7fd403bd40
commit
8f064cda34
@ -2,7 +2,7 @@
|
|||||||
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify, current_app
|
from flask import Blueprint, render_template, redirect, url_for, request, flash, jsonify, current_app
|
||||||
from ..db import db
|
from ..db import db
|
||||||
# Import the new model
|
# Import the new model
|
||||||
from ..models import VolumeConfig, ScheduleConfig, ActivityLog, DownloadPathConfig, PaperMetadata
|
from ..models import VolumeConfig, ScheduleConfig, ActivityLog, DownloadPathConfig, PaperMetadata, TimezoneConfig
|
||||||
from ..defaults import MAX_VOLUME
|
from ..defaults import MAX_VOLUME
|
||||||
import os # Import os for path validation
|
import os # Import os for path validation
|
||||||
import sys
|
import sys
|
||||||
@ -129,6 +129,54 @@ def _update_download_path(new_path):
|
|||||||
return False, f"Error updating download path: {str(e)}", None
|
return False, f"Error updating download path: {str(e)}", None
|
||||||
|
|
||||||
|
|
||||||
|
def _update_timezone(new_timezone):
|
||||||
|
"""
|
||||||
|
Helper function to update timezone configuration.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
new_timezone (str): The new timezone
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (success, message, timezone_config)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Basic validation: check if it's a non-empty string
|
||||||
|
if not new_timezone or not isinstance(new_timezone, str):
|
||||||
|
return False, "Timezone cannot be empty.", None
|
||||||
|
|
||||||
|
# Validate timezone using pytz
|
||||||
|
try:
|
||||||
|
import pytz
|
||||||
|
pytz.timezone(new_timezone) # This will raise an exception if invalid
|
||||||
|
except ImportError:
|
||||||
|
# If pytz is not available, do basic validation
|
||||||
|
if '/' not in new_timezone:
|
||||||
|
return False, "Invalid timezone format. Use format like 'Europe/Berlin'.", None
|
||||||
|
except pytz.exceptions.UnknownTimeZoneError:
|
||||||
|
return False, f"Unknown timezone: {new_timezone}. Use format like 'Europe/Berlin'.", None
|
||||||
|
|
||||||
|
config = TimezoneConfig.query.first()
|
||||||
|
if not config:
|
||||||
|
config = TimezoneConfig(timezone=new_timezone)
|
||||||
|
db.session.add(config)
|
||||||
|
else:
|
||||||
|
old_value = config.timezone
|
||||||
|
config.timezone = new_timezone
|
||||||
|
ActivityLog.log_config_change(
|
||||||
|
config_key="scheduler_timezone",
|
||||||
|
old_value=old_value,
|
||||||
|
new_value=new_timezone,
|
||||||
|
description="Updated scheduler timezone"
|
||||||
|
)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
return True, "Timezone updated successfully!", config
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return False, f"Error updating timezone: {str(e)}", None
|
||||||
|
|
||||||
|
|
||||||
def _update_schedule(schedule_data):
|
def _update_schedule(schedule_data):
|
||||||
"""
|
"""
|
||||||
Helper function to update schedule configuration.
|
Helper function to update schedule configuration.
|
||||||
@ -211,11 +259,19 @@ def general():
|
|||||||
db.session.add(download_path_config)
|
db.session.add(download_path_config)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
# Fetch timezone config
|
||||||
|
timezone_config = TimezoneConfig.query.first()
|
||||||
|
if not timezone_config:
|
||||||
|
timezone_config = TimezoneConfig() # Use default from model
|
||||||
|
db.session.add(timezone_config)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"config/index.html.jinja",
|
"config/index.html.jinja",
|
||||||
active_tab="general",
|
active_tab="general",
|
||||||
volume_config=volume_config,
|
volume_config=volume_config,
|
||||||
download_path_config=download_path_config, # Pass to template
|
download_path_config=download_path_config, # Pass to template
|
||||||
|
timezone_config=timezone_config, # Pass to template
|
||||||
max_volume=MAX_VOLUME,
|
max_volume=MAX_VOLUME,
|
||||||
app_title="Configuration"
|
app_title="Configuration"
|
||||||
)
|
)
|
||||||
@ -369,9 +425,10 @@ def generate_test_papers():
|
|||||||
|
|
||||||
@bp.route("/update/general", methods=["POST"])
|
@bp.route("/update/general", methods=["POST"])
|
||||||
def update_general():
|
def update_general():
|
||||||
"""Update general configuration (Volume and Download Path)."""
|
"""Update general configuration (Volume, Download Path, and Timezone)."""
|
||||||
volume_success, volume_message = True, ""
|
volume_success, volume_message = True, ""
|
||||||
path_success, path_message = True, ""
|
path_success, path_message = True, ""
|
||||||
|
timezone_success, timezone_message = True, ""
|
||||||
|
|
||||||
# Update Volume
|
# Update Volume
|
||||||
new_volume = request.form.get("total_volume")
|
new_volume = request.form.get("total_volume")
|
||||||
@ -391,6 +448,15 @@ def update_general():
|
|||||||
else:
|
else:
|
||||||
flash(path_message, "error")
|
flash(path_message, "error")
|
||||||
|
|
||||||
|
# Update Timezone
|
||||||
|
new_timezone = request.form.get("timezone")
|
||||||
|
if new_timezone is not None:
|
||||||
|
timezone_success, timezone_message, _ = _update_timezone(new_timezone)
|
||||||
|
if timezone_success:
|
||||||
|
flash(timezone_message, "success")
|
||||||
|
else:
|
||||||
|
flash(timezone_message, "error")
|
||||||
|
|
||||||
return redirect(url_for("config.general"))
|
return redirect(url_for("config.general"))
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,6 +343,41 @@ class ScraperModuleConfig(db.Model):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
class TimezoneConfig(db.Model):
|
||||||
|
"""Model to store the configured timezone for the scheduler."""
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
timezone = db.Column(db.String(50), default="Europe/Berlin")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_current_timezone(cls):
|
||||||
|
"""Get the currently configured timezone."""
|
||||||
|
config = cls.query.first()
|
||||||
|
if not config:
|
||||||
|
config = cls(timezone="Europe/Berlin")
|
||||||
|
db.session.add(config)
|
||||||
|
db.session.commit()
|
||||||
|
return config.timezone
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_timezone(cls, timezone_name):
|
||||||
|
"""Set the timezone configuration."""
|
||||||
|
config = cls.query.first()
|
||||||
|
if not config:
|
||||||
|
config = cls(timezone=timezone_name)
|
||||||
|
db.session.add(config)
|
||||||
|
else:
|
||||||
|
old_value = config.timezone
|
||||||
|
config.timezone = timezone_name
|
||||||
|
ActivityLog.log_config_change(
|
||||||
|
config_key="scheduler_timezone",
|
||||||
|
old_value=old_value,
|
||||||
|
new_value=timezone_name,
|
||||||
|
description="Updated scheduler timezone configuration"
|
||||||
|
)
|
||||||
|
db.session.commit()
|
||||||
|
return config
|
||||||
|
|
||||||
def init_schedule_config():
|
def init_schedule_config():
|
||||||
"""Initialize ScheduleConfig with default values if empty"""
|
"""Initialize ScheduleConfig with default values if empty"""
|
||||||
if ScheduleConfig.query.count() == 0:
|
if ScheduleConfig.query.count() == 0:
|
||||||
@ -380,3 +415,9 @@ def init_schedule_config():
|
|||||||
default_path = DownloadPathConfig(path="/path/to/dummy/papers")
|
default_path = DownloadPathConfig(path="/path/to/dummy/papers")
|
||||||
db.session.add(default_path)
|
db.session.add(default_path)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
# Initialize TimezoneConfig if it doesn't exist
|
||||||
|
if TimezoneConfig.query.count() == 0:
|
||||||
|
default_timezone = TimezoneConfig(timezone="Europe/Berlin")
|
||||||
|
db.session.add(default_timezone)
|
||||||
|
db.session.commit()
|
||||||
|
@ -293,12 +293,16 @@ class ScraperScheduler:
|
|||||||
'misfire_grace_time': 30 # 30 seconds grace period for missed jobs
|
'misfire_grace_time': 30 # 30 seconds grace period for missed jobs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get timezone from database configuration
|
||||||
|
from .models import TimezoneConfig
|
||||||
|
configured_timezone = TimezoneConfig.get_current_timezone()
|
||||||
|
|
||||||
# Create the scheduler
|
# Create the scheduler
|
||||||
_scheduler = BackgroundScheduler(
|
_scheduler = BackgroundScheduler(
|
||||||
jobstores=jobstores,
|
jobstores=jobstores,
|
||||||
executors=executors,
|
executors=executors,
|
||||||
job_defaults=job_defaults,
|
job_defaults=job_defaults,
|
||||||
timezone=None # Use system timezone instead of UTC
|
timezone=configured_timezone # Use configurable timezone from database
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add event listeners
|
# Add event listeners
|
||||||
|
@ -38,6 +38,43 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-section">
|
||||||
|
<h6>Scheduler Timezone</h6>
|
||||||
|
<p class="text-muted">Configure the timezone for the APScheduler to use for job
|
||||||
|
scheduling.</p>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="timezone" class="form-label">Timezone:</label>
|
||||||
|
<select class="form-control" id="timezone" name="timezone" required>
|
||||||
|
<option value="UTC" {% if timezone_config.timezone=='UTC' %}selected{% endif %}>
|
||||||
|
UTC</option>
|
||||||
|
<option value="Europe/Berlin" {% if timezone_config.timezone=='Europe/Berlin'
|
||||||
|
%}selected{% endif %}>Europe/Berlin (CET/CEST)</option>
|
||||||
|
<option value="Europe/London" {% if timezone_config.timezone=='Europe/London'
|
||||||
|
%}selected{% endif %}>Europe/London (GMT/BST)</option>
|
||||||
|
<option value="Europe/Paris" {% if timezone_config.timezone=='Europe/Paris'
|
||||||
|
%}selected{% endif %}>Europe/Paris (CET/CEST)</option>
|
||||||
|
<option value="Europe/Rome" {% if timezone_config.timezone=='Europe/Rome'
|
||||||
|
%}selected{% endif %}>Europe/Rome (CET/CEST)</option>
|
||||||
|
<option value="US/Eastern" {% if timezone_config.timezone=='US/Eastern'
|
||||||
|
%}selected{% endif %}>US/Eastern (EST/EDT)</option>
|
||||||
|
<option value="US/Central" {% if timezone_config.timezone=='US/Central'
|
||||||
|
%}selected{% endif %}>US/Central (CST/CDT)</option>
|
||||||
|
<option value="US/Mountain" {% if timezone_config.timezone=='US/Mountain'
|
||||||
|
%}selected{% endif %}>US/Mountain (MST/MDT)</option>
|
||||||
|
<option value="US/Pacific" {% if timezone_config.timezone=='US/Pacific'
|
||||||
|
%}selected{% endif %}>US/Pacific (PST/PDT)</option>
|
||||||
|
<option value="Asia/Tokyo" {% if timezone_config.timezone=='Asia/Tokyo'
|
||||||
|
%}selected{% endif %}>Asia/Tokyo (JST)</option>
|
||||||
|
<option value="Asia/Shanghai" {% if timezone_config.timezone=='Asia/Shanghai'
|
||||||
|
%}selected{% endif %}>Asia/Shanghai (CST)</option>
|
||||||
|
<option value="Australia/Sydney" {% if
|
||||||
|
timezone_config.timezone=='Australia/Sydney' %}selected{% endif %}>
|
||||||
|
Australia/Sydney (AEST/AEDT)</option>
|
||||||
|
</select>
|
||||||
|
<div class="form-text">Current: {{ timezone_config.timezone }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
<h6>System Settings</h6>
|
<h6>System Settings</h6>
|
||||||
<p class="text-muted">Configure general system behavior.</p>
|
<p class="text-muted">Configure general system behavior.</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user