Merge branch 'development' into python3

# Conflicts:
#	bazarr/main.py
#	views/movie.tpl
pull/684/head
Louis Vézina 5 years ago
commit 985219f9af

@ -53,7 +53,7 @@ def track_event(category=None, action=None, label=None):
try: try:
tracker.track_event(event, session, visitor) tracker.track_event(event, session, visitor)
tracker.track_pageview(page, session, visitor) # tracker.track_pageview(page, session, visitor) ## Commented because we were having too much hits on GA.
except: except:
pass pass
else: else:

@ -47,7 +47,8 @@ from beaker.middleware import SessionMiddleware
from cork import Cork from cork import Cork
from bottle import route, template, static_file, request, redirect, response, HTTPError, app, hook from bottle import route, template, static_file, request, redirect, response, HTTPError, app, hook
from datetime import timedelta from datetime import timedelta
from get_languages import load_language_in_db, language_from_alpha3 from get_languages import load_language_in_db, language_from_alpha3, language_from_alpha2, alpha2_from_alpha3
from get_providers import get_providers, get_providers_auth, list_throttled_providers from get_providers import get_providers, get_providers_auth, list_throttled_providers
from get_series import * from get_series import *
from get_episodes import * from get_episodes import *
@ -1738,7 +1739,7 @@ def remove_subtitles():
try: try:
os.remove(subtitlesPath) os.remove(subtitlesPath)
result = language_from_alpha3(language) + " subtitles deleted from disk." result = language_from_alpha3(language) + " subtitles deleted from disk."
history_log(0, sonarrSeriesId, sonarrEpisodeId, result) history_log(0, sonarrSeriesId, sonarrEpisodeId, result, language=alpha2_from_alpha3(language))
except OSError as e: except OSError as e:
logging.exception('BAZARR cannot delete subtitles file: ' + subtitlesPath) logging.exception('BAZARR cannot delete subtitles file: ' + subtitlesPath)
store_subtitles(path_replace_reverse(episodePath), episodePath) store_subtitles(path_replace_reverse(episodePath), episodePath)
@ -1756,7 +1757,7 @@ def remove_subtitles_movie():
try: try:
os.remove(subtitlesPath) os.remove(subtitlesPath)
result = language_from_alpha3(language) + " subtitles deleted from disk." result = language_from_alpha3(language) + " subtitles deleted from disk."
history_log_movie(0, radarrId, result) history_log_movie(0, radarrId, result, language=alpha2_from_alpha3(language))
except OSError as e: except OSError as e:
logging.exception('BAZARR cannot delete subtitles file: ' + subtitlesPath) logging.exception('BAZARR cannot delete subtitles file: ' + subtitlesPath)
store_subtitles_movie(path_replace_reverse_movie(moviePath), moviePath) store_subtitles_movie(path_replace_reverse_movie(moviePath), moviePath)
@ -2136,6 +2137,85 @@ def running_tasks_list():
return dict(tasks=running_tasks) return dict(tasks=running_tasks)
@route(base_url + 'episode_history/<no:int>')
@custom_auth_basic(check_credentials)
def episode_history(no):
authorize()
episode_history = database.execute("SELECT action, timestamp, language, provider, score FROM table_history "
"WHERE sonarrEpisodeId=? ORDER BY timestamp DESC", (no,))
for item in episode_history:
if item['action'] == 0:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"erased.' data-inverted='' data-position='top left'><i class='ui trash icon'></i></div>"
elif item['action'] == 1:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"downloaded.' data-inverted='' data-position='top left'><i class='ui download " \
"icon'></i></div>"
elif item['action'] == 2:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"manually downloaded.' data-inverted='' data-position='top left'><i class='ui user " \
"icon'></i></div>"
elif item['action'] == 3:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"upgraded.' data-inverted='' data-position='top left'><i class='ui recycle " \
"icon'></i></div>"
elif item['action'] == 4:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"manually uploaded.' data-inverted='' data-position='top left'><i class='ui cloud " \
"upload icon'></i></div>"
item['timestamp'] = "<div data-tooltip='" + \
time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(item['timestamp'])) + "'>" + \
pretty.date(datetime.fromtimestamp(item['timestamp'])) + "</div>"
if item['language']:
item['language'] = language_from_alpha2(item['language'])
else:
item['language'] = "<i>undefined</i>"
if item['score']:
item['score'] = str(round((int(item['score']) * 100 / 360), 2)) + "%"
return dict(data=episode_history)
@route(base_url + 'movie_history/<no:int>')
@custom_auth_basic(check_credentials)
def movie_history(no):
authorize()
movie_history = database.execute("SELECT action, timestamp, language, provider, score FROM table_history_movie "
"WHERE radarrId=? ORDER BY timestamp DESC", (no,))
for item in movie_history:
if item['action'] == 0:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"erased.' data-inverted='' data-position='top left'><i class='ui trash icon'></i></div>"
elif item['action'] == 1:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"downloaded.' data-inverted='' data-position='top left'><i class='ui download " \
"icon'></i></div>"
elif item['action'] == 2:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"manually downloaded.' data-inverted='' data-position='top left'><i class='ui user " \
"icon'></i></div>"
elif item['action'] == 3:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"upgraded.' data-inverted='' data-position='top left'><i class='ui recycle " \
"icon'></i></div>"
elif item['action'] == 4:
item['action'] = "<div class ='ui inverted basic compact icon' data-tooltip='Subtitle file has been " \
"manually uploaded.' data-inverted='' data-position='top left'><i class='ui cloud " \
"upload icon'></i></div>"
item['timestamp'] = "<div data-tooltip='" + \
time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(item['timestamp'])) + "'>" + \
pretty.date(datetime.fromtimestamp(item['timestamp'])) + "</div>"
if item['language']:
item['language'] = language_from_alpha2(item['language'])
else:
item['language'] = "<i>undefined</i>"
if item['score']:
item['score'] = str(round((int(item['score']) * 100 / 120), 2)) + '%'
return dict(data=movie_history)
# Mute DeprecationWarning # Mute DeprecationWarning
warnings.simplefilter("ignore", DeprecationWarning) warnings.simplefilter("ignore", DeprecationWarning)
server = CherryPyWSGIServer((str(settings.general.ip), (int(args.port) if args.port else int(settings.general.port))), app) server = CherryPyWSGIServer((str(settings.general.ip), (int(args.port) if args.port else int(settings.general.port))), app)

