mirror of https://github.com/morpheus65535/bazarr
WIP
This commit is contained in:
parent
54376299d9
commit
8749fc13f2
|
@ -8,6 +8,7 @@ import time
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
import platform
|
import platform
|
||||||
import io
|
import io
|
||||||
|
from calendar import day_name
|
||||||
|
|
||||||
from get_args import args
|
from get_args import args
|
||||||
from config import settings, base_url
|
from config import settings, base_url
|
||||||
|
@ -27,6 +28,7 @@ from list_subtitles import store_subtitles, store_subtitles_movie, series_scan_s
|
||||||
from utils import history_log, history_log_movie, get_sonarr_version, get_radarr_version
|
from utils import history_log, history_log_movie, get_sonarr_version, get_radarr_version
|
||||||
from get_providers import get_providers, get_providers_auth, list_throttled_providers
|
from get_providers import get_providers, get_providers_auth, list_throttled_providers
|
||||||
from websocket_handler import event_stream
|
from websocket_handler import event_stream
|
||||||
|
from scheduler import Scheduler
|
||||||
|
|
||||||
from subliminal_patch.core import SUBTITLE_EXTENSIONS
|
from subliminal_patch.core import SUBTITLE_EXTENSIONS
|
||||||
|
|
||||||
|
@ -60,6 +62,15 @@ class Languages(Resource):
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemTasks(Resource):
|
||||||
|
def get(self):
|
||||||
|
scheduler = Scheduler()
|
||||||
|
|
||||||
|
task_list = scheduler.get_task_list()
|
||||||
|
|
||||||
|
return jsonify(data=task_list)
|
||||||
|
|
||||||
|
|
||||||
class SystemLogs(Resource):
|
class SystemLogs(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
logs = []
|
logs = []
|
||||||
|
@ -1090,6 +1101,7 @@ class SearchWantedMovies(Resource):
|
||||||
api.add_resource(Badges, '/badges')
|
api.add_resource(Badges, '/badges')
|
||||||
api.add_resource(Languages, '/languages')
|
api.add_resource(Languages, '/languages')
|
||||||
|
|
||||||
|
api.add_resource(SystemTasks, '/systemtasks')
|
||||||
api.add_resource(SystemLogs, '/systemlogs')
|
api.add_resource(SystemLogs, '/systemlogs')
|
||||||
api.add_resource(SystemStatus, '/systemstatus')
|
api.add_resource(SystemStatus, '/systemstatus')
|
||||||
api.add_resource(SystemReleases, '/systemreleases')
|
api.add_resource(SystemReleases, '/systemreleases')
|
||||||
|
|
|
@ -1016,6 +1016,12 @@ def check_update():
|
||||||
redirect(ref)
|
redirect(ref)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/systemtasks')
|
||||||
|
@login_required
|
||||||
|
def systemtasks():
|
||||||
|
return render_template('systemtasks.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/systemlogs')
|
@app.route('/systemlogs')
|
||||||
@login_required
|
@login_required
|
||||||
def systemlogs():
|
def systemlogs():
|
||||||
|
|
|
@ -16,12 +16,13 @@ from apscheduler.triggers.interval import IntervalTrigger
|
||||||
from apscheduler.triggers.cron import CronTrigger
|
from apscheduler.triggers.cron import CronTrigger
|
||||||
from apscheduler.triggers.date import DateTrigger
|
from apscheduler.triggers.date import DateTrigger
|
||||||
from apscheduler.events import EVENT_JOB_SUBMITTED, EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
|
from apscheduler.events import EVENT_JOB_SUBMITTED, EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
import pytz
|
import pytz
|
||||||
from tzlocal import get_localzone
|
from tzlocal import get_localzone
|
||||||
from calendar import day_name
|
from calendar import day_name
|
||||||
import pretty
|
import pretty
|
||||||
from six import PY2
|
from random import seed, uniform, randint
|
||||||
|
from websocket_handler import event_stream
|
||||||
|
|
||||||
|
|
||||||
class Scheduler:
|
class Scheduler:
|
||||||
|
@ -38,10 +39,12 @@ class Scheduler:
|
||||||
def task_listener_add(event):
|
def task_listener_add(event):
|
||||||
if event.job_id not in self.__running_tasks:
|
if event.job_id not in self.__running_tasks:
|
||||||
self.__running_tasks.append(event.job_id)
|
self.__running_tasks.append(event.job_id)
|
||||||
|
event_stream.write(type='task', action='insert')
|
||||||
|
|
||||||
def task_listener_remove(event):
|
def task_listener_remove(event):
|
||||||
if event.job_id in self.__running_tasks:
|
if event.job_id in self.__running_tasks:
|
||||||
self.__running_tasks.remove(event.job_id)
|
self.__running_tasks.remove(event.job_id)
|
||||||
|
event_stream.write(type='task', action='delete')
|
||||||
|
|
||||||
self.aps_scheduler.add_listener(task_listener_add, EVENT_JOB_SUBMITTED)
|
self.aps_scheduler.add_listener(task_listener_add, EVENT_JOB_SUBMITTED)
|
||||||
self.aps_scheduler.add_listener(task_listener_remove, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
|
self.aps_scheduler.add_listener(task_listener_remove, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
|
||||||
|
@ -60,6 +63,7 @@ class Scheduler:
|
||||||
self.__update_bazarr_task()
|
self.__update_bazarr_task()
|
||||||
self.__search_wanted_subtitles_task()
|
self.__search_wanted_subtitles_task()
|
||||||
self.__upgrade_subtitles_task()
|
self.__upgrade_subtitles_task()
|
||||||
|
self.__randomize_interval_task()
|
||||||
|
|
||||||
def add_job(self, job, name=None, max_instances=1, coalesce=True, args=None):
|
def add_job(self, job, name=None, max_instances=1, coalesce=True, args=None):
|
||||||
self.aps_scheduler.add_job(
|
self.aps_scheduler.add_job(
|
||||||
|
@ -123,9 +127,12 @@ class Scheduler:
|
||||||
|
|
||||||
if isinstance(job.trigger, IntervalTrigger):
|
if isinstance(job.trigger, IntervalTrigger):
|
||||||
interval = "every " + get_time_from_interval(job.trigger.__getstate__()['interval'])
|
interval = "every " + get_time_from_interval(job.trigger.__getstate__()['interval'])
|
||||||
task_list.append([job.name, interval, next_run, job.id])
|
task_list.append({'name': job.name, 'interval': interval, 'next_run_in': next_run,
|
||||||
|
'next_run_time': job.next_run_time.replace(tzinfo=None), 'job_id': job.id})
|
||||||
elif isinstance(job.trigger, CronTrigger):
|
elif isinstance(job.trigger, CronTrigger):
|
||||||
task_list.append([job.name, get_time_from_cron(job.trigger.fields), next_run, job.id])
|
task_list.append({'name': job.name, 'interval': get_time_from_cron(job.trigger.fields),
|
||||||
|
'next_run_in': next_run, 'next_run_time': job.next_run_time.replace(tzinfo=None),
|
||||||
|
'job_id': job.id})
|
||||||
|
|
||||||
return task_list
|
return task_list
|
||||||
|
|
||||||
|
@ -188,9 +195,7 @@ class Scheduler:
|
||||||
id='update_all_movies', name='Update all Movie Subtitles from disk', replace_existing=True)
|
id='update_all_movies', name='Update all Movie Subtitles from disk', replace_existing=True)
|
||||||
|
|
||||||
def __update_bazarr_task(self):
|
def __update_bazarr_task(self):
|
||||||
if PY2:
|
if not args.no_update:
|
||||||
pass
|
|
||||||
elif not args.no_update:
|
|
||||||
task_name = 'Update Bazarr from source on Github'
|
task_name = 'Update Bazarr from source on Github'
|
||||||
if args.release_update:
|
if args.release_update:
|
||||||
task_name = 'Update Bazarr from release on Github'
|
task_name = 'Update Bazarr from release on Github'
|
||||||
|
@ -231,3 +236,9 @@ class Scheduler:
|
||||||
upgrade_subtitles, IntervalTrigger(hours=int(settings.general.upgrade_frequency)), max_instances=1,
|
upgrade_subtitles, IntervalTrigger(hours=int(settings.general.upgrade_frequency)), max_instances=1,
|
||||||
coalesce=True, misfire_grace_time=15, id='upgrade_subtitles',
|
coalesce=True, misfire_grace_time=15, id='upgrade_subtitles',
|
||||||
name='Upgrade previously downloaded Subtitles', replace_existing=True)
|
name='Upgrade previously downloaded Subtitles', replace_existing=True)
|
||||||
|
|
||||||
|
def __randomize_interval_task(self):
|
||||||
|
for job in self.aps_scheduler.get_jobs():
|
||||||
|
if isinstance(job.trigger, IntervalTrigger):
|
||||||
|
seed(randint(0,1000))
|
||||||
|
self.aps_scheduler.modify_job(job.id, next_run_time=datetime.now() + timedelta(seconds=uniform(job.trigger.interval.total_seconds()*0.75, job.trigger.interval.total_seconds())))
|
||||||
|
|
|
@ -188,7 +188,7 @@
|
||||||
<li><a href="#"><i
|
<li><a href="#"><i
|
||||||
class="fas fa-laptop"></i><span class="hide-menu"> System</span></a>
|
class="fas fa-laptop"></i><span class="hide-menu"> System</span></a>
|
||||||
<ul aria-expanded="false" class="collapse">
|
<ul aria-expanded="false" class="collapse">
|
||||||
<li><a href="/"> Tasks</a></li>
|
<li><a href="{{ url_for('systemtasks') }}"> Tasks</a></li>
|
||||||
<li><a href="{{ url_for('systemlogs') }}"> Logs</a></li>
|
<li><a href="{{ url_for('systemlogs') }}"> Logs</a></li>
|
||||||
<li><a href="/"> Providers</a></li>
|
<li><a href="/"> Providers</a></li>
|
||||||
<li><a href="{{ url_for('systemstatus') }}"> Status</a></li>
|
<li><a href="{{ url_for('systemstatus') }}"> Status</a></li>
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
{% extends '_main.html' %}
|
||||||
|
|
||||||
|
{% block title %}Logs - Bazarr{% endblock %}
|
||||||
|
|
||||||
|
{% block bcleft %}
|
||||||
|
|
||||||
|
{% endblock bcleft %}
|
||||||
|
|
||||||
|
{% block bcright %}
|
||||||
|
|
||||||
|
{% endblock bcright %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="container-fluid">
|
||||||
|
<table id="tasks" class="table table-striped" style="width:100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Execution Frequency</th>
|
||||||
|
<th>Next Execution</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock body %}
|
||||||
|
|
||||||
|
{% block tail %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
var table = $('#tasks').DataTable( {
|
||||||
|
language: {
|
||||||
|
zeroRecords: 'No Task Scheduled.',
|
||||||
|
processing: "Loading Tasks..."
|
||||||
|
},
|
||||||
|
paging: false,
|
||||||
|
lengthChange: false,
|
||||||
|
pageLength: {{ settings.general.page_size }},
|
||||||
|
searching: false,
|
||||||
|
ordering: false,
|
||||||
|
processing: true,
|
||||||
|
serverSide: false,
|
||||||
|
ajax: "{{ url_for('api.systemtasks') }}",
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
data: 'name'
|
||||||
|
},
|
||||||
|
{ data: 'interval'
|
||||||
|
},
|
||||||
|
{ data: 'next_run_in'
|
||||||
|
},
|
||||||
|
{ data: null,
|
||||||
|
render: function(data) {
|
||||||
|
return 'button'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock tail %}
|
Loading…
Reference in New Issue