pull/884/head
Louis Vézina 5 years ago
parent a8e6b2c0b0
commit 8230208ce5

@ -270,7 +270,7 @@ class EpisodesSubtitlesUpload(Resource):
if sceneName == "null": if sceneName == "null":
sceneName = "None" sceneName = "None"
language = request.form.get('language') language = request.form.get('language')
forced = True if request.form.get('forced') == '1' else False forced = True if request.form.get('forced') == 'on' else False
upload = request.files.get('upload') upload = request.files.get('upload')
sonarrSeriesId = request.form.get('sonarrSeriesId') sonarrSeriesId = request.form.get('sonarrSeriesId')
sonarrEpisodeId = request.form.get('sonarrEpisodeId') sonarrEpisodeId = request.form.get('sonarrEpisodeId')

@ -27,6 +27,8 @@
<link href="{{ url_for('static',filename='css/bazarr.css') }}" id="theme" rel="stylesheet"> <link href="{{ url_for('static',filename='css/bazarr.css') }}" id="theme" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='datatables/datatables.min.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='datatables/datatables.min.css') }}">
<link rel="stylesheet" type="text/css"
href="{{ url_for('static',filename='datatables/rowGroup.dataTables.min.css') }}">
<link rel="stylesheet" type="text/css" <link rel="stylesheet" type="text/css"
href="{{ url_for('static',filename='datatables/responsive.dataTables.min.css') }}"> href="{{ url_for('static',filename='datatables/responsive.dataTables.min.css') }}">
<link rel="stylesheet" type="text/css" <link rel="stylesheet" type="text/css"
@ -246,6 +248,7 @@
<script src="{{ url_for('static',filename='plugins/sticky-kit-master/dist/sticky-kit.min.js') }}"></script> <script src="{{ url_for('static',filename='plugins/sticky-kit-master/dist/sticky-kit.min.js') }}"></script>
<!--Custom JavaScript --> <!--Custom JavaScript -->
<script src="{{ url_for('static',filename='datatables/jquery.dataTables.min.js') }}"></script> <script src="{{ url_for('static',filename='datatables/jquery.dataTables.min.js') }}"></script>
<script src="{{ url_for('static',filename='datatables/dataTables.rowGroup.min.js') }}"></script>
<script src="{{ url_for('static',filename='datatables/dataTables.responsive.min.js') }}"></script> <script src="{{ url_for('static',filename='datatables/dataTables.responsive.min.js') }}"></script>
<script src="{{ url_for('static',filename='plugins/datatables.net-bs4/js/dataTables.bootstrap4.min.js') }}"></script> <script src="{{ url_for('static',filename='plugins/datatables.net-bs4/js/dataTables.bootstrap4.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/custom.js') }}"></script> <script src="{{ url_for('static',filename='js/custom.js') }}"></script>

