mirror of
https://github.com/morpheus65535/bazarr
synced 2024-12-25 09:12:38 +00:00
WIP
This commit is contained in:
parent
8230208ce5
commit
184b57da41
5 changed files with 99 additions and 67 deletions
|
@ -10,15 +10,21 @@ class EventStream:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.queue = deque(maxlen=10)
|
self.queue = deque(maxlen=100)
|
||||||
|
|
||||||
def write(self, msg):
|
def write(self, type=None, series=None, episode=None, movie=None):
|
||||||
"""
|
"""
|
||||||
:param msg: The message to display.
|
:param type: The type of element.
|
||||||
:type msg: str
|
:type type: str
|
||||||
|
:param type: The series id.
|
||||||
|
:type type: str
|
||||||
|
:param type: The episode id.
|
||||||
|
:type type: str
|
||||||
|
:param type: The movie id.
|
||||||
|
:type type: str
|
||||||
"""
|
"""
|
||||||
|
msg = {"type": type, "series": series, "episode": episode, "movie": movie}
|
||||||
self.queue.append("data:" + msg + "\n\n")
|
self.queue.append("data:" + json.dumps(msg) + "\n\n")
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
"""
|
"""
|
||||||
|
@ -29,6 +35,8 @@ class EventStream:
|
||||||
while True:
|
while True:
|
||||||
if self.queue:
|
if self.queue:
|
||||||
return self.queue.popleft()
|
return self.queue.popleft()
|
||||||
|
else:
|
||||||
|
return ':'
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ from list_subtitles import store_subtitles, store_subtitles_movie, series_scan_s
|
||||||
list_missing_subtitles, list_missing_subtitles_movies
|
list_missing_subtitles, list_missing_subtitles_movies
|
||||||
from utils import history_log, history_log_movie
|
from utils import history_log, history_log_movie
|
||||||
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 SSE import event_stream
|
||||||
|
|
||||||
from subliminal_patch.core import SUBTITLE_EXTENSIONS
|
from subliminal_patch.core import SUBTITLE_EXTENSIONS
|
||||||
|
|
||||||
|
@ -44,6 +45,11 @@ class Badges(Resource):
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
||||||
|
class Events(Resource):
|
||||||
|
def get(self):
|
||||||
|
return Response(event_stream.read(), mimetype="text/event-stream")
|
||||||
|
|
||||||
|
|
||||||
class Series(Resource):
|
class Series(Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
start = request.args.get('start') or 0
|
start = request.args.get('start') or 0
|
||||||
|
@ -102,10 +108,17 @@ class Episodes(Resource):
|
||||||
length = request.args.get('length') or -1
|
length = request.args.get('length') or -1
|
||||||
draw = request.args.get('draw')
|
draw = request.args.get('draw')
|
||||||
|
|
||||||
seriesId = request.args.get('id')
|
seriesId = request.args.get('seriesid')
|
||||||
|
episodeId = request.args.get('episodeid')
|
||||||
row_count = database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE sonarrSeriesId=?",
|
row_count = database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE sonarrSeriesId=?",
|
||||||
(seriesId,), only_one=True)['count']
|
(seriesId,), only_one=True)['count']
|
||||||
if seriesId:
|
if episodeId:
|
||||||
|
result = database.execute("SELECT * FROM table_episodes WHERE sonarrEpisodeId=?", (episodeId,))
|
||||||
|
desired_languages = database.execute("SELECT languages FROM table_shows WHERE sonarrSeriesId=?",
|
||||||
|
(seriesId,), only_one=True)['languages']
|
||||||
|
if desired_languages == "None":
|
||||||
|
desired_languages = '[]'
|
||||||
|
elif seriesId:
|
||||||
result = database.execute("SELECT * FROM table_episodes WHERE sonarrSeriesId=? ORDER BY season DESC, "
|
result = database.execute("SELECT * FROM table_episodes WHERE sonarrSeriesId=? ORDER BY season DESC, "
|
||||||
"episode DESC", (seriesId,))
|
"episode DESC", (seriesId,))
|
||||||
desired_languages = database.execute("SELECT languages FROM table_shows WHERE sonarrSeriesId=?",
|
desired_languages = database.execute("SELECT languages FROM table_shows WHERE sonarrSeriesId=?",
|
||||||
|
@ -115,6 +128,9 @@ class Episodes(Resource):
|
||||||
else:
|
else:
|
||||||
return "Series ID not provided", 400
|
return "Series ID not provided", 400
|
||||||
for item in result:
|
for item in result:
|
||||||
|
# Add Datatables rowId
|
||||||
|
item.update({"DT_RowId": 'row_' + str(item['sonarrEpisodeId'])})
|
||||||
|
|
||||||
# Parse subtitles
|
# Parse subtitles
|
||||||
if item['subtitles']:
|
if item['subtitles']:
|
||||||
item.update({"subtitles": ast.literal_eval(item['subtitles'])})
|
item.update({"subtitles": ast.literal_eval(item['subtitles'])})
|
||||||
|
@ -612,6 +628,7 @@ class WantedMovies(Resource):
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(Badges, '/badges')
|
api.add_resource(Badges, '/badges')
|
||||||
|
api.add_resource(Events, '/events')
|
||||||
api.add_resource(Series, '/series')
|
api.add_resource(Series, '/series')
|
||||||
api.add_resource(Episodes, '/episodes')
|
api.add_resource(Episodes, '/episodes')
|
||||||
api.add_resource(EpisodesSubtitlesDelete, '/episodes_subtitles_delete')
|
api.add_resource(EpisodesSubtitlesDelete, '/episodes_subtitles_delete')
|
||||||
|
|
|
@ -26,6 +26,7 @@ from helper import path_replace, path_replace_movie, path_replace_reverse, \
|
||||||
|
|
||||||
from queueconfig import notifications
|
from queueconfig import notifications
|
||||||
from embedded_subs_reader import embedded_subs_reader
|
from embedded_subs_reader import embedded_subs_reader
|
||||||
|
from SSE import event_stream
|
||||||
import six
|
import six
|
||||||
|
|
||||||
gc.enable()
|
gc.enable()
|
||||||
|
@ -90,7 +91,7 @@ def store_subtitles(original_path, reversed_path):
|
||||||
|
|
||||||
database.execute("UPDATE table_episodes SET subtitles=? WHERE path=?",
|
database.execute("UPDATE table_episodes SET subtitles=? WHERE path=?",
|
||||||
(str(actual_subtitles), original_path))
|
(str(actual_subtitles), original_path))
|
||||||
matching_episodes = database.execute("SELECT sonarrEpisodeId FROM table_episodes WHERE path=?",
|
matching_episodes = database.execute("SELECT sonarrEpisodeId, sonarrSeriesId FROM table_episodes WHERE path=?",
|
||||||
(original_path,))
|
(original_path,))
|
||||||
|
|
||||||
for episode in matching_episodes:
|
for episode in matching_episodes:
|
||||||
|
@ -104,6 +105,8 @@ def store_subtitles(original_path, reversed_path):
|
||||||
|
|
||||||
logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path)
|
logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path)
|
||||||
|
|
||||||
|
event_stream.write(type='episode', series=episode['sonarrSeriesId'], episode=episode['sonarrEpisodeId'])
|
||||||
|
|
||||||
return actual_subtitles
|
return actual_subtitles
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -254,19 +254,44 @@
|
||||||
<script src="{{ url_for('static',filename='js/custom.js') }}"></script>
|
<script src="{{ url_for('static',filename='js/custom.js') }}"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
BadgesAjax();
|
||||||
|
|
||||||
|
$('.table').on('draw.dt', function () {
|
||||||
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
||||||
|
});
|
||||||
|
|
||||||
|
var events = new EventSource('{{ url_for('api.events') }}');
|
||||||
|
events.onmessage = function (event) {
|
||||||
|
var event_json = JSON.parse(event.data);
|
||||||
|
if (event_json.type === 'episode') {
|
||||||
|
rowId = $('#episodes').DataTable().row('#row_'+event_json.episode);
|
||||||
|
if (rowId.length) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ url_for('api.episodes') }}?seriesid="+event_json.series+"&episodeid="+event_json.episode,
|
||||||
|
async: true,
|
||||||
|
success: function (data) {
|
||||||
|
$('#episodes').DataTable().row(rowId).data(data.data[0]);
|
||||||
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function BadgesAjax() {
|
function BadgesAjax() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "{{url_for('api.badges')}}",
|
url: "{{url_for('api.badges')}}",
|
||||||
async: true,
|
async: true,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (data['throttled_providers']) {
|
if (data['throttled_providers']) {
|
||||||
$('#throttled_providers_count').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['throttled_providers'] + '</div>')
|
$('#throttled_providers_count').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['throttled_providers'] + '</div>');
|
||||||
}
|
}
|
||||||
if (data['missing_episodes']) {
|
if (data['missing_episodes']) {
|
||||||
$('#wanted').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['missing_episodes'] + '</div>')
|
$('#wanted').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['missing_episodes'] + '</div>');
|
||||||
}
|
}
|
||||||
if (data['missing_movies']) {
|
if (data['missing_movies']) {
|
||||||
$('#wanted').append('<div id="wanted_movies" class="floating ui tiny green label" style="left:90% !important;top:3em !important;">' + data['missing_movies'] + '</div>')
|
$('#wanted').append('<div id="wanted_movies" class="floating ui tiny green label" style="left:90% !important;top:3em !important;">' + data['missing_movies'] + '</div>');
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -277,15 +302,6 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
BadgesAjax()
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip({html: true})
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.table').on('draw.dt', function () {
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock tail_js %}
|
{% endblock tail_js %}
|
||||||
|
|
|
@ -38,15 +38,22 @@
|
||||||
{% block bcleft %}
|
{% block bcleft %}
|
||||||
<div class="">
|
<div class="">
|
||||||
<button class="btn btn-outline">
|
<button class="btn btn-outline">
|
||||||
<i class="fas fa-sync align-top text-themecolor text-center font-20" aria-hidden="true"></i>
|
<div><i class="fas fa-sync align-top text-themecolor text-center font-20" aria-hidden="true"></i></div>
|
||||||
<span class="align-bottom text-themecolor small text-center">Update</span>
|
<div class="align-bottom text-themecolor small text-center">Scan Disk</div>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-outline">
|
||||||
|
<div><i class="fas fa-search align-top text-themecolor text-center font-20" aria-hidden="true"></i></div>
|
||||||
|
<div class="align-bottom text-themecolor small text-center">Search</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% endblock bcleft %}
|
{% endblock bcleft %}
|
||||||
|
|
||||||
{% block bcright %}
|
{% block bcright %}
|
||||||
<div class="d-flex m-t-5 justify-content-end">
|
<div class="d-flex m-t-5 justify-content-end">
|
||||||
<h5 class="m-t-0 text-themecolor">Some page settings</h5>
|
<button class="btn btn-outline">
|
||||||
|
<div><i class="fas fa-wrench align-top text-themecolor text-center font-20" aria-hidden="true"></i></div>
|
||||||
|
<div class="align-bottom text-themecolor small text-center">Edit Series</div>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% endblock bcright %}
|
{% endblock bcright %}
|
||||||
|
|
||||||
|
@ -241,14 +248,18 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var table = $('#episodes').DataTable({
|
var table = $('#episodes').DataTable({
|
||||||
"processing": false,
|
"processing": true,
|
||||||
"serverSide": true,
|
"serverSide": true,
|
||||||
|
language: {
|
||||||
|
zeroRecords: 'No Episodes Found For This Series',
|
||||||
|
processing: "Loading Episodes..."
|
||||||
|
},
|
||||||
"searching": false,
|
"searching": false,
|
||||||
"ordering": false,
|
"ordering": false,
|
||||||
"lengthChange": false,
|
"lengthChange": false,
|
||||||
"responsive": true,
|
"responsive": true,
|
||||||
"pageLength": 100,
|
"pageLength": 100,
|
||||||
"ajax": "{{ url_for('api.episodes') }}?id={{id}}",
|
"ajax": "{{ url_for('api.episodes') }}?seriesid={{id}}",
|
||||||
rowGroup: {
|
rowGroup: {
|
||||||
dataSrc: function(data) {
|
dataSrc: function(data) {
|
||||||
return 'Season ' + data.season;
|
return 'Season ' + data.season;
|
||||||
|
@ -340,14 +351,6 @@
|
||||||
data: values,
|
data: values,
|
||||||
beforeSend: function() {
|
beforeSend: function() {
|
||||||
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
||||||
},
|
|
||||||
complete: function(data) {
|
|
||||||
table.ajax.reload(null, false);
|
|
||||||
if (data['responseJSON']) {
|
|
||||||
console.log(data['responseJSON']);
|
|
||||||
} else {
|
|
||||||
console.log("Unable to delete subtitle.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -373,14 +376,6 @@
|
||||||
data: values,
|
data: values,
|
||||||
beforeSend: function() {
|
beforeSend: function() {
|
||||||
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
||||||
},
|
|
||||||
complete: function(data) {
|
|
||||||
table.ajax.reload(null, false);
|
|
||||||
if (data['responseJSON']) {
|
|
||||||
console.log(data['responseJSON'][0]);
|
|
||||||
} else {
|
|
||||||
console.log("No subtitle found.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -520,13 +515,7 @@
|
||||||
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
|
||||||
},
|
},
|
||||||
complete: function(data) {
|
complete: function(data) {
|
||||||
$('#episodes').DataTable().ajax.reload(null, false);
|
|
||||||
$('#manualSearchModal').modal('hide');
|
$('#manualSearchModal').modal('hide');
|
||||||
if (data['responseJSON']) {
|
|
||||||
console.log(data['responseJSON'][0]);
|
|
||||||
} else {
|
|
||||||
console.log("No subtitle downloaded.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -568,7 +557,6 @@
|
||||||
contentType: false,
|
contentType: false,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
success: function(){
|
success: function(){
|
||||||
$('#episodes').DataTable().ajax.reload(null, false);
|
|
||||||
$('#uploadModal').modal('hide');
|
$('#uploadModal').modal('hide');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue