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):
|
def get(self):
|
||||||
episodeid = request.args.get('episodeid')
|
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)
|
(episodeid,), only_one=True)
|
||||||
try:
|
try:
|
||||||
all_subs = ast.literal_eval(episode_ext_subs['subtitles'])
|
all_subs = ast.literal_eval(episode_ext_subs['subtitles'])
|
||||||
|
@ -875,6 +875,7 @@ class EpisodesTools(Resource):
|
||||||
episode_external_subtitles.append({'language': subs[0],
|
episode_external_subtitles.append({'language': subs[0],
|
||||||
'path': path_mappings.path_replace(subs[1]),
|
'path': path_mappings.path_replace(subs[1]),
|
||||||
'filename': os.path.basename(subs[1]),
|
'filename': os.path.basename(subs[1]),
|
||||||
|
'season' : episode_ext_subs['season'],
|
||||||
'videopath': path_mappings.path_replace(episode_ext_subs['path'])})
|
'videopath': path_mappings.path_replace(episode_ext_subs['path'])})
|
||||||
|
|
||||||
return jsonify(data=episode_external_subtitles)
|
return jsonify(data=episode_external_subtitles)
|
||||||
|
@ -1912,6 +1913,46 @@ class SyncSubtitles(Resource):
|
||||||
|
|
||||||
return '', 200
|
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):
|
class SubMods(Resource):
|
||||||
@authenticate
|
@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(BlacklistMovieSubtitlesRemoveAll, '/blacklist_movie_subtitles_remove_all')
|
||||||
|
|
||||||
api.add_resource(SyncSubtitles, '/sync_subtitles')
|
api.add_resource(SyncSubtitles, '/sync_subtitles')
|
||||||
|
api.add_resource(SyncAllSubtitles, '/sync_all_subtitles')
|
||||||
api.add_resource(SubMods, '/sub_mods')
|
api.add_resource(SubMods, '/sub_mods')
|
||||||
api.add_resource(SubTranslate, '/sub_translate')
|
api.add_resource(SubTranslate, '/sub_translate')
|
||||||
|
|
||||||
api.add_resource(BrowseBazarrFS, '/browse_bazarr_filesystem')
|
api.add_resource(BrowseBazarrFS, '/browse_bazarr_filesystem')
|
||||||
api.add_resource(BrowseSonarrFS, '/browse_sonarr_filesystem')
|
api.add_resource(BrowseSonarrFS, '/browse_sonarr_filesystem')
|
||||||
api.add_resource(BrowseRadarrFS, '/browse_radarr_filesystem')
|
api.add_resource(BrowseRadarrFS, '/browse_radarr_filesystem')
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
padding: .4rem !important;
|
padding: .4rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table tr {
|
||||||
|
cursor: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-light {
|
.btn-light {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid #ced4da;
|
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><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>
|
<div class="align-bottom text-themecolor small text-center">Search</div>
|
||||||
</button>
|
</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>
|
</div>
|
||||||
{% endblock bcleft %}
|
{% endblock bcleft %}
|
||||||
|
|
||||||
|
@ -382,6 +386,80 @@
|
||||||
</div>
|
</div>
|
||||||
</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 id="episodeSubtitleModColorModal" class="modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
@ -620,14 +698,14 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (collapsed) {
|
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 {
|
} 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/>')
|
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)
|
.attr('data-name', group)
|
||||||
.toggleClass('collapsed', collapsed);
|
.toggleClass('collapsed', collapsed);
|
||||||
}
|
}
|
||||||
|
@ -748,8 +826,8 @@
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#episodes').on('click', 'tr.dtrg-start', function () {
|
$('#episodes').on('click', '.chevron', function () {
|
||||||
var name = $(this).data('name');
|
var name = $(this).closest('tr').data('name');
|
||||||
collapsedGroups[name] = !collapsedGroups[name];
|
collapsedGroups[name] = !collapsedGroups[name];
|
||||||
table.draw(false);
|
table.draw(false);
|
||||||
});
|
});
|
||||||
|
@ -1057,6 +1135,47 @@
|
||||||
DONE: 3
|
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) {
|
$('#mass_upload_button').on('click', function (e) {
|
||||||
e.preventDefault();
|
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) {
|
$('#episode_tools_result').on('click', '.subtitles_sync', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const values = {
|
const values = {
|
||||||
|
|
Loading…
Reference in a new issue