mirror of
https://github.com/morpheus65535/bazarr
synced 2025-01-03 13:35:18 +00:00
Added sync subtitles button for whole show and for whole season
This commit is contained in:
parent
1a915b15f7
commit
300a037cbe
3 changed files with 211 additions and 6 deletions
|
@ -856,7 +856,7 @@ class EpisodesTools(Resource):
|
|||
def get(self):
|
||||
episodeid = request.args.get('episodeid')
|
||||
|
||||
episode_ext_subs = database.execute("SELECT path, subtitles FROM table_episodes WHERE sonarrEpisodeId=?",
|
||||
episode_ext_subs = database.execute("SELECT path, subtitles, season FROM table_episodes WHERE sonarrEpisodeId=?",
|
||||
(episodeid,), only_one=True)
|
||||
try:
|
||||
all_subs = ast.literal_eval(episode_ext_subs['subtitles'])
|
||||
|
@ -875,6 +875,7 @@ class EpisodesTools(Resource):
|
|||
episode_external_subtitles.append({'language': subs[0],
|
||||
'path': path_mappings.path_replace(subs[1]),
|
||||
'filename': os.path.basename(subs[1]),
|
||||
'season' : episode_ext_subs['season'],
|
||||
'videopath': path_mappings.path_replace(episode_ext_subs['path'])})
|
||||
|
||||
return jsonify(data=episode_external_subtitles)
|
||||
|
@ -1912,6 +1913,46 @@ class SyncSubtitles(Resource):
|
|||
|
||||
return '', 200
|
||||
|
||||
class SyncAllSubtitles(Resource):
|
||||
@authenticate
|
||||
def post(self):
|
||||
language = request.form.get('language')
|
||||
media_type = request.form.get('mediaType')
|
||||
season = request.form.get('season')
|
||||
show = request.form.get('show')
|
||||
if media_type == 'series' and show:
|
||||
if season:
|
||||
episode_metadata = database.execute("SELECT sonarrSeriesId, sonarrEpisodeId, path, subtitles FROM table_episodes"
|
||||
" WHERE sonarrSeriesId = ?1 AND season = ?2", (show,season,))
|
||||
else:
|
||||
episode_metadata = database.execute("SELECT sonarrSeriesId, sonarrEpisodeId, path, subtitles FROM table_episodes"
|
||||
" WHERE sonarrSeriesId = ?1", (show,))
|
||||
|
||||
ret = ''
|
||||
#ret += json.dumps(episode_metadata)
|
||||
for episode in episode_metadata:
|
||||
#ret += str(episode['sonarrSeriesId']) +" "+str(episode['sonarrEpisodeId'])
|
||||
if episode['subtitles']:
|
||||
episode.update({"subtitles": ast.literal_eval(episode['subtitles'])})
|
||||
for subs in episode['subtitles']:
|
||||
lang = subs[0].split(':')
|
||||
if lang[0] == "en":
|
||||
video_path = path_mappings.path_replace(episode['path'])
|
||||
subtitles_path = path_mappings.path_replace(subs[1])
|
||||
language = language
|
||||
media_type = media_type
|
||||
sonarr_series_id = episode['sonarrSeriesId']
|
||||
sonarr_episode_id = episode['sonarrEpisodeId']
|
||||
if video_path and subtitles_path and language and media_type and sonarr_series_id and sonarr_episode_id:
|
||||
logging.info('Batch-syncing subtitle '+subtitles_path+' for series '+str(sonarr_series_id) + ' episode ' + str(sonarr_episode_id))
|
||||
subsync.sync(video_path=video_path, srt_path=subtitles_path,
|
||||
srt_lang=language, media_type=media_type, sonarr_series_id=sonarr_series_id,
|
||||
sonarr_episode_id=sonarr_episode_id)
|
||||
|
||||
#ret+= " " + json.dumps(video_path) + " " + json.dumps(subtitles_path) + " " + json.dumps(language) + " " + json.dumps(media_type) + " " + json.dumps(sonarr_series_id) + " " + json.dumps(sonarr_episode_id)
|
||||
logging.info('Finished batch-sync')
|
||||
return ret, 200
|
||||
|
||||
|
||||
class SubMods(Resource):
|
||||
@authenticate
|
||||
|
@ -2078,9 +2119,11 @@ api.add_resource(BlacklistMovieSubtitlesRemove, '/blacklist_movie_subtitles_remo
|
|||
api.add_resource(BlacklistMovieSubtitlesRemoveAll, '/blacklist_movie_subtitles_remove_all')
|
||||
|
||||
api.add_resource(SyncSubtitles, '/sync_subtitles')
|
||||
api.add_resource(SyncAllSubtitles, '/sync_all_subtitles')
|
||||
api.add_resource(SubMods, '/sub_mods')
|
||||
api.add_resource(SubTranslate, '/sub_translate')
|
||||
|
||||
api.add_resource(BrowseBazarrFS, '/browse_bazarr_filesystem')
|
||||
api.add_resource(BrowseSonarrFS, '/browse_sonarr_filesystem')
|
||||
api.add_resource(BrowseRadarrFS, '/browse_radarr_filesystem')
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@
|
|||
padding: .4rem !important;
|
||||
}
|
||||
|
||||
.table tr {
|
||||
cursor: auto !important;
|
||||
}
|
||||
|
||||
.btn-light {
|
||||
background-color: white;
|
||||
border: 1px solid #ced4da;
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
<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 class="btn btn-outline" id="tools_button">
|
||||
<div><i class="fa fa-briefcase align-top text-themecolor text-center font-20" aria-hidden="true"></i></div>
|
||||
<div class="align-bottom text-themecolor small text-center">Tools</div>
|
||||
</button>
|
||||
</div>
|
||||
{% endblock bcleft %}
|
||||
|
||||
|
@ -382,6 +386,80 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="seasonToolsModal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><span id="season_tools_title_span"></span></h5><br>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 text-right">
|
||||
Language
|
||||
</div>
|
||||
<div class="form-group col-sm-8 pl-sm-0">
|
||||
<span id="season_tools_audio_language_span"></span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 text-right">
|
||||
Tools
|
||||
</div>
|
||||
<div class="form-group col-sm-8 pl-sm-0">
|
||||
<span id="season_tools_span"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="showToolsModal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><span id="show_tools_title_span"></span></h5><br>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 text-right">
|
||||
Language
|
||||
</div>
|
||||
<div class="form-group col-sm-8 pl-sm-0">
|
||||
<span id="show_tools_audio_language_span"></span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-sm-3 text-right">
|
||||
Tools
|
||||
</div>
|
||||
<div class="form-group col-sm-8 pl-sm-0">
|
||||
<span id="show_tools_span"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="episodeSubtitleModColorModal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
|
@ -620,14 +698,14 @@
|
|||
});
|
||||
|
||||
if (collapsed) {
|
||||
var chevron_icon = '<i class="fas fa-chevron-circle-right"></i>';
|
||||
var chevron_icon = '<i style="cursor: pointer;" class="chevron fas fa-chevron-circle-up"></i>';
|
||||
} else {
|
||||
var chevron_icon = '<i class="fas fa-chevron-circle-down"></i>';
|
||||
var chevron_icon = '<i style="cursor: pointer;" class="chevron fas fa-chevron-circle-down"></i>';
|
||||
}
|
||||
|
||||
|
||||
return $('<tr/>')
|
||||
.append('<td colspan=' + rows.columns()[0].length + '>Season ' + group + ' ' + chevron_icon + '</td>')
|
||||
.append('<td colspan=' + ( rows.columns()[0].length - 1 ) + '>Season ' + group + ' ' + chevron_icon + '</td><td><a href="" class="season_tools badge badge-secondary" data-season="' + group + '"><i class="fa fa-briefcase"></i></a></td>')
|
||||
.attr('data-name', group)
|
||||
.toggleClass('collapsed', collapsed);
|
||||
}
|
||||
|
@ -748,8 +826,8 @@
|
|||
]
|
||||
});
|
||||
|
||||
$('#episodes').on('click', 'tr.dtrg-start', function () {
|
||||
var name = $(this).data('name');
|
||||
$('#episodes').on('click', '.chevron', function () {
|
||||
var name = $(this).closest('tr').data('name');
|
||||
collapsedGroups[name] = !collapsedGroups[name];
|
||||
table.draw(false);
|
||||
});
|
||||
|
@ -1057,6 +1135,47 @@
|
|||
DONE: 3
|
||||
}
|
||||
|
||||
$('#tools_button').on('click', function (e) {
|
||||
$(this).tooltip('dispose');
|
||||
e.preventDefault();
|
||||
|
||||
$("#show_tools_title_span").html(seriesDetails['title']);
|
||||
|
||||
$("#show_tools_audio_language_span").html(seriesDetails['audio_language'][0].name);
|
||||
$("#show_tools_span").html('<a href="" class="subtitles_sync_all_show badge badge-secondary" data-language="' + seriesDetails['audio_language'][0].code3 + '" data-placement="right" data-toggle="tooltip" id="sync_button_show" title="Sync whole show"><i class="far fa-play-circle"></i></a>');
|
||||
|
||||
$('#showToolsModal')
|
||||
.modal({
|
||||
focus: false
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
$('#show_tools_span').on('click', '.subtitles_sync_all_show', function (e) {
|
||||
e.preventDefault();
|
||||
const values = {
|
||||
language: $(this).attr("data-language"),
|
||||
show: seriesDetails['sonarrSeriesId'],
|
||||
mediaType: 'series'
|
||||
};
|
||||
var cell = $(this).parent()
|
||||
;
|
||||
$.ajax({
|
||||
url: "{{ url_for('api.syncallsubtitles') }}",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: values,
|
||||
beforeSend: function () {
|
||||
$('#sync_button_show').find("i").addClass('fa-spin');
|
||||
},
|
||||
complete: function () {
|
||||
$('#sync_button_show').find("i").removeClass('fa-spin');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#mass_upload_button').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -1635,6 +1754,45 @@
|
|||
});
|
||||
});
|
||||
|
||||
$('#episodes').on('click', '.season_tools', function (e) {
|
||||
$(this).tooltip('dispose');
|
||||
e.preventDefault();
|
||||
|
||||
$("#season_tools_title_span").html(seriesDetails['title'] + ' - Season ' + $(this).data("season"));
|
||||
|
||||
$("#season_tools_audio_language_span").html(seriesDetails['audio_language'][0].name);
|
||||
$("#season_tools_span").html('<a href="" class="subtitles_sync_all badge badge-secondary" data-language="' + seriesDetails['audio_language'][0].code3 + '" data-season="' + $(this).data("season") + '" data-placement="right" data-toggle="tooltip" id="sync_button_season" title="Sync whole season"><i class="far fa-play-circle"></i></a>');
|
||||
|
||||
$('#seasonToolsModal')
|
||||
.modal({
|
||||
focus: false
|
||||
});
|
||||
});
|
||||
|
||||
$('#season_tools_span').on('click', '.subtitles_sync_all', function (e) {
|
||||
e.preventDefault();
|
||||
var season = $(this).attr("data-season");
|
||||
const values = {
|
||||
language: $(this).attr("data-language"),
|
||||
show: seriesDetails['sonarrSeriesId'],
|
||||
season: season,
|
||||
mediaType: 'series'
|
||||
};
|
||||
var cell = $(this).parent();
|
||||
$.ajax({
|
||||
url: "{{ url_for('api.syncallsubtitles') }}",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: values,
|
||||
beforeSend: function () {
|
||||
$('#'+'sync_button_season').find("i").addClass('fa-spin');
|
||||
},
|
||||
complete: function () {
|
||||
$('#'+'sync_button_season').find("i").removeClass('fa-spin');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#episode_tools_result').on('click', '.subtitles_sync', function (e) {
|
||||
e.preventDefault();
|
||||
const values = {
|
||||
|
|
Loading…
Reference in a new issue