{% extends '_main.html' %} {% block title %}Movie - Bazarr{% endblock %} {% block page_head %} <style> #movieFanart { background-repeat: no-repeat; background-size: cover; background-position: top center; box-sizing: initial; margin-left: -32px; margin-top: -5px; padding: 2em; } #movieDetails { padding: 30px; background: rgba(0, 0, 0, 0.7); color: white; margin: -32px; } #moviePoster { max-height: 250px; } h1 { color: white; } span { margin-right: 0.5em; } .badge { display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; } </style> {% endblock page_head %} {% block bcleft %} <div class=""> <button class="btn btn-outline" id="scan_button"> <div><i class="fas fa-sync align-top text-themecolor text-center font-20" aria-hidden="true"></i></div> <div class="align-bottom text-themecolor small text-center">Scan Disk</div> </button> <button class="btn btn-outline" id="search_button"> <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="manual_button"> <div><i class="fas fa-user align-top text-themecolor text-center font-20" aria-hidden="true"></i></div> <div class="align-bottom text-themecolor small text-center">Manual</div> </button> <button class="btn btn-outline" id="upload_button"> <div><i class=" fas fa-cloud-upload-alt align-top text-themecolor text-center font-20" aria-hidden="true"></i></div> <div class="align-bottom text-themecolor small text-center">Upload</div> </button> <button class="btn btn-outline" id="history_button"> <div><i class="fas fa-history align-top text-themecolor text-center font-20" aria-hidden="true"></i></div> <div class="align-bottom text-themecolor small text-center">History</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 %} {% block bcright %} <div class="d-flex m-t-5 justify-content-end"> <button class="btn btn-outline" id="edit_button"> <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 Movie</div> </button> </div> {% endblock bcright %} {% block body %} <div class="container-fluid" id="movieFanart"> <div class="row justify-content-md-center" id="movieDetails"> <div class="col-sm-auto" id="moviePosterColumn"> <img id="moviePoster" src=""> </div> <div class="col" id="movieDetailsColumn"> <div class="container-fluid"> <div class="row"> <h1><span id="movieTitle"></span></h1> <i class="far fa-clone" id="moviealternativeTitles" data-toggle="tooltip" data-placement="right" title="None" data-html="true"></i> </div> <div class="row"> <h5><span id="movieAudioLanguage" class="badge badge-secondary"></span></h5> <h5><span id="movieMappedPath" data-toggle="tooltip" data-placement="right" title="None" class="badge badge-secondary"></span></h5> <h5><span id="movieTags" class="badge badge-secondary" data-toggle="tooltip" data-placement="right" title="None" data-html="true">Tags</span></h5> </div> <div class="row"> <h5><span id="movieSubtitlesLanguages"></span></h5> </div> <div class="row"> <h5><span id="movieHearingImpaired" class="badge badge-secondary"></span></h5> <h5><span id="movieForced" class="badge badge-secondary"></span></h5> </div> <div class="row"> <span id="movieDescription"></span> </div> </div> </div> </div> </div> <!-- Bread crumb and right sidebar toggle --> <!-- ============================================================== --> <table id="movieSubtitles" class="table table-striped" style="width:100%"> <thead> <tr> <th>Subtitles Path</th> <th>Language(s)</th> <th></th> </tr> </thead> </table> <br> <h5 style="font-weight: 500;">Missing Subtitles</h5> <span id="missingSubtitles"></span> <div id="manualSearchModal" class="modal" tabindex="-1" role="dialog" data-backdrop="static"> <div class="modal-dialog modal-xl" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title"><span id="movie_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"> <h6>Movie path is: <span id="movie_path_span" class="badge badge-secondary"></span> <br>Scenename is: <span id="movie_scenename_span" class="badge badge-secondary"></span></h6> <div class="container-fluid" style="padding:0px;"> <table id="search_result" class="table table-striped" style="width:100%"> <thead> <tr> <th style="text-align: left;">Score:</th> <th></th> <th style="text-align: left;">Provider:</th> <th style="text-align: left;">Matching:</th> <th style="text-align: left;">Releases:</th> <th style="text-align: left;">Uploader:</th> <th></th> </tr> </thead> </table> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> </div> </div> </div> </div> <div id="uploadModal" class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title"><span id="upload_movie_title_span"></span></h5><br> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form class="form" name="upload_form" id="upload_form"> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col-sm-2 text-right"> Language </div> <div class="form-group col-sm-8 pl-sm-0"> <select class="selectpicker" id="manual_language_select" name="language"></select> </div> </div> <div class="row"> <div class="col-sm-2 text-right"> Forced </div> <div class="form-group col-sm-1 pl-sm-0"> <label class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input" id="forced_checkbox" name="forced"> <span class="custom-control-label" for="forced_checkbox"></span> </label> </div> </div> <div class="row"> <div class="col-sm-2 text-right"> 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> <input type="hidden" id="upload_moviePath" name="moviePath" value="" /> <input type="hidden" id="upload_sceneName" name="sceneName" value="" /> <input type="hidden" id="upload_radarrId" name="radarrId" value="" /> <input type="hidden" id="upload_title" name="title" value="" /> <input type="hidden" id="upload_audioLanguage" name="audioLanguage" value="" /> </div> <div class="modal-footer"> <span id="upload_save_button_span"><button type="submit" id="upload_save_button" class="btn btn-info">Save</button></span> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> </div> </form> </div> </div> </div> <div id="editModal" class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title"><span id="edit_movie_title_span"></span></h5><br> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form class="form" name="edit_form" id="edit_form"> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col-sm-3 text-right"> Audio Language </div> <div class="form-group col-sm-8 pl-sm-0"> <span id="edit_audio_language_span"></span> </div> </div> <div class="row"> <div class="col-sm-3 text-right"> Subtitles Language(s) </div> <div class="form-group col-sm-8 pl-sm-0"> <select class="selectpicker" id="edit_languages_select" name="languages" multiple data-live-search="true"></select> </div> </div> <div class="row"> <div class="col-sm-3 text-right"> Hearing-Impaired </div> <div class="form-group col-sm-1 pl-sm-0"> <label class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input" id="hi_checkbox" name="hi"> <span class="custom-control-label" for="hi_checkbox"></span> </label> </div> </div> <div class="row"> <div class="col-sm-3 text-right"> Forced </div> <div class="form-group col-sm-8 pl-sm-0"> <select class="selectpicker" id="edit_forced_select" name="forced"> <option value="False">False</option> <option value="True">True</option> <option value="Both">Both</option> </select> </div> </div> </div> <input type="hidden" id="edit_radarrId" name="radarrId" value="" /> </div> <div class="modal-footer"> <button type="submit" id="edit_save_button" class="btn btn-info"><span id="edit_save_button_span">Save</span></button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> </div> </form> </div> </div> </div> <div id="movieHistoryModal" 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="movie_history_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"> <table id="movie_history_result" class="table table-striped" style="width:100%"> <thead> <tr> <th></th> <th style="text-align: left;">Language.:</th> <th style="text-align: left;">Provider:</th> <th style="text-align: left;">Score:</th> <th style="text-align: left;">Date:</th> <th style="text-align: left;">Actions:</th> </tr> </thead> </table> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> <div id="movieToolsModal" 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="movie_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"> <table id="movie_tools_result" class="table table-striped" style="width:100%"> <thead> <tr> <th style="text-align: left;">Language:</th> <th style="text-align: left;">Filename:</th> <th style="text-align: left;">Tools:</th> </tr> </thead> </table> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> <div id="movieSubtitleModColorModal" class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Chose Color</h5><br> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form class="form" name="subtitles_mod_color_form" id="subtitles_mod_color_form"> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col text-right"> <b>Color Name</b> </div> <div class="form-group col"> <select class="form-control selectpicker" id="subzero_color_name"> <option value="white">White</option> <option value="light-grey">Light Grey</option> <option value="red">Red</option> <option value="green">Green</option> <option value="yellow">Yellow</option> <option value="blue">Blue</option> <option value="magenta">Magenta</option> <option value="cyan">Cyan</option> <option value="black">Black</option> <option value="dark-red">Dark Red</option> <option value="dark-green">Dark Green</option> <option value="dark-yellow">Dark Yellow</option> <option value="dark-blue">Dark Blue</option> <option value="dark-magenta">Dark Magenta</option> <option value="dark-cyan">Dark Cyan</option> <option value="dark-grey">Dark Grey</option> </select> </div> <input type="hidden" id="subzero_color_data_language" value="" /> <input type="hidden" id="subzero_color_data_path" value="" /> </div> </div> </div> <div class="modal-footer"> <span id="subtitles_mod_color_save_button_span"><button type="submit" id="subtitles_mod_color_save_button" class="btn btn-info">Save</button></span> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </form> </div> </div> </div> <div id="movieSubtitleModFpsModal" class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Convert frame rate of subtitle</h5><br> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form class="form" name="subtitles_mod_fps_form" id="subtitles_mod_fps_form"> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col text-right"> <b>From frame rate</b> </div> <div class="form-group col"> <input type="text" class="form-control" list="default_frame_rates" id="subzero_fps_from" minlength="2" maxlength="6" required autocomplete> <datalist id="default_frame_rates"> <option value="23.976">23.976</option> <option value="24">24</option> <option value="25">25</option> <option value="29.97">29.97</option> <option value="30">30</option> </datalist> </div> </div> <div class="row"> <div class="col text-right"> <b>To frame rate</b> </div> <div class="form-group col"> <input type="text" class="form-control" list="default_frame_rates" id="subzero_fps_to" minlength="2" maxlength="6" required autocomplete> </div> </div> <input type="hidden" id="subzero_fps_data_language" value="" /> <input type="hidden" id="subzero_fps_data_path" value="" /> </div> </div> <div class="modal-footer"> <span id="subtitles_mod_fps_save_button_span"><button type="submit" id="subtitles_mod_fps_save_button" class="btn btn-info">Save</button></span> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </form> </div> </div> </div> <div id="movieSubtitleModOffsetModal" class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Adjust All Times</h5><br> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <form class="form" name="subtitles_mod_offset_form" id="subtitles_mod_offset_form"> <div class="modal-body"> <div class="container-fluid"> <div class="row"> <div class="col text-right"> <b>Hour:min:sec:ms</b> </div> <div class="form-group col"> <input type="text" class="form-control" id="subzero_offset_time" minlength="12" maxlength="12" required value="00:00:00.100"> </div> </div> <div class="row justify-content-center"> <div class="form-group col-sm-7"> <label class="custom-control custom-radio"> <input type="radio" class="custom-control-input" id="subzero_offset_show_earlier" name="subzero_offset_dir" checked value="0"> <span class="custom-control-label" for="subzero_offset_show_earlier">Show earlier</span> </label> </div> </div> <div class="row justify-content-center"> <div class="form-group col-sm-7"> <label class="custom-control custom-radio"> <input type="radio" class="custom-control-input" id="subzero_offset_show_later" name="subzero_offset_dir" value="1"> <span class="custom-control-label" for="subzero_offset_show_later">Show later</span> </label> </div> </div> <input type="hidden" id="subzero_offset_data_language" value="" /> <input type="hidden" id="subzero_offset_data_path" value="" /> </div> </div> <div class="modal-footer"> <span id="subtitles_mod_offset_save_button_span"><button type="submit" id="subtitles_mod_offset_save_button" class="btn btn-info">Save</button></span> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </form> </div> </div> </div> {% endblock body %} {% block tail %} <script> // make the filename appear in upload file dialog once a file have been selected. $(document).ready(function () { document.querySelector('.custom-file-input').addEventListener('change',function(e){ var fileName = document.getElementById("upload").files[0].name; var nextSibling = e.target.nextElementSibling; nextSibling.innerText = fileName; }); $('#movies_nav').addClass("active"); movieDetailsRefresh(); getLanguages(); getEnabledLanguages(); //test $('#movieSubtitles').on('click', '.remove_subtitles', function(e){ $(this).tooltip('dispose'); e.preventDefault(); const values = { moviePath: movieDetails['mapped_path'], language: $(this).data("language"), forced: $(this).data("forced"), hi: $(this).data("hi"), subtitlesPath: $(this).data("subtitlespath"), radarrId: movieDetails['radarrId'], tmdbid: movieDetails['tmdbId'] }; var cell = $(this).parent(); $.ajax({ url: "{{ url_for('api.moviesubtitlesdelete') }}", 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>'); } }); }); $(document).on('click', '.get_subtitle', function(e){ $(this).tooltip('dispose'); e.preventDefault(); const values = { moviePath: movieDetails['mapped_path'], sceneName: movieDetails['sceneName'], language: $(this).attr("data-language"), hi: movieDetails['hearing_impaired'], forced:$(this).attr("data-forced"), radarrId: movieDetails['radarrId'], title: movieDetails['title'] }; var button = $(this).closest('button' + ''); $.ajax({ url: "{{ url_for('api.moviesubtitlesdownload') }}", type: "POST", dataType: "json", data: values, beforeSend: function() { button.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); } }); }); $('#manual_button').on('click', function(e){ e.preventDefault(); $("#movie_title_span").html(movieDetails['title']); $("#movie_path_span").html(movieDetails['mapped_path']); $("#movie_scenename_span").html(movieDetails['sceneName']); moviePath = movieDetails['mapped_path']; sceneName = movieDetails['sceneName']; language = movieDetails['desired_languages']; hi = movieDetails['hearing_impaired']; forced = movieDetails['forced']; radarrId = movieDetails['radarrId']; var languages = Array.from(movieDetails['languages']); var is_pb = languages.includes('pb'); var is_pt = languages.includes('pt'); const values = { moviePath: moviePath, sceneName: sceneName, language: language, hi: hi, forced: forced, radarrId: radarrId, title: movieDetails['title'] }; $('#search_result').DataTable( { destroy: true, language: { zeroRecords: 'No Subtitles Found For This Movie', processing: "Searching{% if settings.general.anti_captcha_provider != 'None' %} (possibly solving captcha){% endif %}...", search: "Filter:" }, paging: true, lengthChange: true, pageLength: {{ settings.general.page_size_manual_search }}, lengthMenu: [ 5, 10, 15, 20, 25 ], searching: true, scrollX: true, ordering: false, processing: true, serverSide: false, ajax: { url: '{{ url_for('api.moviesubtitlesmanualsearch') }}', type: 'POST', data: values }, columns: [ { data: 'score', render: function ( data ) { return data +'%'; } }, { data: null, render: function ( data ) { let lng = data.language; if ( data.language === "pt" && is_pb === true && is_pt === false) { lng = 'pb' } let text = '<div class="badge badge-secondary" style="margin:1px;">' + lng.toUpperCase() + '</div>'; if (data.forced == "True") { text += '<div class="badge badge-dark" style="margin:1px;">Forced</div>'; } if (data.hearing_impaired == "True") { text += '<div class="badge badge-dark" style="margin:1px;">HI</div>'; } return text; } }, { data: null, render: function ( data ) { return '<a href="'+data.url+'" target="_blank">'+data.provider+'</a>'; } }, { data: null, searchable: false, render: function ( data ) { const array_matches = data.matches; const array_dont_matches = data.dont_matches; let i; let text = '<div class="dropdown"><div class="btn-group dropdown"><button class="btn btn-secondary btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="margin:1px;"><i class="fas fa-check-circle" style="color: green;"></i> '+array_matches.length+'</button><div class="dropdown-menu" aria-labelledby="dropdownMenuButton">'; for (i = 0; i < array_matches.length; i++) { text += '<a class="dropdown-item disabled" href="#">' + array_matches[i] + '</a>'; } text += '</div>'; text += '<div class="dropdown"><button class="btn btn-secondary btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="margin:1px;"><i class="fas fa-times-circle" style="color: red;"></i> '+array_dont_matches.length+'</button><div class="dropdown-menu" aria-labelledby="dropdownMenuButton">'; for (i = 0; i < array_dont_matches.length; i++) { text += '<a class="dropdown-item disabled" href="#">' + array_dont_matches[i] + '</a>'; } text += '</div></div></div>'; return text; } }, { data: null, render: function ( data ) { const array_release_info = data.release_info; let i; let text; if (array_release_info.length == 1) { text = '<div style="font-size: 75%;font-weight: 400;">' + array_release_info[0] + '</div>'; } else { text = '<div class="dropdown"><button class="btn btn-secondary btn-sm dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="\tfas fa-comment-dots"></i> ' + array_release_info.length + '</button><div class="dropdown-menu" aria-labelledby="dropdownMenuButton">'; for (i = 0; i < array_release_info.length; i++) { text += '<a class="dropdown-item" href="#">' + array_release_info[i] + '</a>'; } text += '</div></div>'; } return text; } }, { data: 'uploader', render: function ( data ) { return '<div class="badge badge-secondary">' + data + '</div>'; } }, { data: null, searchable: false, render: function ( data ) { return '<a href="" class="manual_download badge badge-secondary" data-moviePath="'+moviePath+'" data-sceneName="'+sceneName+'" 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') .modal({ focus: false }); }); $('#search_result').on('click', '.manual_download', function(e){ e.preventDefault(); const values = { moviePath: $(this).attr("data-moviepath"), sceneName: $(this).attr("data-scenename"), language: $(this).attr("data-language"), hi: movieDetails['hearing_impaired'], forced: $(this).attr("data-forced"), provider: $(this).attr("data-provider"), subtitle: $(this).attr("data-subtitle"), radarrId: movieDetails['radarrId'], title: movieDetails['title'] }; var cell = $(this).parent(); $.ajax({ url: "{{ url_for('api.moviesubtitlesmanualdownload') }}", 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) { $('#manualSearchModal').modal('hide'); } }); }); $('#upload_button').on('click', function(e){ e.preventDefault(); $("#upload_movie_title_span").html(movieDetails['title']); $('#upload_moviePath').val(movieDetails['mapped_path']); $('#upload_sceneName').val(movieDetails['sceneName']); $('#upload_radarrId').val(movieDetails['radarrId']); $('#upload_title').val(movieDetails['title']); $('#upload_audioLanguage').val(movieDetails['audio_language']['name']); $('#manual_language_select').empty(); $.each(enabledLanguages, function (i, item) { $('#manual_language_select').append('<option value="'+item.code2+'">'+item.name+'</option>'); }); $("#manual_language_select").selectpicker("refresh"); $('#uploadModal') .modal({ focus: false }); }); $('#upload_form').on('submit', function(e){ e.preventDefault(); var formdata = new FormData(document.getElementById("upload_form")); $.ajax({ url: "{{ url_for('api.moviesubtitlesupload') }}", data: formdata, processData: false, contentType: false, type: 'POST', beforeSend: function () { $('#upload_save_button').html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function(){ $('#uploadModal').modal('hide'); } }); }); $('#scan_button').on('click', function(e){ e.preventDefault(); $.ajax({ url: "{{ url_for('api.moviescandisk', radarrid=id) }}", type: 'GET', beforeSend: function() { $('#scan_button').find("i").addClass('fa-spin'); }, complete: function() { $('#scan_button').find("i").removeClass('fa-spin'); } }); }); $('#search_button').on('click', function(e){ e.preventDefault(); $.ajax({ url: "{{ url_for('api.moviesearchmissing', radarrid=id) }}", type: 'GET', beforeSend: function() { $('#search_button').find("i").addClass('fa-spin'); }, complete: function() { $('#search_button').find("i").removeClass('fa-spin'); } }); }); $('#edit_button').on('click', function(e){ e.preventDefault(); $("#edit_movie_title_span").html(movieDetails['title']); $("#edit_audio_language_span").text(movieDetails['audio_language']['name']); $('#edit_radarrId').val(movieDetails['radarrId']); $('#edit_languages_select').empty(); if ('{{settings.general.single_language}}' === 'True') { $('#edit_languages_select').selectpicker({maxOptions: 1}); $('#edit_languages_select').append('<option value="None">None</option>'); } $.each(enabledLanguages, function (i, item) { $('#edit_languages_select').append('<option value="'+item.code2+'">'+item.name+'</option>'); }); $("#edit_languages_select").selectpicker("refresh"); var selected_languages = Array(); $.each(Array.from(movieDetails['languages']), function (i, item) { selected_languages.push(item.code2); }); $('#edit_languages_select').selectpicker('val', selected_languages); $('#hi_checkbox').prop('checked', (movieDetails['hearing_impaired'] === 'True')); $('#edit_forced_select').val(movieDetails['forced']).change(); $('#editModal') .modal({ focus: false }); }); $('#edit_form').on('submit', function(e){ e.preventDefault(); var formdata = new FormData(document.getElementById("edit_form")); $.ajax({ url: "{{ url_for('api.movies') }}?radarrid={{id}}", data: formdata, processData: false, contentType: false, type: 'POST', beforeSend: function () { $('#edit_save_button_span').html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, success: function(){ movieDetailsRefresh(); $('#editModal').modal('hide'); $('#edit_save_button_span').html('Save'); } }); }); $('#uploadModal').on('hidden.bs.modal', function () { $(this).find('form').trigger('reset'); $('.custom-file-label').text('Choose file') $('#upload_save_button_span').html('<button type="submit" id="upload_save_button" class="btn btn-info">Save</button>'); }); events.on('event', function(event) { var event_json = JSON.parse(event); if (event_json.type === 'movie') { if (event_json.movie === {{id}}) { movieDetailsRefresh(); } } if (event_json.type === 'movieBlacklist' || event_json.type === 'movieHistory') { if ($('#movie_history_result').DataTable().ajax.json()) { $('#movie_history_result').DataTable().ajax.reload(resetPaging = false); $('[data-toggle="tooltip"]').tooltip({html: true}); } } }); $('#history_button').on('click', function(e){ $(this).tooltip('dispose'); e.preventDefault(); $("#movie_history_title_span").html(movieDetails['title']); radarrId = movieDetails['radarrId']; $('#movie_history_result').DataTable( { destroy: true, language: { zeroRecords: 'No History Records Found For This Movie' }, paging: true, lengthChange: false, pageLength: 5, searching: true, ordering: false, scrollX: true, processing: true, serverSide: false, ajax: { url: '{{ url_for( 'api.moviehistory' )}}?radarrid=' + radarrId }, columns: [ { data: 'action', render: function(data) { if (data === 0) {return "<i class='fas fa-trash' title='Subtitle file has been erased.' data-toggle='tooltip' data-placement='right'></i>";} else if (data === 1) {return "<i class='fas fa-download' title='Subtitle file has been downloaded.' data-toggle='tooltip' data-placement='right'></i>";} else if (data === 2) {return "<i class='fas fa-user' title='Subtitle file has been manually downloaded.' data-toggle='tooltip' data-placement='right'></i>";} else if (data === 3) {return "<i class='fas fa-recycle' title='Subtitle file has been upgraded.' data-toggle='tooltip' data-placement='right'></i>";} else if (data === 4) {return "<i class='fas fa-cloud-upload-alt' title='Subtitle file has been manually uploaded.' data-toggle='tooltip' data-placement='right'></i>";} else if (data === 5) {return "<i class='fas fa-clock' title='Subtitle file has been synced.' data-toggle='tooltip' data-placement='right'></i>";} } }, { data: 'language', render: function (value) { if (value) { var language_string = ''; if (value.hi) { language_string = ' HI'; } else if (value.forced) { language_string = ' forced'; } return value.name + language_string; } else { return '<i>undefined</i>' } } }, { data: 'provider' }, { data: 'score'}, { data: 'timestamp'}, { data: null, render: function (data) { if (data.subs_id && data.subtitles_path && !data.blacklisted) { return '<a href="" class="blacklist_subtitles badge badge-secondary" data-toggle="tooltip" data-placement="right" title="Blacklist this subtitles" data-radarrid="' + data.radarrId + '" data-language="' + data.language.code2 + '" data-forced="' + data.language.forced + '" data-hi="' + data.language.hi + '" data-provider="' + data.provider + '" data-subs_id="' + data.subs_id + '" data-video_path="' + data.video_path + '" data-subtitles_path="' + data.subtitles_path + '"><i class="far fa-file-excel"></i></a>'; } else { return null; } } } ] } ); $('#movieHistoryModal') .modal({ focus: false }); }); $('#movie_history_result').on('click', '.blacklist_subtitles', function (e) { $(this).tooltip('dispose'); e.preventDefault(); const values = { radarr_id: $(this).attr('data-radarrid'), provider: $(this).attr('data-provider'), subs_id: $(this).attr('data-subs_id'), language: $(this).attr('data-language'), forced: $(this).attr('data-forced'), hi: $(this).attr('data-hi'), video_path: $(this).attr('data-video_path'), subtitles_path: $(this).attr('data-subtitles_path') }; var cell = $(this).parent(); $.ajax({ url: "{{ url_for('api.blacklistmoviesubtitlesadd') }}", 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>'); } }); }); $('#tools_button').on('click', function (e) { $(this).tooltip('dispose'); e.preventDefault(); $("#movie_tools_title_span").html(movieDetails['title']); radarrId = movieDetails['radarrId']; $('#movie_tools_result').DataTable({ destroy: true, language: { zeroRecords: 'No External Subtitles Found For This Movie' }, paging: true, lengthChange: false, pageLength: 5, searching: true, ordering: false, scrollX: true, processing: false, serverSide: false, ajax: { url: '{{ url_for( 'api.movietools' )}}?movieid=' + radarrId }, columns: [ {data: 'language.name'}, {data: 'filename'}, { data: null, "render": function (data) { var tools = ''; tools += '<a href="" class="subtitles_sync badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-videopath="' + data.videopath + '" data-toggle="tooltip" data-placement="right" title="Sync"><i class="far fa-play-circle"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "remove_HI" data-toggle="tooltip" data-placement="right" title="Remove HI-tags"><i class="fa fa-deaf"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "remove_tags" data-toggle="tooltip" data-placement="right" title="Remove style tags"><i class="fa fa-code"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "OCR_fixes" data-toggle="tooltip" data-placement="right" title="OCR Fixes"><i class="fa fa-image"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "common" data-toggle="tooltip" data-placement="right" title="Common Fixes"><i class="fas fa-magic"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "fix_uppercase" data-toggle="tooltip" data-placement="right" title="Fix Uppercase"><i class="fa fa-text-height"></i></a> '; tools += '<a href="" class="subtitles_mod badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-mod = "reverse_rtl" data-toggle="tooltip" data-placement="right" title="Reverse RTL"><i class="fa fa-exchange-alt"></i></a> '; tools += '<a href="" class="subtitles_mod_color badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-toggle="tooltip" data-placement="right" title = "Adds color to your subtitles"><i class="fa fa-paint-brush"></i></a> '; tools += '<a href="" class="subtitles_mod_fps badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-toggle="tooltip" data-placement="right" title = "Change Frame Rate"><i class="fa fa-film"></i></a> '; tools += '<a href="" class="subtitles_mod_offset badge badge-secondary" data-language="' + data.language.code3 + '" data-path="' + data.path + '" data-toggle="tooltip" data-placement="right" title = "Adjust all times (show earlier/later)"><i class="fa fa-clock"></i></a> '; return tools; } } ] }); $('#movieToolsModal') .modal({ focus: false }); }); $('#movie_tools_result').on('click', '.subtitles_sync', function (e) { e.preventDefault(); const values = { language: $(this).attr("data-language"), subtitlesPath: $(this).attr("data-path"), videoPath: $(this).attr("data-videopath"), mediaType: 'movies' }; var cell = $(this).parent() ; $.ajax({ url: "{{ url_for('api.syncsubtitles') }}", type: "POST", dataType: "json", data: values, beforeSend: function () { $('.subtitles_sync').tooltip('hide') cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function (data) { $('#movieToolsModal').modal('hide'); } }); }); $('#movie_tools_result').on('click', '.subtitles_mod', function (e) { e.preventDefault(); const values = { language: $(this).attr("data-language"), subtitlesPath: $(this).attr("data-path"), mod: $(this).attr("data-mod"), }; var cell = $(this).parent(); $.ajax({ url: "{{ url_for('api.submods') }}", type: "POST", dataType: "json", data: values, beforeSend: function () { $('.subtitles_mod').tooltip('hide') cell.html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function () { $('#movieToolsModal').modal('hide'); } }); }); $('#movie_tools_result').on('click', '.subtitles_mod_color', function (e) { e.preventDefault(); $('#subzero_color_data_language').val($(this).attr("data-language")) $('#subzero_color_data_path').val($(this).attr("data-path")) $('#movieToolsModal').modal('hide'); $('#movieSubtitleModColorModal') .modal({ focus: false }); }); $('#subtitles_mod_color_form').on('submit', function (e) { e.preventDefault(); const values = { language: $('#subzero_color_data_language').val(), subtitlesPath: $('#subzero_color_data_path').val(), mod: 'color(name=' + $('#subzero_color_name').val() + ')', }; $.ajax({ url: "{{ url_for('api.submods') }}", type: "POST", dataType: "json", data: values, beforeSend: function () { $('#subtitles_mod_color_save_button').html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function () { $('#movieSubtitleModColorModal').modal('hide'); } }); }); $('#movieSubtitleModColorModal').on('hidden.bs.modal', function (e) { $('#subtitles_mod_color_save_button_span').html('<button type="submit" id="subtitles_mod_color_save_button" class="btn btn-info">Save</button>'); }); $('#movie_tools_result').on('click', '.subtitles_mod_fps', function (e) { e.preventDefault(); $('#subzero_fps_data_language').val($(this).attr("data-language")) $('#subzero_fps_data_path').val($(this).attr("data-path")) $('#movieToolsModal').modal('hide'); $('#movieSubtitleModFpsModal') .modal({ focus: false }); }); $('#subtitles_mod_fps_form').on('submit', function (e) { e.preventDefault(); const values = { language: $('#subzero_fps_data_language').val(), subtitlesPath: $('#subzero_fps_data_path').val(), mod: 'change_FPS(from=' + $('#subzero_fps_from').val() + ',to=' + $('#subzero_fps_to').val() + ')', }; $.ajax({ url: "{{ url_for('api.submods') }}", type: "POST", dataType: "json", data: values, beforeSend: function () { $('#subtitles_mod_fps_save_button').html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function () { $('#movieSubtitleModFpsModal').modal('hide'); } }); }); $('#movieSubtitleModFpsModal').on('hidden.bs.modal', function (e) { $('#subtitles_mod_fps_save_button_span').html('<button type="submit" id="subtitles_mod_fps_save_button" class="btn btn-info">Save</button>'); }); $('#movie_tools_result').on('click', '.subtitles_mod_offset', function (e) { e.preventDefault(); $('#subzero_offset_data_language').val($(this).attr("data-language")) $('#subzero_offset_data_path').val($(this).attr("data-path")) $('#movieToolsModal').modal('hide'); $('#movieSubtitleModOffsetModal') .modal({ focus: false }); }); $('#subtitles_mod_offset_form').on('submit', function (e) { e.preventDefault(); let times = $('#subzero_offset_time').val().match(/(\d\d):(\d\d):(\d\d)[\.,:](\d\d\d)/); if (times == null || times.length != 5) return false; let sign = ''; if ($('input[name="subzero_offset_dir"]:checked').val() == "0") { sign = '-'; } const values = { language: $('#subzero_offset_data_language').val(), subtitlesPath: $('#subzero_offset_data_path').val(), mod: 'shift_offset(h='+sign+times[1]+',m='+sign+times[2]+',s='+sign+times[3]+',ms='+sign+times[4]+')', }; $.ajax({ url: "{{ url_for('api.submods') }}", type: "POST", dataType: "json", data: values, beforeSend: function () { $('#subtitles_mod_offset_save_button').html('<div class="spinner-border spinner-border-sm" role="status"><span class="sr-only">Loading...</span></div>'); }, complete: function () { $('#movieSubtitleModOffsetModal').modal('hide'); } }); }); $('#movieSubtitleModOffsetModal').on('hidden.bs.modal', function (e) { $('#subtitles_mod_offset_save_button_span').html('<button type="submit" id="subtitles_mod_offset_save_button" class="btn btn-info">Save</button>'); }); }); function movieDetailsRefresh() { $.ajax({ url: "{{ url_for('api.movies') }}?radarrid={{id}}" }).done(function (data) { movieDetails = data.data[0]; $(document).prop('title', movieDetails['title'] + ' - Bazarr'); $('#movieFanart').css('background-image', "url('{{ url_for('image_proxy_movies', url='MediaCover/'+id+'/fanart.jpg') }}')"); $('#moviePoster').attr("src", "{{ url_for('image_proxy_movies', url='MediaCover/'+id+'/poster-250.jpg') }}"); $('#movieTitle').text(movieDetails['title']); if (movieDetails['alternativeTitles'].length > 0) { $('#moviealternativeTitles').attr("data-original-title", "<b>Alternative Titles:</b><br>" + movieDetails['alternativeTitles']); } else { $('#moviealternativeTitles').hide(); } if (movieDetails['tags'].length > 0) { $('#movieTags').attr("data-original-title", "<b>Tags:</b><br>" + movieDetails['tags']); } else { $('#movieTags').hide(); } $('#movieAudioLanguage').text(movieDetails['audio_language']['name']); $('#movieMappedPath').text(movieDetails['mapped_path']); $('#movieMappedPath').attr("data-original-title", movieDetails['mapped_path']); var languages = ''; if (movieDetails['languages'] && movieDetails['languages'] !== 'None') { movieDetails['languages'].forEach(appendFunc); } function appendFunc(value) { languages += '<span class="badge badge-secondary" data-toggle="tooltip" data-placement="right" title="' + value.name + '">' + value.code2 + '</span> '; } $('#movieSubtitlesLanguages').html(languages); $('#movieHearingImpaired').text('Hearing-Impaired: ' + movieDetails['hearing_impaired']); $('#movieForced').text('Forced: ' + movieDetails['forced']); $('#movieDescription').text(movieDetails['overview']); var missing_languages = ''; if (movieDetails['missing_subtitles'] !== 'None') { movieDetails['missing_subtitles'].forEach(missingAppendFunc); } function missingAppendFunc(value) { if (value.forced) { missing_languages += '<button class="get_subtitle btn btn-secondary btn-sm" type="button" data-toggle="tooltip" data-placement="right" data-original-title="' + value.name + '" data-language="' + value.code3 + '" data-forced=' + value.forced + '>' + value.code2 + ':forced <i class="fas fa-search"></i></button> '; } else if (value.hi) { missing_languages += '<button class="get_subtitle btn btn-secondary btn-sm" type="button" data-toggle="tooltip" data-placement="right" data-original-title="' + value.name + '" data-language="' + value.code3 + '" data-forced=' + value.forced + '>' + value.code2 + ':HI <i class="fas fa-search"></i></button> '; } else { missing_languages += '<button class="get_subtitle btn btn-secondary btn-sm" type="button" data-toggle="tooltip" data-placement="right" data-original-title="' + value.name + '" data-language="' + value.code3 + '" data-forced=' + value.forced + '>' + value.code2 + ' <i class="fas fa-search"></i></button> '; } } $('#missingSubtitles').html(missing_languages); $('[data-toggle="tooltip"]').tooltip({html: true}); if (movieDetails['desired_languages'] == '[]') { $('#search_button').hide(); $('#manual_button').hide(); $('#upload_button').hide(); } else { $('#search_button').show(); $('#manual_button').show(); $('#upload_button').show(); } var table = $('#movieSubtitles').DataTable({ destroy: true, language: { zeroRecords: 'No Subtitles Found For This Movie' }, "searching": false, "ordering": false, "paging": false, "info": false, "lengthChange": false, "responsive": true, "data" : movieDetails['subtitles'], "columns" : [ { "data" : null, "render": function(data) { if (data['path']) { return data['path']; } else { return 'Video File Subtitles Track'; } } }, { "data" : null, "render": function(data) { if (data['forced']) { return '<span class="badge badge-secondary">' + data['name'] + ' forced</span>'; } else if (data['hi']) { return '<span class="badge badge-secondary">' + data['name'] + ' HI</span>'; } else { return '<span class="badge badge-secondary">' + data['name'] + '</span>'; } } }, { "data" : null, "render": function(data) { if (data['path']) { return '<button type="button" class="remove_subtitles close" aria-label="Close" data-toggle="tooltip" data-placement="right" title="Delete Subtitles File" data-language='+data['code3']+' data-forced='+data['forced']+' data-hi='+data['hi']+' data-subtitlesPath="'+data['path']+'"><span aria-hidden="true">×</span></button>'; } else { return ''; } } } ] }); }); } function getLanguages() { $.ajax({ url: "{{ url_for('api.languages') }}?enabled=false", success:function(data) { availableLanguages = data; } }); } function getEnabledLanguages() { $.ajax({ url: "{{ url_for('api.languages') }}?enabled=true", success:function(data) { enabledLanguages = data; } }); } </script> {% endblock tail %}