@ -217,7 +217,7 @@
% if episode['scene_name'] is not None: % if episode['scene_name'] is not None:
<span data-tooltip="Scenename is: {{episode['scene_name']}}" data-inverted='' data-position="top left"><i class="info circle icon"></i></span> <span data-tooltip="Scenename is: {{episode['scene_name']}}" data-inverted='' data-position="top left"><i class="info circle icon"></i></span>
% end % end
<span data-tooltip="Path is: {{episode['path']}}" data-inverted='' data-position="top left">{{episode['title']}}</span> <span data-tooltip="Path is: {{episode['path']}}" data-inverted='' data-position="top left"><a data-series_title="{{details['title']}}" data-season="{{episode['season']}}" data-episode="{{episode['episode']}}" data-episode_title="{{episode['title']}}" data-sonarrEpisodeId="{{episode['sonarrEpisodeId']}}" class="episode_history">{{episode['title']}}</a></span>
</td> </td>
<td> <td>
%if episode['subtitles'] is not None: %if episode['subtitles'] is not None:
@ -379,6 +379,29 @@
</div> </div>
</div> </div>
<div class="episode_dialog ui modal">
<i class="close icon"></i>
<div class="header">
<span id="series_title_span"></span> - <span id="season"></span>x<span id="episode"></span> - <span id="episode_title"></span>
</div>
<div class="scrolling content">
<table id="episode_result" class="display" 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>
</tr>
</thead>
</table>
</div>
<div class="actions">
<button class="ui cancel button" >Cancel</button>
</div>
</div>
<div class="search_dialog ui modal"> <div class="search_dialog ui modal">
<i class="close icon"></i> <i class="close icon"></i>
<div class="header"> <div class="header">
@ -531,7 +554,7 @@
}); });
}); });
$('a:not(.manual_search, .manual_upload), .menu .item, button:not(#config, .cancel, #search_missing_subtitles)').on('click', function(){ $('a:not(.manual_search, .manual_upload, .episode_history), .menu .item, button:not(#config, .cancel, #search_missing_subtitles)').on('click', function(){
$('#loader').addClass('active'); $('#loader').addClass('active');
}); });
@ -564,6 +587,51 @@
.modal('show'); .modal('show');
}); });
$('.episode_history').on('click', function(){
$("#series_title_span").html($(this).data("series_title"));
$("#season").html($(this).data("season"));
$("#episode").html($(this).data("episode"));
$("#episode_title").html($(this).data("episode_title"));
sonarrEpisodeId = $(this).attr("data-sonarrEpisodeId");
$('#episode_result').DataTable( {
destroy: true,
language: {
loadingRecords: '<br><div class="ui active inverted dimmer" style="width: 95%;"><div class="ui centered inline loader"></div></div><br>',
zeroRecords: 'No History Records Found For This Episode'
},
paging: true,
lengthChange: false,
pageLength: 5,
searching: true,
ordering: true,
processing: false,
serverSide: false,
ajax: {
url: '{{base_url}}episode_history/' + sonarrEpisodeId
},
drawCallback: function(settings) {
$('.inline.dropdown').dropdown();
$('.ui.accordion').accordion();
},
columns: [
{ data: 'action'},
{ data: 'language' },
{ data: 'provider' },
{ data: 'score'},
{ data: 'timestamp' }
]
} );
$('.episode_dialog')
.modal({
centered: false,
autofocus: false
})
.modal('show');
});
$('.manual_search').on('click', function(){ $('.manual_search').on('click', function(){
$("#series_title_span").html($(this).data("series_title")); $("#series_title_span").html($(this).data("series_title"));
$("#season").html($(this).data("season")); $("#season").html($(this).data("season"));

@ -41,6 +41,7 @@
} }
#fondblanc { #fondblanc {
background-color: #ffffff; background-color: #ffffff;
color: #000000;
opacity: 0.9; opacity: 0.9;
border-radius: 1px; border-radius: 1px;
box-shadow: 0 0 3px 3px #ffffff; box-shadow: 0 0 3px 3px #ffffff;
@ -160,6 +161,12 @@
</div> </div>
<div id="fondblanc" class="ui container"> <div id="fondblanc" class="ui container">
<div class="ui top attached tabular menu">
<a id="subtitles_tab" class="tabs item active" data-tab="subtitles">Subtitles</a>
<a id="history_tab" class="tabs item" data-tab="history">History</a>
</div>
<div class="ui bottom attached tab active segment" data-tab="subtitles">
<div class="content">
<table class="ui very basic single line selectable table"> <table class="ui very basic single line selectable table">
<thead> <thead>
<tr> <tr>
@ -263,6 +270,23 @@
%> %>
</div> </div>
</div> </div>
<div class="ui bottom attached tab segment" data-tab="history">
<div class="content">
<table id="movie_result" class="display" 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>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div> </div>
<div class="config_dialog ui small modal"> <div class="config_dialog ui small modal">
@ -420,6 +444,9 @@
</html> </html>
<script> <script>
$('.menu .item')
.tab();
$('#scan_disk').on('click', function(){ $('#scan_disk').on('click', function(){
$('#loader_text').text("Scanning Disk For Existing Subtitles..."); $('#loader_text').text("Scanning Disk For Existing Subtitles...");
window.location = '{{base_url}}scan_disk_movie/{{no}}'; window.location = '{{base_url}}scan_disk_movie/{{no}}';
@ -486,7 +513,7 @@
}); });
}); });
$('a, .menu .item, button:not(#config, .cancel, .manual_search, .manual_upload, #search_missing_subtitles_movie)').on('click', function(){ $('a:not(.tabs), button:not(#config, .cancel, .manual_search, .manual_upload, #search_missing_subtitles_movie)').on('click', function(){
$('#loader').addClass('active'); $('#loader').addClass('active');
}); });
@ -519,6 +546,37 @@
.modal('show'); .modal('show');
}); });
$('#history_tab').on('click', function(){
$('#movie_result').DataTable( {
destroy: true,
language: {
loadingRecords: '<br><div class="ui active inverted dimmer" style="width: 95%;"><div class="ui centered inline loader"></div></div><br>',
zeroRecords: 'No History Records Found For This Movie'
},
paging: true,
lengthChange: false,
pageLength: 5,
searching: true,
ordering: true,
processing: false,
serverSide: false,
ajax: {
url: '{{base_url}}movie_history/{{no}}'
},
drawCallback: function(settings) {
$('.inline.dropdown').dropdown();
$('.ui.accordion').accordion();
},
columns: [
{ data: 'action'},
{ data: 'language' },
{ data: 'provider' },
{ data: 'score'},
{ data: 'timestamp' }
]
} );
});
$('.manual_search').on('click', function(){ $('.manual_search').on('click', function(){
$("#movie_title_span").html($(this).data("movie_title")); $("#movie_title_span").html($(this).data("movie_title"));
$("#movie_path_span").html($(this).attr("data-moviePath")); $("#movie_path_span").html($(this).attr("data-moviePath"));

Loading…
Cancel
Save