@ -3,206 +3,212 @@
{% block title %}Series - Bazarr{% endblock %} {% block title %}Series - Bazarr{% endblock %}
{% block head %} {% block head %}
<style> <style>
#seriesFanart { #seriesFanart {
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
background-position: top center; background-position: top center;
box-sizing: initial; box-sizing: initial;
margin-left: -32px; margin-left: -32px;
margin-top: -30px; margin-top: -30px;
padding: 2em; padding: 2em;
} }
#seriesDetails { #seriesDetails {
padding: 30px; padding: 30px;
background: rgba(0, 0, 0, 0.7); background: rgba(0, 0, 0, 0.7);
color: white; color: white;
margin: -32px; margin: -32px;
} }
#seriesPoster { #seriesPoster {
width: 250px; width: 250px;
} }
h1 { h1 {
color: white; color: white;
} }
span { span {
margin-right: 0.5em; margin-right: 0.5em;
} }
</style> </style>
{% endblock head %} {% endblock head %}
{% 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> <i class="fas fa-sync align-top text-themecolor text-center font-20" aria-hidden="true"></i>
<span class="align-bottom text-themecolor small text-center">Update</span> <span class="align-bottom text-themecolor small text-center">Update</span>
</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> <h5 class="m-t-0 text-themecolor">Some page settings</h5>
</div> </div>
{% endblock bcright %} {% endblock bcright %}
{% block body %} {% block body %}
<div class="container-fluid" id="seriesFanart"> <div class="container-fluid" id="seriesFanart">
<div class="row justify-content-md-center" id="seriesDetails"> <div class="row justify-content-md-center" id="seriesDetails">
<div class="col-sm-auto" id="seriesPosterColumn"> <div class="col-sm-auto" id="seriesPosterColumn">
<img id="seriesPoster" src=""> <img id="seriesPoster" src="">
</div> </div>
<div class="col"> <div class="col">
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<h1><span id="seriesTitle"></span></h1> <h1><span id="seriesTitle"></span></h1>
<i class="far fa-clone" id="seriesAlternateTitles" data-toggle="tooltip" data-placement="right"></i> <i class="far fa-clone" id="seriesAlternateTitles" data-toggle="tooltip" data-placement="right"></i>
</div> </div>
<div class="row"> <div class="row">
<h5><span id="seriesAudioLanguage" class="badge badge-secondary"></span></h5> <h5><span id="seriesAudioLanguage" class="badge badge-secondary"></span></h5>
<h5><span id="seriesMappedPath" class="badge badge-secondary"></span></h5> <h5><span id="seriesMappedPath" class="badge badge-secondary"></span></h5>
<h5><span id="seriesFileCount" class="badge badge-secondary"></span></h5> <h5><span id="seriesFileCount" class="badge badge-secondary"></span></h5>
</div> </div>
<div class="row"> <div class="row">
<h5><span id="seriesSubtitlesLanguages"></span></h5> <h5><span id="seriesSubtitlesLanguages"></span></h5>
</div> </div>
<div class="row"> <div class="row">
<h5><span id="seriesHearingImpaired" class="badge badge-secondary"></span></h5> <h5><span id="seriesHearingImpaired" class="badge badge-secondary"></span></h5>
<h5><span id="seriesForced" class="badge badge-secondary"></span></h5> <h5><span id="seriesForced" class="badge badge-secondary"></span></h5>
</div> </div>
<div class="row"> <div class="row">
<span id="seriesDescription"></span> <span id="seriesDescription"></span>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="container-fluid"> </div>
<!-- Bread crumb and right sidebar toggle --> <div class="container-fluid">
<!-- ============================================================== --> <!-- Bread crumb and right sidebar toggle -->
<table id="episodes" class="table table-striped" style="width:100%"> <!-- ============================================================== -->
<thead> <table id="episodes" class="table table-striped" style="width:100%">
<tr> <thead>
<th></th> <tr>
<th>Episode</th> <th></th>
<th>Title</th> <th>Episode</th>
<th>Existing Subtitles</th> <th>Title</th>
<th>Missing Subtitles</th> <th>Existing Subtitles</th>
<th>Manual Search</th> <th>Missing Subtitles</th>
<th>Manual Upload</th> <th>Manual Search</th>
</tr> <th>Manual Upload</th>
</thead> </tr>
</table> </thead>
</div> </table>
</div>
<div id="manualSearchModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document"> <div id="manualSearchModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-content"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-header"> <div class="modal-content">
<h5 class="modal-title"><span id="series_title_span"></span></h5><br> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <h5 class="modal-title"><span id="series_title_span"></span></h5><br>
<span aria-hidden="true">&times;</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button> <span aria-hidden="true">&times;</span>
</div> </button>
<div class="modal-body"> </div>
<h6>Episode path is: <span id="episode_path_span" class="badge badge-secondary"></span> <div class="modal-body">
<h6>Episode path is: <span id="episode_path_span" class="badge badge-secondary"></span>
<br>Scenename is: <span id="episode_scenename_span" class="badge badge-secondary"></span></h6> <br>Scenename is: <span id="episode_scenename_span" class="badge badge-secondary"></span></h6>
<div class="container-fluid"> <div class="container-fluid">
<table id="search_result" class="table table-striped"> <table id="search_result" class="table table-striped">
<thead> <thead>
<tr> <tr>
<th style="text-align: left;">Score:</th> <th style="text-align: left;">Score:</th>
<th style="text-align: left;">Lang.:</th> <th style="text-align: left;">Lang.:</th>
<th style="text-align: left;">HI:</th> <th style="text-align: left;">HI:</th>
<th style="text-align: left;">Provider:</th> <th style="text-align: left;">Provider:</th>
<th style="text-align: left;">Matching:</th> <th style="text-align: left;">Matching:</th>
<th style="text-align: left;">Releases:</th> <th style="text-align: left;">Releases:</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
</table> </table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div> </div>
</div> </div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</div> </div>
</div> </div>
</div>
<div id="uploadModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document"> <div id="uploadModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-content"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-header"> <div class="modal-content">
<h5 class="modal-title"><span id="upload_series_title_span"></span></h5><br> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <h5 class="modal-title"><span id="upload_series_title_span"></span></h5><br>
<span aria-hidden="true">&times;</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button> <span aria-hidden="true">&times;</span>
</div> </button>
</div>
<form class="form" name="upload_form" id="upload_form">
<div class="modal-body"> <div class="modal-body">
<form class="form" name="upload_form" id="upload_form" method="post" enctype="multipart/form-data"> <div class="container-fluid">
<div class="container-fluid"> <div class="row">
<div class="row"> <div class="col-sm-2 text-right">
<div class="col-sm-2 text-right"> Language
Language
</div>
<div class="form-group col-sm-8 pl-sm-0">
<select class="custom-select" id="manual_language_select" name="language"></select>
</div>
</div> </div>
<div class="row"> <div class="form-group col-sm-8 pl-sm-0">
<div class="col-sm-2 text-right"> <select class="custom-select" id="manual_language_select" name="language"></select>
Forced </div>
</div> </div>
<div class="form-group col-sm-8 pl-sm-0"> <div class="row">
<div class="custom-control custom-checkbox pl-sm-0"> <div class="col-sm-2 text-right">
<input type="checkbox" class="custom-control-input" id="forced_checkbox" name="forced"> Forced
<label class="custom-control-label" for="forced_checkbox">test</label>
</div>
</div>
</div> </div>
<div class="row"> <div class="form-group col-sm-8 pl-sm-0">
<div class="col-sm-2 text-right"> <div class="custom-control custom-checkbox pl-sm-0">
File <input type="checkbox" class="custom-control-input" id="forced_checkbox" name="forced">
<label class="custom-control-label" for="forced_checkbox">test</label>
</div> </div>
<div class="form-group col-sm-7 pl-sm-0"> </div>
<div class="custom-file"> </div>
<input type="file" class="custom-file-input" id="upload" name="upload"> <div class="row">
<label class="custom-file-label" for="upload">Choose file</label> <div class="col-sm-2 text-right">
</div> File
</div>
<div class="form-group col-sm-7 pl-sm-0">
<div class="custom-file">
<input type="file" class="custom-file-input" id="upload" name="upload">
<label class="custom-file-label" for="upload">Choose file</label>
</div> </div>
</div> </div>
</div> </div>
</form> </div>
<input type="hidden" id="upload_episodePath" name="episodePath" value="" />
<input type="hidden" id="upload_sceneName" name="sceneName" value="" />
<input type="hidden" id="upload_sonarrSeriesId" name="sonarrSeriesId" value="" />
<input type="hidden" id="upload_sonarrEpisodeId" name="sonarrEpisodeId" value="" />
<input type="hidden" id="upload_title" name="title" value="" />
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" id="upload_save_button" class="btn btn-primary">Save</button> <button type="submit" id="upload_save_button" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div> </div>
</div> </form>
</div> </div>
</div> </div>
</div>
{% endblock body %} {% endblock body %}
{% block tail %} {% block tail %}
<script> <script>
// make the filename appear in upload file dialog once a file have been selected. // make the filename appear in upload file dialog once a file have been selected.
$(document).ready(function () { $(document).ready(function () {
document.querySelector('.custom-file-input').addEventListener('change',function(e){ document.querySelector('.custom-file-input').addEventListener('change',function(e){
var fileName = document.getElementById("upload").files[0].name; var fileName = document.getElementById("upload").files[0].name;
var nextSibling = e.target.nextElementSibling; var nextSibling = e.target.nextElementSibling;
nextSibling.innerText = fileName; nextSibling.innerText = fileName;
}); });
$.ajax({ $.ajax({
url: "{{ url_for('api.series') }}?id={{id}}" url: "{{ url_for('api.series') }}?id={{id}}"
}) })
.done(function( data ) { .done(function( data ) {
seriesDetails = data.data[0]; seriesDetails = data.data[0];
$(document).prop('title', seriesDetails['title'] + ' - Bazarr'); $(document).prop('title', seriesDetails['title'] + ' - Bazarr');
$('#seriesFanart').css('background-image', "url('{{ url_for('image_proxy', url='MediaCover/'+id+'/fanart.jpg') }}')"); $('#seriesFanart').css('background-image', "url('{{ url_for('image_proxy', url='MediaCover/'+id+'/fanart.jpg') }}')");
$('#seriesPoster').attr("src","{{ url_for('image_proxy', url='MediaCover/'+id+'/poster-250.jpg') }}"); $('#seriesPoster').attr("src","{{ url_for('image_proxy', url='MediaCover/'+id+'/poster-250.jpg') }}");
@ -232,207 +238,221 @@
$('#seriesHearingImpaired').text('Hearing-Impaired: '+seriesDetails['hearing_impaired']); $('#seriesHearingImpaired').text('Hearing-Impaired: '+seriesDetails['hearing_impaired']);
$('#seriesForced').text('Forced: '+seriesDetails['forced']); $('#seriesForced').text('Forced: '+seriesDetails['forced']);
$('#seriesDescription').text(seriesDetails['overview']); $('#seriesDescription').text(seriesDetails['overview']);
}); });
var table = $('#episodes').DataTable({ var table = $('#episodes').DataTable({
"processing": false, "processing": false,
"serverSide": true, "serverSide": true,
"searching": false, "searching": false,
"ordering": false, "ordering": false,
"lengthChange": false, "lengthChange": false,
"responsive": true, "responsive": true,
"pageLength": 250, "pageLength": 100,
"ajax": "{{ url_for('api.episodes') }}?id={{id}}", "ajax": "{{ url_for('api.episodes') }}?id={{id}}",
"columns": [ rowGroup: {
{"data": "monitored", dataSrc: function(data) {
"render": function (data, type, row) { return 'Season ' + data.season;
if (data === 'False') { }
return '<i class="far fa-bookmark" data-toggle="tooltip" data-placement="right" title="Episode unmonitored in Sonarr"></i>'; },
} else if (data === 'True') { "columns": [
return '<i class="fas fa-bookmark" data-toggle="tooltip" data-placement="right" title="Episode monitored in Sonarr"></i>'; {"data": "monitored",
} "render": function (data, type, row) {
} if (data === 'False') {
}, return '<i class="far fa-bookmark" data-toggle="tooltip" data-placement="right" title="Episode unmonitored in Sonarr"></i>';
{"data": "episode"}, } else if (data === 'True') {
{"data": "title"}, return '<i class="fas fa-bookmark" data-toggle="tooltip" data-placement="right" title="Episode monitored in Sonarr"></i>';
{"data": null, }
"render": function (data) { }
if (data.subtitles !== 'None') { },
var languages = ''; {"data": "episode"},
data.subtitles.forEach(appendFunc); {"data": "title"},
return languages; {"data": null,
} else { "render": function (data) {
return null; if (data.subtitles !== 'None') {
} var languages = '';
data.subtitles.forEach(appendFunc);
function appendFunc(value) { return languages;
if (value[1] === null) { } else {
languages = languages + '<span class="badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value[0].name + ((value[0].forced) ? ' forced':'') + '">' + value[0].code2 + ((value[0].forced) ? ':forced':'') + '</span> '; return null;
} else { }
languages = languages + '<a href="" class="remove_subtitles badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value[0].name + ((value[0].forced) ? ' forced':'') + '" data-episodePath="'+data.mapped_path+'" data-language="'+value[0].code3+'" data-subtitlesPath="'+value[1]+'" data-sonarrEpisodeId='+data.sonarrEpisodeId+'>' + value[0].code2 + ((value[0].forced) ? ':forced':'') + ' <i class="far fa-trash-alt"></i></a> ';
} function appendFunc(value) {
} if (value[1] === null) {
} languages = languages + '<span class="badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value[0].name + ((value[0].forced) ? ' forced':'') + '">' + value[0].code2 + ((value[0].forced) ? ':forced':'') + '</span> ';
}, } else {
{"data": null, languages = languages + '<a href="" class="remove_subtitles badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value[0].name + ((value[0].forced) ? ' forced':'') + '" data-episodePath="'+data.mapped_path+'" data-language="'+value[0].code3+'" data-subtitlesPath="'+value[1]+'" data-sonarrEpisodeId='+data.sonarrEpisodeId+'>' + value[0].code2 + ((value[0].forced) ? ':forced':'') + ' <i class="far fa-trash-alt"></i></a> ';
"render": function (data) {
if (data.missing_subtitles !== 'None') {
var languages = '';
data.missing_subtitles.forEach(appendFunc);
return languages;
} else {
return null;
}
function appendFunc(value) {
languages = languages + '<a href="" class="get_subtitle badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value.name + ((value.forced) ? ' forced':'') + '" data-episodepath="'+data.mapped_path+'" data-scenename="'+data.scene_name+'" data-title="'+data.title+'" data-language="'+value.code3+'" data-hi="'+seriesDetails.hearing_impaired+'" data-forced="'+value.forced+'" data-sonarrepisodeid='+data.sonarrEpisodeId+'>' + value.code2 + ((value.forced) ? ':forced':'') + ' <i class="fas fa-search"></i></a> ';
} }
}
},
{"data": null,
"render": function (data) {
return '<a href="" class="manual_search badge badge-secondary" data-season='+data.season+' data-episode='+data.episode+' data-episode_title="'+data.title+'" data-episodePath="'+data.mapped_path+'" data-sceneName="'+data.scene_name+'" data-language="'+data.desired_languages+'" data-sonarrEpisodeId='+data.sonarrEpisodeId+'><i class="fas fa-user"></i></a>';
} }
}, }
{"data": null, },
"render": function (data) { {"data": null,
return '<a href="" class="upload_subtitle badge badge-secondary" data-episodePath="'+data.path+'" data-sceneName"'+data.scene_name+'" data-sonarrEpisodeId="'+data.sonarrEpisodeId+'" data-season="'+data.season+'" data-episode="'+data.episode+'" data-episode_title="'+data.title+'"><i class="fas fa-cloud-upload-alt"></i></a>'; "render": function (data) {
if (data.missing_subtitles !== 'None') {
var languages = '';
data.missing_subtitles.forEach(appendFunc);
return languages;
} else {
return null;
}
function appendFunc(value) {
languages = languages + '<a href="" class="get_subtitle badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value.name + ((value.forced) ? ' forced':'') + '" data-episodepath="'+data.mapped_path+'" data-scenename="'+data.scene_name+'" data-title="'+data.title+'" data-language="'+value.code3+'" data-hi="'+seriesDetails.hearing_impaired+'" data-forced="'+value.forced+'" data-sonarrepisodeid='+data.sonarrEpisodeId+'>' + value.code2 + ((value.forced) ? ':forced':'') + ' <i class="fas fa-search"></i></a> ';
} }
} }
] },
}); {"data": null,
"render": function (data) {
$('#episodes').on('click', '.remove_subtitles', function(e){ if (data.desired_languages !== '[]') {
$(this).tooltip('hide'); return '<a href="" class="manual_search badge badge-secondary" data-season=' + data.season + ' data-episode=' + data.episode + ' data-episode_title="' + data.title + '" data-episodePath="' + data.mapped_path + '" data-sceneName="' + data.scene_name + '" data-language="' + data.desired_languages + '" data-sonarrEpisodeId=' + data.sonarrEpisodeId + '><i class="fas fa-user"></i></a>';
e.preventDefault();
const values = {
episodePath: $(this).attr("data-episodePath"),
language: $(this).attr("data-language"),
subtitlesPath: $(this).attr("data-subtitlesPath"),
sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrEpisodeId: $(this).attr("data-sonarrEpisodeId"),
tvdbid: seriesDetails['tvdbId']
};
var cell = $(this).closest('td');
$.ajax({
url: "{{ url_for('api.episodessubtitlesdelete') }}",
type: "DELETE",
dataType: "json",
data: values,
beforeSend: function() {
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 { } else {
console.log("Unable to delete subtitle."); return ''
} }
} }
}); },
}); {"data": null,
"render": function (data) {
$('#episodes').on('click', '.get_subtitle', function(e){ if (data.desired_languages !== '[]') {
$(this).tooltip('hide'); return '<a href="" class="upload_subtitle badge badge-secondary" data-episodePath="'+data.mapped_path+'" data-sceneName"'+data.scene_name+'" data-sonarrSeriesId="'+seriesDetails['sonarrSeriesId']+'" data-sonarrEpisodeId="'+data.sonarrEpisodeId+'" data-season="'+data.season+'" data-episode="'+data.episode+'" data-episode_title="'+data.title+'"><i class="fas fa-cloud-upload-alt"></i></a>';
e.preventDefault();
const values = {
episodePath: $(this).attr("data-episodepath"),
sceneName: $(this).attr("data-scenename"),
language: $(this).attr("data-language"),
hi: $(this).attr("data-hi"),
forced: $(this).attr("data-forced"),
sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrEpisodeId: $(this).attr('data-sonarrepisodeid'),
title: seriesDetails['title']
};
var cell = $(this).closest('td');
$.ajax({
url: "{{ url_for('api.episodessubtitlesdownload') }}",
type: "POST",
dataType: "json",
data: values,
beforeSend: function() {
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 { } else {
console.log("No subtitle found."); return ''
} }
} }
}); }
]
});
$('#episodes').on('click', '.remove_subtitles', function(e){
$(this).tooltip('hide');
e.preventDefault();
const values = {
episodePath: $(this).attr("data-episodePath"),
language: $(this).attr("data-language"),
subtitlesPath: $(this).attr("data-subtitlesPath"),
sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrEpisodeId: $(this).attr("data-sonarrEpisodeId"),
tvdbid: seriesDetails['tvdbId']
};
var cell = $(this).closest('td');
$.ajax({
url: "{{ url_for('api.episodessubtitlesdelete') }}",
type: "DELETE",
dataType: "json",
data: values,
beforeSend: function() {
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.");
}
}
}); });
});
$('#episodes').on('click', '.manual_search', function(e){
e.preventDefault(); $('#episodes').on('click', '.get_subtitle', function(e){
$("#series_title_span").html(seriesDetails['title'] + ' - ' + $(this).data("season") + 'x' + $(this).data("episode") + ' - ' + $(this).data("episode_title")); $(this).tooltip('hide');
$("#episode_path_span").html($(this).attr("data-episodePath")); e.preventDefault();
$("#episode_scenename_span").html($(this).attr("data-sceneName")); const values = {
episodePath: $(this).attr("data-episodepath"),
episodePath = $(this).attr("data-episodePath"); sceneName: $(this).attr("data-scenename"),
sceneName = $(this).attr("data-sceneName"); language: $(this).attr("data-language"),
language = $(this).attr("data-language"); hi: $(this).attr("data-hi"),
hi = seriesDetails['hearing_impaired']; forced: $(this).attr("data-forced"),
forced = seriesDetails['forced']; sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrSeriesId = seriesDetails['sonarrSeriesId']; sonarrEpisodeId: $(this).attr('data-sonarrepisodeid'),
sonarrEpisodeId = $(this).attr("data-sonarrEpisodeId"); title: seriesDetails['title']
var languages = Array.from(seriesDetails['languages']); };
var is_pb = languages.includes('pb'); var cell = $(this).closest('td');
var is_pt = languages.includes('pt'); $.ajax({
url: "{{ url_for('api.episodessubtitlesdownload') }}",
const values = { type: "POST",
episodePath: episodePath, dataType: "json",
sceneName: sceneName, data: values,
language: language, beforeSend: function() {
hi: hi, cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
forced: forced, },
sonarrSeriesId: sonarrSeriesId, complete: function(data) {
sonarrEpisodeId: sonarrEpisodeId, table.ajax.reload(null, false);
title: seriesDetails['title'] if (data['responseJSON']) {
}; console.log(data['responseJSON'][0]);
} else {
$('#search_result').DataTable( { console.log("No subtitle found.");
destroy: true, }
language: { }
zeroRecords: 'No Subtitles Found For This Episode' });
}, });
paging: true,
lengthChange: false, $('#episodes').on('click', '.manual_search', function(e){
pageLength: 5, e.preventDefault();
searching: false, $("#series_title_span").html(seriesDetails['title'] + ' - ' + $(this).data("season") + 'x' + $(this).data("episode") + ' - ' + $(this).data("episode_title"));
ordering: false, $("#episode_path_span").html($(this).attr("data-episodePath"));
processing: true, $("#episode_scenename_span").html($(this).attr("data-sceneName"));
serverSide: false,
ajax: { episodePath = $(this).attr("data-episodePath");
url: '{{ url_for('api.episodessubtitlesmanualsearch') }}', sceneName = $(this).attr("data-sceneName");
type: 'POST', language = $(this).attr("data-language");
data: values hi = seriesDetails['hearing_impaired'];
}, forced = seriesDetails['forced'];
columns: [ sonarrSeriesId = seriesDetails['sonarrSeriesId'];
{ data: 'score', sonarrEpisodeId = $(this).attr("data-sonarrEpisodeId");
var languages = Array.from(seriesDetails['languages']);
var is_pb = languages.includes('pb');
var is_pt = languages.includes('pt');
const values = {
episodePath: episodePath,
sceneName: sceneName,
language: language,
hi: hi,
forced: forced,
sonarrSeriesId: sonarrSeriesId,
sonarrEpisodeId: sonarrEpisodeId,
title: seriesDetails['title']
};
$('#search_result').DataTable( {
destroy: true,
language: {
zeroRecords: 'No Subtitles Found For This Episode',
processing: "Searching (possibly solving captcha)..."
},
paging: true,
lengthChange: false,
pageLength: 5,
searching: false,
ordering: false,
processing: true,
serverSide: false,
ajax: {
url: '{{ url_for('api.episodessubtitlesmanualsearch') }}',
type: 'POST',
data: values
},
columns: [
{ data: 'score',
render: function ( data ) { render: function ( data ) {
return data +'%'; return data +'%';
} }
}, },
{ data: null, { data: null,
render: function ( data ) { render: function ( data ) {
if ( data.language === "pt" && is_pb === true && is_pt === false) { if ( data.language === "pt" && is_pb === true && is_pt === false) {
return 'pb' return 'pb'
} else { } else {
return data.language return data.language
} }
} }
}, },
{ data: 'hearing_impaired' }, { data: 'hearing_impaired' },
{ data: null, { data: null,
render: function ( data ) { render: function ( data ) {
return '<a href="'+data.url+'" target="_blank">'+data.provider+'</a>'; return '<a href="'+data.url+'" target="_blank">'+data.provider+'</a>';
} }
}, },
{ data: null, { data: null,
render: function ( data ) { render: function ( data ) {
const array_matches = data.matches; const array_matches = data.matches;
const array_dont_matches = data.dont_matches; const array_dont_matches = data.dont_matches;
@ -448,9 +468,9 @@
} }
text += '</div></div></div>'; text += '</div></div></div>';
return text; return text;
} }
}, },
{ data: null, { data: null,
render: function ( data ) { render: function ( data ) {
const array_release_info = data.release_info; const array_release_info = data.release_info;
let i; let i;
@ -460,60 +480,103 @@
} }
text += '</div></div>'; text += '</div></div>';
return text; return text;
} }
}, },
{ data: null, { data: null,
render: function ( data ) { render: function ( data ) {
return '<a href="" class="manual_download badge badge-secondary" data-episodePath="'+episodePath+'" data-sceneName="'+sceneName+'" data-sonarrEpisodeId='+sonarrEpisodeId+' data-subtitle="'+data.subtitle+'" data-provider="'+data.provider+'" data-language="'+data.language+'" data-forced="'+forced+'"><i class="fas fa-download" style="margin-right:0px" ></i></a>'; return '<a href="" class="manual_download badge badge-secondary" data-episodePath="'+episodePath+'" data-sceneName="'+sceneName+'" data-sonarrEpisodeId='+sonarrEpisodeId+' data-subtitle="'+data.subtitle+'" data-provider="'+data.provider+'" data-language="'+data.language+'" data-forced="'+forced+'"><i class="fas fa-download" style="margin-right:0px" ></i></a>';
}
} }
] }
} ); ]
} );
$('#manualSearchModal') $('#manualSearchModal')
.modal({ .modal({
focus: false focus: false
}); });
});
$('#search_result').on('click', '.manual_download', function(e){
e.preventDefault();
const values = {
episodePath: $(this).attr("data-episodepath"),
sceneName: $(this).attr("data-scenename"),
language: $(this).attr("data-language"),
hi: seriesDetails['hearing_impaired'],
forced: $(this).attr("data-forced"),
provider: $(this).attr("data-provider"),
subtitle: $(this).attr("data-subtitle"),
sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrEpisodeId: $(this).attr('data-sonarrepisodeid'),
title: seriesDetails['title']
};
var cell = $(this).closest('td');
$.ajax({
url: "{{ url_for('api.episodessubtitlesmanualdownload') }}",
type: "POST",
dataType: "json",
data: values,
beforeSend: function() {
cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>');
},
complete: function(data) {
$('#episodes').DataTable().ajax.reload(null, false);
$('#manualSearchModal').modal('hide');
if (data['responseJSON']) {
console.log(data['responseJSON'][0]);
} else {
console.log("No subtitle downloaded.");
}
}
});
});
$('#episodes').on('click', '.upload_subtitle', function(e){
e.preventDefault();
$("#upload_series_title_span").html(seriesDetails['title'] + ' - ' + $(this).data("season") + 'x' + $(this).data("episode") + ' - ' + $(this).data("episode_title"));
$('#upload_episodePath').val($(this).data("episodepath"));
$('#upload_sceneName').val($(this).data("scenename"));
$('#upload_sonarrSeriesId').val($(this).data("sonarrseriesid"));
$('#upload_sonarrEpisodeId').val($(this).data("sonarrepisodeid"));
$('#upload_title').val($(this).data("episode_title"));
var languages = Array.from(seriesDetails['languages']);
var is_pb = languages.includes('pb');
var is_pt = languages.includes('pt');
$.each(languages, function (i, item) {
$('#manual_language_select').append($('<option>', {
value: item.code2,
text : item.name
}));
}); });
$('#episodes').on('click', '.upload_subtitle', function(e){ $('#uploadModal')
e.preventDefault();
$("#upload_series_title_span").html(seriesDetails['title'] + ' - ' + $(this).data("season") + 'x' + $(this).data("episode") + ' - ' + $(this).data("episode_title"));
var languages = Array.from(seriesDetails['languages']);
var is_pb = languages.includes('pb');
var is_pt = languages.includes('pt');
$.each(languages, function (i, item) {
$('#manual_language_select').append($('<option>', {
value: item.code2,
text : item.name
}));
});
/*
const values = {
episodePath: $(this).data("episodePath"),
sceneName: $(this).data("sceneName"),
language: seriesDetails['languages'],
forced: "valeur du checkbox (0 ou 1)",
hi: seriesDetails['hearing_impaired'],
sonarrSeriesId: seriesDetails['sonarrSeriesId'],
sonarrEpisodeId: $(this).data("sonarrEpisodeId"),
title: seriesDetails['title']
};
$.ajax({
url: "{{ url_for('api.episodessubtitlesupload') }}",
type: "POST",
dataType: "json",
data: values
});
*/
$('#uploadModal')
.modal({ .modal({
focus: false focus: false
}); });
});
$('#upload_form').on('submit', function(e){
e.preventDefault();
var formdata = new FormData(document.getElementById("upload_form"));
$.ajax({
url: "{{ url_for('api.episodessubtitlesupload') }}",
data: formdata,
processData: false,
contentType: false,
type: 'POST',
success: function(){
$('#episodes').DataTable().ajax.reload(null, false);
$('#uploadModal').modal('hide');
}
}); });
}); });
</script>
$('#uploadModal').on('hidden.bs.modal', function () {
$(this).find('form')[0].reset();
});
});
</script>
{% endblock tail %} {% endblock tail %}

Loading…
Cancel
Save