mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-10 12:00:01 +00:00
Changed schedule start- and end-time to schedule start and duration
Localized display of schedule start-time and duration Removed displaying scheduling settings if "APScheduler" is missing Input check for start-time and duration
This commit is contained in:
parent
d83c731030
commit
6e8445fed5
2
cps.py
2
cps.py
@ -77,7 +77,7 @@ def main():
|
||||
app.register_blueprint(oauth)
|
||||
|
||||
# Register scheduled tasks
|
||||
register_scheduled_tasks()
|
||||
register_scheduled_tasks() # ToDo only reconnect if reconnect is enabled
|
||||
register_startup_tasks()
|
||||
|
||||
success = web_server.start()
|
||||
|
76
cps/admin.py
76
cps/admin.py
@ -24,13 +24,12 @@ import os
|
||||
import re
|
||||
import base64
|
||||
import json
|
||||
import time
|
||||
import operator
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, time
|
||||
from functools import wraps
|
||||
|
||||
from babel import Locale
|
||||
from babel.dates import format_datetime
|
||||
from babel.dates import format_datetime, format_time, format_timedelta
|
||||
from flask import Blueprint, flash, redirect, url_for, abort, request, make_response, send_from_directory, g, Response
|
||||
from flask_login import login_required, current_user, logout_user, confirm_login
|
||||
from flask_babel import gettext as _
|
||||
@ -58,7 +57,8 @@ feature_support = {
|
||||
'goodreads': bool(services.goodreads_support),
|
||||
'kobo': bool(services.kobo),
|
||||
'updater': constants.UPDATER_AVAILABLE,
|
||||
'gmail': bool(services.gmail)
|
||||
'gmail': bool(services.gmail),
|
||||
'scheduler': schedule.use_APScheduler
|
||||
}
|
||||
|
||||
try:
|
||||
@ -184,6 +184,7 @@ def update_thumbnails():
|
||||
@login_required
|
||||
@admin_required
|
||||
def admin():
|
||||
locale = get_locale()
|
||||
version = updater_thread.get_current_version_info()
|
||||
if version is False:
|
||||
commit = _(u'Unknown')
|
||||
@ -198,15 +199,19 @@ def admin():
|
||||
form_date -= timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
||||
elif commit[19] == '-':
|
||||
form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
||||
commit = format_datetime(form_date - tz, format='short', locale=get_locale())
|
||||
commit = format_datetime(form_date - tz, format='short', locale=locale)
|
||||
else:
|
||||
commit = version['version']
|
||||
|
||||
all_user = ub.session.query(ub.User).all()
|
||||
email_settings = config.get_mail_settings()
|
||||
kobo_support = feature_support['kobo'] and config.config_kobo_sync
|
||||
schedule_time = format_time(time(hour=config.schedule_start_time), format="short", locale=locale)
|
||||
t = timedelta(hours=config.schedule_duration // 60, minutes=config.schedule_duration % 60)
|
||||
schedule_duration = format_timedelta(t, format="short", threshold=.99, locale=locale)
|
||||
|
||||
return render_title_template("admin.html", allUser=all_user, email=email_settings, config=config, commit=commit,
|
||||
feature_support=feature_support, kobo_support=kobo_support,
|
||||
feature_support=feature_support, schedule_time=schedule_time,
|
||||
schedule_duration=schedule_duration,
|
||||
title=_(u"Admin page"), page="admin")
|
||||
|
||||
|
||||
@ -1660,36 +1665,57 @@ def update_mailsettings():
|
||||
@admin_required
|
||||
def edit_scheduledtasks():
|
||||
content = config.get_scheduled_task_settings()
|
||||
return render_title_template("schedule_edit.html", config=content, title=_(u"Edit Scheduled Tasks Settings"))
|
||||
time_field = list()
|
||||
duration_field = list()
|
||||
|
||||
locale = get_locale()
|
||||
for n in range(24):
|
||||
time_field.append((n , format_time(time(hour=n), format="short", locale=locale)))
|
||||
for n in range(5, 65, 5):
|
||||
t = timedelta(hours=n // 60, minutes=n % 60)
|
||||
duration_field.append((n, format_timedelta(t, format="short", threshold=.99, locale=locale)))
|
||||
|
||||
return render_title_template("schedule_edit.html", config=content, starttime=time_field, duration=duration_field, title=_(u"Edit Scheduled Tasks Settings"))
|
||||
|
||||
|
||||
@admi.route("/admin/scheduledtasks", methods=["POST"])
|
||||
@login_required
|
||||
@admin_required
|
||||
def update_scheduledtasks():
|
||||
error = False
|
||||
to_save = request.form.to_dict()
|
||||
_config_int(to_save, "schedule_start_time")
|
||||
_config_int(to_save, "schedule_end_time")
|
||||
if "0" <= to_save.get("schedule_start_time") <= "23":
|
||||
_config_int(to_save, "schedule_start_time")
|
||||
else:
|
||||
flash(_(u"Invalid start time for task specified"), category="error")
|
||||
error = True
|
||||
if "0" < to_save.get("schedule_duration") <= "60":
|
||||
_config_int(to_save, "schedule_duration")
|
||||
else:
|
||||
flash(_(u"Invalid duration for task specified"), category="error")
|
||||
error = True
|
||||
_config_checkbox(to_save, "schedule_generate_book_covers")
|
||||
_config_checkbox(to_save, "schedule_generate_series_covers")
|
||||
_config_checkbox(to_save, "schedule_reconnect")
|
||||
|
||||
try:
|
||||
config.save()
|
||||
flash(_(u"Scheduled tasks settings updated"), category="success")
|
||||
if not error:
|
||||
try:
|
||||
config.save()
|
||||
flash(_(u"Scheduled tasks settings updated"), category="success")
|
||||
|
||||
# Cancel any running tasks
|
||||
schedule.end_scheduled_tasks()
|
||||
# Cancel any running tasks
|
||||
schedule.end_scheduled_tasks()
|
||||
|
||||
# Re-register tasks with new settings
|
||||
schedule.register_scheduled_tasks(cli.reconnect_enable)
|
||||
except IntegrityError as ex:
|
||||
ub.session.rollback()
|
||||
log.error("An unknown error occurred while saving scheduled tasks settings")
|
||||
flash(_(u"An unknown error occurred. Please try again later."), category="error")
|
||||
except OperationalError:
|
||||
ub.session.rollback()
|
||||
log.error("Settings DB is not Writeable")
|
||||
flash(_("Settings DB is not Writeable"), category="error")
|
||||
# Re-register tasks with new settings
|
||||
schedule.register_scheduled_tasks(config.schedule_reconnect)
|
||||
except IntegrityError:
|
||||
ub.session.rollback()
|
||||
log.error("An unknown error occurred while saving scheduled tasks settings")
|
||||
flash(_(u"An unknown error occurred. Please try again later."), category="error")
|
||||
except OperationalError:
|
||||
ub.session.rollback()
|
||||
log.error("Settings DB is not Writeable")
|
||||
flash(_("Settings DB is not Writeable"), category="error")
|
||||
|
||||
return edit_scheduledtasks()
|
||||
|
||||
|
@ -142,9 +142,10 @@ class _Settings(_Base):
|
||||
config_allow_reverse_proxy_header_login = Column(Boolean, default=False)
|
||||
|
||||
schedule_start_time = Column(Integer, default=4)
|
||||
schedule_end_time = Column(Integer, default=6)
|
||||
schedule_duration = Column(Integer, default=10)
|
||||
schedule_generate_book_covers = Column(Boolean, default=False)
|
||||
schedule_generate_series_covers = Column(Boolean, default=False)
|
||||
schedule_reconnect = Column(Boolean, default=False)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__
|
||||
|
@ -19,7 +19,7 @@
|
||||
import datetime
|
||||
|
||||
from . import config, constants
|
||||
from .services.background_scheduler import BackgroundScheduler
|
||||
from .services.background_scheduler import BackgroundScheduler, use_APScheduler
|
||||
from .tasks.database import TaskReconnectDatabase
|
||||
from .tasks.thumbnail import TaskGenerateCoverThumbnails, TaskGenerateSeriesThumbnails, TaskClearCoverThumbnailCache
|
||||
from .services.worker import WorkerThread
|
||||
@ -27,7 +27,7 @@ from .services.worker import WorkerThread
|
||||
|
||||
def get_scheduled_tasks(reconnect=True):
|
||||
tasks = list()
|
||||
|
||||
# config.schedule_reconnect or
|
||||
# Reconnect Calibre database (metadata.db)
|
||||
if reconnect:
|
||||
tasks.append([lambda: TaskReconnectDatabase(), 'reconnect', False])
|
||||
@ -59,15 +59,14 @@ def register_scheduled_tasks(reconnect=True):
|
||||
scheduler.remove_all_jobs()
|
||||
|
||||
start = config.schedule_start_time
|
||||
end = config.schedule_end_time
|
||||
duration = config.schedule_duration
|
||||
|
||||
# Register scheduled tasks
|
||||
if start != end:
|
||||
scheduler.schedule_tasks(tasks=get_scheduled_tasks(), trigger='cron', hour=start)
|
||||
scheduler.schedule(func=end_scheduled_tasks, trigger='cron', name="end scheduled task", hour=end)
|
||||
scheduler.schedule_tasks(tasks=get_scheduled_tasks(), trigger='cron', hour=start)
|
||||
scheduler.schedule(func=end_scheduled_tasks, trigger='cron', name="end scheduled task", hour=start) # toDo
|
||||
|
||||
# Kick-off tasks, if they should currently be running
|
||||
if should_task_be_running(start, end):
|
||||
if should_task_be_running(start, duration):
|
||||
scheduler.schedule_tasks_immediately(tasks=get_scheduled_tasks(reconnect))
|
||||
|
||||
|
||||
@ -76,14 +75,17 @@ def register_startup_tasks():
|
||||
|
||||
if scheduler:
|
||||
start = config.schedule_start_time
|
||||
end = config.schedule_end_time
|
||||
duration = config.schedule_duration
|
||||
|
||||
# Run scheduled tasks immediately for development and testing
|
||||
# Ignore tasks that should currently be running, as these will be added when registering scheduled tasks
|
||||
if constants.APP_MODE in ['development', 'test'] and not should_task_be_running(start, end):
|
||||
if constants.APP_MODE in ['development', 'test'] and not should_task_be_running(start, duration):
|
||||
scheduler.schedule_tasks_immediately(tasks=get_scheduled_tasks(False))
|
||||
|
||||
|
||||
def should_task_be_running(start, end):
|
||||
now = datetime.datetime.now().hour
|
||||
return (start < end and start <= now < end) or (end < start and (now < end or start <= now ))
|
||||
def should_task_be_running(start, duration):
|
||||
now = datetime.datetime.now()
|
||||
start_time = datetime.datetime.now().replace(hour=start, minute=0, second=0, microsecond=0)
|
||||
end_time = start_time + datetime.timedelta(hours=duration // 60, minutes=duration % 60)
|
||||
return start_time < now < end_time
|
||||
# return (start < end and start <= now < end) or (end < start and (now < end or start <= now ))
|
||||
|
@ -31,6 +31,7 @@ class TaskReconnectDatabase(CalibreTask):
|
||||
self.listen_address = config.get_config_ipaddress()
|
||||
self.listen_port = config.config_port
|
||||
|
||||
|
||||
def run(self, worker_thread):
|
||||
address = self.listen_address if self.listen_address else 'localhost'
|
||||
port = self.listen_port if self.listen_port else 8083
|
||||
|
@ -161,18 +161,18 @@
|
||||
<a class="btn btn-default" id="view_config" href="{{url_for('admin.view_configuration')}}">{{_('Edit UI Configuration')}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if feature_support['scheduler'] %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>{{_('Scheduled Tasks')}}</h2>
|
||||
<div class="col-xs-12 col-sm-12 scheduled_tasks_details">
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-3">{{_('Time at which tasks start to run')}}</div>
|
||||
<div class="col-xs-6 col-sm-3">{{config.schedule_start_time}}:00</div>
|
||||
<div class="col-xs-6 col-sm-3">{{schedule_time}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-3">{{_('Time at which tasks stop running')}}</div>
|
||||
<div class="col-xs-6 col-sm-3">{{config.schedule_end_time}}:00</div>
|
||||
<div class="col-xs-6 col-sm-3">{{_('Maximum tasks duration')}}</div>
|
||||
<div class="col-xs-6 col-sm-3">{{schedule_duration}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-3">{{_('Generate book cover thumbnails')}}</div>
|
||||
@ -182,6 +182,11 @@
|
||||
<div class="col-xs-6 col-sm-3">{{_('Generate series cover thumbnails')}}</div>
|
||||
<div class="col-xs-6 col-sm-3">{{ display_bool_setting(config.schedule_generate_series_covers) }}</div>
|
||||
</div-->
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-3">{{_('Reconnect to Calibre Library')}}</div>
|
||||
<div class="col-xs-6 col-sm-3">{{ display_bool_setting(config.schedule_reconnect) }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a class="btn btn-default scheduledtasks" id="admin_edit_scheduled_tasks" href="{{url_for('admin.edit_scheduledtasks')}}">{{_('Edit Scheduled Tasks Settings')}}</a>
|
||||
{% if config.schedule_generate_book_covers %}
|
||||
@ -189,7 +194,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
<div class="row form-group">
|
||||
<h2>{{_('Administration')}}</h2>
|
||||
<a class="btn btn-default" id="debug" href="{{url_for('admin.download_debug')}}">{{_('Download Debug Package')}}</a>
|
||||
|
@ -11,16 +11,16 @@
|
||||
<div class="form-group">
|
||||
<label for="schedule_start_time">{{_('Time at which tasks start to run')}}</label>
|
||||
<select name="schedule_start_time" id="schedule_start_time" class="form-control">
|
||||
{% for n in range(24) %}
|
||||
<option value="{{n}}" {% if config.schedule_start_time == n %}selected{% endif %}>{{n}}{{_(':00')}}</option>
|
||||
{% for n in starttime %}
|
||||
<option value="{{n[0]}}" {% if config.schedule_start_time == n[0] %}selected{% endif %}>{{n[1]}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="schedule_end_time">{{_('Time at which tasks stop running')}}</label>
|
||||
<select name="schedule_end_time" id="schedule_end_time" class="form-control">
|
||||
{% for n in range(24) %}
|
||||
<option value="{{n}}" {% if config.schedule_end_time == n %}selected{% endif %}>{{n}}{{_(':00')}}</option>
|
||||
<label for="schedule_duration">{{_('Maximum tasks duration')}}</label>
|
||||
<select name="schedule_duration" id="schedule_duration" class="form-control">
|
||||
{% for n in duration %}
|
||||
<option value="{{n[0]}}" {% if config.schedule_duration == n[0] %}selected{% endif %}>{{n[1]}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
@ -32,6 +32,11 @@
|
||||
<input type="checkbox" id="schedule_generate_series_covers" name="schedule_generate_series_covers" {% if config.schedule_generate_series_covers %}checked{% endif %}>
|
||||
<label for="schedule_generate_series_covers">{{_('Generate Series Cover Thumbnails')}}</label>
|
||||
</div-->
|
||||
<div class="form-group">
|
||||
<input type="checkbox" id="schedule_reconnect" name="schedule_reconnect" {% if config.schedule_generate_book_covers %}checked{% endif %}>
|
||||
<label for="schedule_reconnect">{{_('Reconnect to Calibre Library')}}</label>
|
||||
</div>
|
||||
|
||||
<button type="submit" name="submit" value="submit" class="btn btn-default">{{_('Save')}}</button>
|
||||
<a href="{{ url_for('admin.admin') }}" id="email_back" class="btn btn-default">{{_('Cancel')}}</a>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue
Block a user