|
|
|
<!doctype html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<title>{% block title %}Bazarr{% endblock %}</title>
|
|
|
|
|
|
|
|
{% block head_meta %}
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
|
|
<meta name="mobile-web-app-capable" content="yes"/>
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
|
|
|
|
|
|
|
<link rel="apple-touch-icon" sizes="120x120" href="{{ url_for('static',filename='apple-touch-icon.png') }}">
|
|
|
|
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static',filename='favicon-32x32.png') }}">
|
|
|
|
<link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static',filename='favicon-16x16.png') }}">
|
|
|
|
<link rel="manifest" href="{{ url_for('static',filename='manifest.json') }}">
|
|
|
|
<link rel="mask-icon" href="{{ url_for('static',filename='safari-pinned-tab.svg') }}" color="#5bbad5">
|
|
|
|
<link rel="shortcut icon" href="{{ url_for('static',filename='favicon.ico') }}">
|
|
|
|
<meta name="msapplication-config" content="{{ url_for('static',filename='browserconfig.xml') }}">
|
|
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
|
|
|
|
{% endblock head_meta %}
|
|
|
|
|
|
|
|
{% block head_css %}
|
|
|
|
<link href="{{ url_for('static',filename='plugins/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
|
|
|
|
<!-- Custom CSS -->
|
|
|
|
<link href="{{ url_for('static',filename='css/style.css') }}" rel="stylesheet">
|
|
|
|
<!-- You can change the theme colors from here -->
|
|
|
|
<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/rowGroup.dataTables.min.css') }}">
|
|
|
|
<link rel="stylesheet" type="text/css"
|
|
|
|
href="{{ url_for('static',filename='datatables/responsive.dataTables.min.css') }}">
|
|
|
|
<link rel="stylesheet" type="text/css"
|
|
|
|
href="{{ url_for('static',filename='plugins/datatables.net-bs4/css/dataTables.bootstrap4.min.css') }}">
|
|
|
|
{% endblock head_css %}
|
|
|
|
|
|
|
|
{% block head %}
|
|
|
|
{% endblock head %}
|
|
|
|
|
|
|
|
{% block head_tail %}
|
|
|
|
{% endblock head_tail %}
|
|
|
|
|
|
|
|
</head>
|
|
|
|
<body class="fix-header fix-sidebar card-no-border">
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Preloader - style you can find in spinners.css -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div class="preloader">
|
|
|
|
<svg class="circular" viewBox="25 25 50 50">
|
|
|
|
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
|
|
|
|
</svg>
|
|
|
|
</div>
|
|
|
|
{% block page_body %}
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Main wrapper - style you can find in pages.scss -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div id="main-wrapper">
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Topbar header - style you can find in pages.scss -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<header class="topbar">
|
|
|
|
<nav class="navbar top-navbar navbar-expand-md navbar-light">
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Logo -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div class="navbar-header">
|
|
|
|
<a class="navbar-brand" href="{{ url_for('redirect_root') }}">
|
|
|
|
<!-- Logo icon -->
|
|
|
|
<b>
|
|
|
|
<img src="{{ url_for('static',filename='logo128.png') }}" alt="homepage" width="40"
|
|
|
|
class="dark-logo"/>
|
|
|
|
</b></a>
|
|
|
|
<!--End Logo icon -->
|
|
|
|
<!-- Logo text -->
|
|
|
|
</div>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- End Logo -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div class="navbar-collapse">
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- toggle and nav items -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<ul class="navbar-nav mr-auto mt-md-0">
|
|
|
|
<!-- This is -->
|
|
|
|
<li class="nav-item"><a
|
|
|
|
class="nav-link nav-toggler d-block d-md-none text-muted hidden-xl-up"
|
|
|
|
href="javascript:void(0)"><i class="mdi mdi-menu"></i></a></li>
|
|
|
|
<li class="nav-item"><a
|
|
|
|
class="nav-link sidebartoggler d-none d-md-block text-muted hidden-xl-up"
|
|
|
|
href="javascript:void(0)"><i class="ti-menu"></i></a></li>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Search -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<li class="nav-item hidden-sm-down search-box">
|
|
|
|
<form class="form-material"><input type="text" class="form-control text-white"
|
|
|
|
placeholder="Search...">
|
|
|
|
</form>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- User profile and search -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<ul class="navbar-nav my-lg-0">
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Profile -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<li class="nav-item dropdown">
|
|
|
|
<a class="nav-link dropdown-toggle text-muted fas fa-user" href=""
|
|
|
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></a>
|
|
|
|
<div class="dropdown-menu dropdown-menu-right scale-up">
|
|
|
|
<ul class="dropdown-user">
|
|
|
|
<li><a href="{{ url_for('restart') }}"><i class="fas fa-redo"></i> Restart</a></li>
|
|
|
|
<li><a href="{{ url_for('shutdown') }}"><i class="fas fa-power-off"></i>
|
|
|
|
Shutdown</a></li>
|
|
|
|
<li><a href="{{ url_for('logout') }}"><i class="fas fa-sign-out-alt"></i> Logout</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- End Topbar header -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Left Sidebar - style you can find in sidebar.scss -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<aside class="left-sidebar">
|
|
|
|
<!-- Sidebar scroll-->
|
|
|
|
<div class="scroll-sidebar">
|
|
|
|
<!-- Sidebar navigation-->
|
|
|
|
<nav class="sidebar-nav">
|
|
|
|
<ul id="sidebarnav">
|
|
|
|
{% if settings.general.getboolean('use_sonarr') %}
|
|
|
|
<li><a href="{{ url_for('series') }}"><i class="fas fa-play"></i><span
|
|
|
|
class="hide-menu"> Series</span></a>
|
|
|
|
</li>
|
|
|
|
{% endif %}
|
|
|
|
{% if settings.general.getboolean('use_radarr') %}
|
|
|
|
<li><a href="{{ url_for('movies') }}"><i class="fas fa-film"></i><span
|
|
|
|
class="hide-menu"> Movies</span></a>
|
|
|
|
</li>
|
|
|
|
{% endif %}
|
|
|
|
{% if settings.general.getboolean('use_sonarr') and settings.general.getboolean('use_radarr') %}
|
|
|
|
<li><a href="#"><i class="fas fa-clock"></i><span
|
|
|
|
class="hide-menu"> History</span></a>
|
|
|
|
<ul aria-expanded="false" class="collapse">
|
|
|
|
<li><a href="{{ url_for('historyseries') }}"> Series</a></li>
|
|
|
|
<li><a href="{{ url_for('historymovies') }}"> Movies</a></li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
{% elif settings.general.getboolean('use_sonarr') and not settings.general.getboolean('use_radarr') %}
|
|
|
|
<li><a href="{{ url_for('historyseries') }}"><i class="fas fa-play"></i><span
|
|
|
|
class="hide-menu"> History</span></a>
|
|
|
|
</li>
|
|
|
|
{% elif settings.general.getboolean('use_radarr') and not settings.general.getboolean('use_sonarr') %}
|
|
|
|
<li><a href="{{ url_for('historymovies') }}"><i class="fas fa-play"></i><span
|
|
|
|
class="hide-menu"> History</span></a>
|
|
|
|
</li>
|
|
|
|
{% endif %}
|
|
|
|
<li><a href="#"><i class="fas fa-exclamation-triangle"></i><span
|
|
|
|
class="hide-menu"> Wanted</span></a>
|
|
|
|
<ul aria-expanded="false" class="collapse">
|
|
|
|
<li><a href="/"> Missing</a></li>
|
|
|
|
<li><a href="/"> Cutoff Unmet</a></li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li><a href="#"><i
|
|
|
|
class="fas fa-cogs"></i><span class="hide-menu"> Settings</span></a>
|
|
|
|
<ul aria-expanded="false" class="collapse">
|
|
|
|
<li><a href="/"> General</a></li>
|
|
|
|
<li><a href="/"> Sonarr</a></li>
|
|
|
|
<li><a href="/"> Radarr</a></li>
|
|
|
|
<li><a href="/"> Subtitles</a></li>
|
|
|
|
<li><a href="/"> Notifications</a></li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
<li><a href="#"><i
|
|
|
|
class="fas fa-laptop"></i><span class="hide-menu"> System</span></a>
|
|
|
|
<ul aria-expanded="false" class="collapse">
|
|
|
|
<li><a href="/"> Tasks</a></li>
|
|
|
|
<li><a href="/"> Logs</a></li>
|
|
|
|
<li><a href="/"> Providers</a></li>
|
|
|
|
<li><a href="/"> Status</a></li>
|
|
|
|
<li><a href="/"> Releases</a></li>
|
|
|
|
</ul>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
<!-- End Sidebar navigation -->
|
|
|
|
</div>
|
|
|
|
<!-- End Sidebar scroll-->
|
|
|
|
</aside>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- End Left Sidebar - style you can find in sidebar.scss -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div class="page-wrapper">
|
|
|
|
<div class="container-fluid">
|
|
|
|
{% block breadcrumb %}
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- Bread crumb and right sidebar toggle -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<div class="row page-titles">
|
|
|
|
<div class="col-md-5 col-8 align-self-center">
|
|
|
|
{% block bcleft %}
|
|
|
|
{% endblock bcleft %}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<div class="col-md-7 col-4 align-self-center">
|
|
|
|
{% block bcright %}
|
|
|
|
{% endblock bcright %}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endblock breadcrumb %}
|
|
|
|
{% block body %}
|
|
|
|
|
|
|
|
{% endblock body %}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- footer -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
</div>
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- End footer -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
{% endblock page_body %}
|
|
|
|
|
|
|
|
|
|
|
|
{% block tail_js %}
|
|
|
|
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<!-- All Jquery -->
|
|
|
|
<!-- ============================================================== -->
|
|
|
|
<script src="{{ url_for('static',filename='plugins/jquery/jquery.min.js') }}"></script>
|
|
|
|
<!-- Bootstrap tether Core JavaScript -->
|
|
|
|
<script src="{{ url_for('static',filename='plugins/popper/popper.min.js') }}"></script>
|
|
|
|
<script src="{{ url_for('static',filename='plugins/bootstrap/js/bootstrap.min.js') }}"></script>
|
|
|
|
<!-- slimscrollbar scrollbar JavaScript -->
|
|
|
|
<script src="{{ url_for('static',filename='js/jquery.slimscroll.js') }}"></script>
|
|
|
|
<!--Menu sidebar -->
|
|
|
|
<script src="{{ url_for('static',filename='js/sidebarmenu.js') }}"></script>
|
|
|
|
|
|
|
|
<!--stickey kit -->
|
|
|
|
<script src="{{ url_for('static',filename='plugins/sticky-kit-master/dist/sticky-kit.min.js') }}"></script>
|
|
|
|
<!--Custom JavaScript -->
|
|
|
|
<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='plugins/datatables.net-bs4/js/dataTables.bootstrap4.min.js') }}"></script>
|
|
|
|
<script src="{{ url_for('static',filename='js/custom.js') }}"></script>
|
|
|
|
<!-- Polyfill for older browsers without native support for the HTML5 EventSource API. -->
|
|
|
|
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=EventSource"></script>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
$(document).ready(function () {
|
|
|
|
BadgesAjax();
|
|
|
|
|
|
|
|
$('.table').on('draw.dt', function () {
|
|
|
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
|
|
|
});
|
|
|
|
|
|
|
|
events = new EventSource('{{ url_for('api.events') }}');
|
|
|
|
|
|
|
|
// Handler for when the stream is opened (either the first time or after a reconnect).
|
|
|
|
events.addEventListener('open', function(event) {
|
|
|
|
console.log('Stream is open');
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
// Handler for new messages.
|
|
|
|
events.addEventListener('message', event => {
|
|
|
|
var event_json = JSON.parse(event.data);
|
|
|
|
if (event_json.series === {{id}}) {
|
|
|
|
if (event_json.type === 'series' && event_json.action === 'update' && event_json.episode == null) {
|
|
|
|
seriesDetailsRefresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_json.type === 'episode' && event_json.action === 'insert') {
|
|
|
|
$.ajax({
|
|
|
|
url: "{{ url_for('api.episodes') }}?seriesid=" + event_json.series + "&episodeid=" + event_json.episode,
|
|
|
|
async: true,
|
|
|
|
success: function (data) {
|
|
|
|
if (data.data.length) {
|
|
|
|
$('#episodes').DataTable().row.add(data.data[0]).draw();
|
|
|
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} else if (event_json.type === 'episode' && event_json.action === 'update') {
|
|
|
|
var rowId = $('#episodes').DataTable().row('#row_' + event_json.episode);
|
|
|
|
if (rowId.length) {
|
|
|
|
$.ajax({
|
|
|
|
url: "{{ url_for('api.episodes') }}?seriesid=" + event_json.series + "&episodeid=" + event_json.episode,
|
|
|
|
async: true,
|
|
|
|
success: function (data) {
|
|
|
|
if (data.data.length) {
|
|
|
|
$('#episodes').DataTable().row(rowId).data(data.data[0]);
|
|
|
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
} else if (event_json.type === 'episode' && event_json.action === 'delete') {
|
|
|
|
var rowId = $('#episodes').DataTable().row('#row_' + event_json.episode);
|
|
|
|
if (rowId.length) {
|
|
|
|
$('#episodes').DataTable().row(rowId).remove().draw();
|
|
|
|
$('[data-toggle="tooltip"]').tooltip({html: true});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
// Handler for a dropped connection or the server closing the connection.
|
|
|
|
events.addEventListener('error', function(event) {
|
|
|
|
switch (event.target.readyState) {
|
|
|
|
case EventSource.CONNECTING:
|
|
|
|
console.log('Reconnecting...');
|
|
|
|
break;
|
|
|
|
case EventSource.CLOSED:
|
|
|
|
console.log('Connection failed, will not reconnect');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
function BadgesAjax() {
|
|
|
|
$.ajax({
|
|
|
|
url: "{{url_for('api.badges')}}",
|
|
|
|
async: true,
|
|
|
|
success: function (data) {
|
|
|
|
if (data['throttled_providers']) {
|
|
|
|
$('#throttled_providers_count').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['throttled_providers'] + '</div>');
|
|
|
|
}
|
|
|
|
if (data['missing_episodes']) {
|
|
|
|
$('#wanted').append('<div class="floating ui tiny yellow label" style="left:90% !important;top:0.5em !important;">' + data['missing_episodes'] + '</div>');
|
|
|
|
}
|
|
|
|
if (data['missing_movies']) {
|
|
|
|
$('#wanted').append('<div id="wanted_movies" class="floating ui tiny green label" style="left:90% !important;top:3em !important;">' + data['missing_movies'] + '</div>');
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
error: (function () {
|
|
|
|
setTimeout(function () {
|
|
|
|
setInterval(ping, 2000);
|
|
|
|
}, 8000);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$(window).on('beforeunload', function() {
|
|
|
|
events.close();
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
{% endblock tail_js %}
|
|
|
|
{% block tail %}
|
|
|
|
{% endblock tail %}
|
|
|
|
</body>
|
|
|
|
</html>
|