mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-08 02:53:38 +00:00
Change refactor email notifier.
This commit is contained in:
parent
31d10c8bb7
commit
101e698a86
8 changed files with 460 additions and 415 deletions
|
@ -19,6 +19,7 @@
|
||||||
* Update Requests library 2.7.0 (5d6d1bc) to 2.9.1 (a1c9b84)
|
* Update Requests library 2.7.0 (5d6d1bc) to 2.9.1 (a1c9b84)
|
||||||
* Update SimpleJSON library 3.8.0 (a37a9bd) to 3.8.1 (6022794)
|
* Update SimpleJSON library 3.8.0 (a37a9bd) to 3.8.1 (6022794)
|
||||||
* Update Six compatibility library 1.9.0 (r400) to 1.10.0 (r405)
|
* Update Six compatibility library 1.9.0 (r400) to 1.10.0 (r405)
|
||||||
|
* Change refactor email notifier
|
||||||
|
|
||||||
|
|
||||||
### 0.11.3 (2016-01-16 20:00:00 UTC)
|
### 0.11.3 (2016-01-16 20:00:00 UTC)
|
||||||
|
|
|
@ -1178,6 +1178,7 @@ pre{
|
||||||
input sizing (for config pages)
|
input sizing (for config pages)
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
|
.showlist-select optgroup,
|
||||||
#pickShow optgroup,
|
#pickShow optgroup,
|
||||||
#showfilter optgroup,
|
#showfilter optgroup,
|
||||||
#editAProvider optgroup{
|
#editAProvider optgroup{
|
||||||
|
@ -1185,6 +1186,7 @@ input sizing (for config pages)
|
||||||
background-color:rgb(51, 51, 51)
|
background-color:rgb(51, 51, 51)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.showlist-select optgroup option,
|
||||||
#pickShow optgroup option,
|
#pickShow optgroup option,
|
||||||
#showfilter optgroup option,
|
#showfilter optgroup option,
|
||||||
#editAProvider optgroup option{
|
#editAProvider optgroup option{
|
||||||
|
|
|
@ -1142,6 +1142,7 @@ pre{
|
||||||
input sizing (for config pages)
|
input sizing (for config pages)
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
||||||
|
.showlist-select optgroup,
|
||||||
#pickShow optgroup,
|
#pickShow optgroup,
|
||||||
#showfilter optgroup,
|
#showfilter optgroup,
|
||||||
#editAProvider optgroup{
|
#editAProvider optgroup{
|
||||||
|
@ -1149,6 +1150,7 @@ input sizing (for config pages)
|
||||||
background-color:#888
|
background-color:#888
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.showlist-select optgroup option,
|
||||||
#pickShow optgroup option,
|
#pickShow optgroup option,
|
||||||
#showfilter optgroup option,
|
#showfilter optgroup option,
|
||||||
#editAProvider optgroup option{
|
#editAProvider optgroup option{
|
||||||
|
|
|
@ -1637,7 +1637,7 @@
|
||||||
<div class="component-group-desc">
|
<div class="component-group-desc">
|
||||||
<img class="notifier-icon" src="$sbRoot/images/notifiers/email.png" alt="" title="Email" />
|
<img class="notifier-icon" src="$sbRoot/images/notifiers/email.png" alt="" title="Email" />
|
||||||
<h3><a href="<%= anon_url('http://en.wikipedia.org/wiki/Comparison_of_webmail_providers') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Email</a></h3>
|
<h3><a href="<%= anon_url('http://en.wikipedia.org/wiki/Comparison_of_webmail_providers') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Email</a></h3>
|
||||||
<p>Allows configuration of email notifications on a per show basis.</p>
|
<p>Email notification settings.</p>
|
||||||
</div>
|
</div>
|
||||||
<fieldset class="component-group-list">
|
<fieldset class="component-group-list">
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
|
@ -1678,95 +1678,71 @@
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-pair">
|
|
||||||
<label for="email_host">
|
|
||||||
<span class="component-title">SMTP host</span>
|
|
||||||
<input type="text" name="email_host" id="email_host" value="$sickbeard.EMAIL_HOST" class="form-control input-sm input250" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span class="component-title"> </span>
|
|
||||||
<span class="component-desc">hostname of your SMTP email server.</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-pair">
|
|
||||||
<label for="email_port">
|
|
||||||
<span class="component-title">SMTP port</span>
|
|
||||||
<input type="text" name="email_port" id="email_port" value="$sickbeard.EMAIL_PORT" class="form-control input-sm input75" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span class="component-title"> </span>
|
|
||||||
<span class="component-desc">port number used to connect to your SMTP host.</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<label for="email_from">
|
<label for="email_from">
|
||||||
<span class="component-title">SMTP from</span>
|
<span class="component-title">SMTP sender email address</span>
|
||||||
|
<span class="component-desc">
|
||||||
<input type="text" name="email_from" id="email_from" value="$sickbeard.EMAIL_FROM" class="form-control input-sm input250" />
|
<input type="text" name="email_from" id="email_from" value="$sickbeard.EMAIL_FROM" class="form-control input-sm input250" />
|
||||||
|
<div class="clear-left"><p>some recipient hosts require a real address</p></div>
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<div style="margin-bottom:5px;display:inline-block">
|
||||||
<span class="component-title"> </span>
|
<span class="component-title">SMTP server hostname</span>
|
||||||
<span class="component-desc">sender email address, some hosts require a real address.</span>
|
<span class="component-desc">
|
||||||
</label>
|
<input type="text" name="email_host" id="email_host" value="$sickbeard.EMAIL_HOST" class="form-control input-sm input250" />
|
||||||
|
<span style="float:left;margin-right:6px">and port</span><input type="text" name="email_port" id="email_port" value="$sickbeard.EMAIL_PORT" class="form-control input-sm input75" style="width:60px" />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-pair">
|
|
||||||
<label for="email_tls">
|
<label for="email_tls">
|
||||||
<span class="component-title">Use TLS</span>
|
<span class="component-title">Enable TLS encryption</span>
|
||||||
<span class="component-desc">
|
<span class="component-desc">
|
||||||
<input type="checkbox" name="email_tls" id="email_tls" #if $sickbeard.EMAIL_TLS then 'checked="checked"' else ''# />
|
<input type="checkbox" name="email_tls" id="email_tls" #if $sickbeard.EMAIL_TLS then 'checked="checked"' else ''# />
|
||||||
<p>check to use TLS encryption.</p>
|
</span>
|
||||||
|
</label>
|
||||||
|
<label for="email_user">
|
||||||
|
<span class="component-title">SMTP server username</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="text" name="email_user" id="email_user" value="$sickbeard.EMAIL_USER" class="form-control input-sm input250" />
|
||||||
|
<p>(optional)</p>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label for="email_password">
|
||||||
|
<span class="component-title">SMTP server password</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="password" name="email_password" id="email_password" value="#echo '*' * len($sickbeard.EMAIL_PASSWORD)#" class="form-control input-sm input250" />
|
||||||
|
<p>(optional)</p>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-pair">
|
|
||||||
<label for="email_user">
|
|
||||||
<span class="component-title">SMTP user</span>
|
|
||||||
<input type="text" name="email_user" id="email_user" value="$sickbeard.EMAIL_USER" class="form-control input-sm input250" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span class="component-title"> </span>
|
|
||||||
<span class="component-desc">(optional) your SMTP server username.</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-pair">
|
|
||||||
<label for="email_password">
|
|
||||||
<span class="component-title">SMTP password</span>
|
|
||||||
<input type="password" name="email_password" id="email_password" value="#echo '*' * len($sickbeard.EMAIL_PASSWORD)#" class="form-control input-sm input250" />
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<span class="component-title"> </span>
|
|
||||||
<span class="component-desc">(optional) your SMTP server password.</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<label for="email_list">
|
<label for="email_list">
|
||||||
<span class="component-title">Global email list</span>
|
<span class="component-title">Notify for every show</span>
|
||||||
|
<span class="component-desc">
|
||||||
<input type="text" name="email_list" id="email_list" value="$sickbeard.EMAIL_LIST" class="form-control input-sm input350" />
|
<input type="text" name="email_list" id="email_list" value="$sickbeard.EMAIL_LIST" class="form-control input-sm input350" />
|
||||||
</label>
|
<div class="clear-left"><p>comma separated email list</p></div>
|
||||||
<label>
|
</span>
|
||||||
<span class="component-title"> </span>
|
|
||||||
<span class="component-desc">all emails here receive notifications for <b>all</b> shows.</span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<label for="email_show">
|
<label for="email_show">
|
||||||
<span class="component-title">Show notification list</span>
|
<span class="component-title">Notify on a per show basis</span>
|
||||||
<select name="email_show" id="email_show" class="form-control input-sm">
|
<select name="email_show" id="email_show" class="showlist-select form-control input-sm">
|
||||||
<option value="-1">-- Select a Show --</option>
|
<option value="-1">-- Shows appear here --</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<span class="component-title"> </span>
|
<span class="component-title"> </span>
|
||||||
<input type="text" name="email_show_list" id="email_show_list" class="form-control input-sm input350" />
|
<span class="component-desc">
|
||||||
</label>
|
<input type="text" name="show_email_list" id="show_email_list" class="form-control input-sm input350" />
|
||||||
<label>
|
<input type="button" value="Save Show" id="save_show_email" class="btn" />
|
||||||
<span class="component-title"> </span>
|
<div class="clear-left"><p>comma separated email list for each show</p></div>
|
||||||
<span class="component-desc">configure per show notifications here.</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="testNotification" id="testEmail-result">Click below to test.</div>
|
<div class="testNotification" id="testEmail-result">Click below to test.</div>
|
||||||
<input class="btn" type="button" value="Test Email" id="testEmail" />
|
<input type="button" class="btn" value="Test Email" id="testEmail" />
|
||||||
<input class="btn" type="submit" class="config_submitter" value="Save Changes" />
|
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
||||||
</div><!-- /content_use_email //-->
|
</div><!-- /content_use_email //-->
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div><!-- /email component-group //-->
|
</div><!-- /email component-group //-->
|
||||||
|
|
|
@ -75,6 +75,16 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// show instructions for plex when enabled
|
||||||
|
$('#use_plex').click(function() {
|
||||||
|
if ( $(this).is(':checked') ) {
|
||||||
|
$('.plexinfo').removeClass('hide');
|
||||||
|
} else {
|
||||||
|
$('.plexinfo').addClass('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if ($('input[id="use_plex"]').is(':checked')) {$('.plexinfo').removeClass('hide')}
|
||||||
|
|
||||||
$('#testPMC').click(function () {
|
$('#testPMC').click(function () {
|
||||||
var plex_host = $.trim($('#plex_host').val());
|
var plex_host = $.trim($('#plex_host').val());
|
||||||
var plex_username = $.trim($('#plex_username').val());
|
var plex_username = $.trim($('#plex_username').val());
|
||||||
|
@ -225,30 +235,6 @@
|
||||||
function (data) { $('#testLibnotify-result').html(data); });
|
function (data) { $('#testLibnotify-result').html(data); });
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#twitterStep1').click(function() {
|
|
||||||
$('#testTwitter-result').html(loading);
|
|
||||||
$.get(sbRoot + '/home/twitterStep1', function (data) {window.open(data); })
|
|
||||||
.done(function () { $('#testTwitter-result').html('<b>Step1:</b> Confirm Authorization'); });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#twitterStep2').click(function () {
|
|
||||||
var twitter_key = $.trim($('#twitter_key').val());
|
|
||||||
if (!twitter_key) {
|
|
||||||
$('#testTwitter-result').html('Please fill out the necessary fields above.');
|
|
||||||
$('#twitter_key').addClass('warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('#twitter_key').removeClass('warning');
|
|
||||||
$('#testTwitter-result').html(loading);
|
|
||||||
$.get(sbRoot + '/home/twitterStep2', {'key': twitter_key},
|
|
||||||
function (data) { $('#testTwitter-result').html(data); });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#testTwitter').click(function() {
|
|
||||||
$.get(sbRoot + '/home/testTwitter',
|
|
||||||
function (data) { $('#testTwitter-result').html(data); });
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#settingsNMJ').click(function() {
|
$('#settingsNMJ').click(function() {
|
||||||
if (!$('#nmj_host').val()) {
|
if (!$('#nmj_host').val()) {
|
||||||
alert('Please fill in the Popcorn IP address');
|
alert('Please fill in the Popcorn IP address');
|
||||||
|
@ -352,6 +338,139 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#testNMA').click(function () {
|
||||||
|
var nma_api = $.trim($('#nma_api').val());
|
||||||
|
var nma_priority = $('#nma_priority').val();
|
||||||
|
if (!nma_api) {
|
||||||
|
$('#testNMA-result').html('Please fill out the necessary fields above.');
|
||||||
|
$('#nma_api').addClass('warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#nma_api').removeClass('warning');
|
||||||
|
$(this).prop('disabled', true);
|
||||||
|
$('#testNMA-result').html(loading);
|
||||||
|
$.get(sbRoot + '/home/testNMA', {'nma_api': nma_api, 'nma_priority': nma_priority})
|
||||||
|
.done(function (data) {
|
||||||
|
$('#testNMA-result').html(data);
|
||||||
|
$('#testNMA').prop('disabled', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#testPushalot').click(function () {
|
||||||
|
var pushalot_authorizationtoken = $.trim($('#pushalot_authorizationtoken').val());
|
||||||
|
if (!pushalot_authorizationtoken) {
|
||||||
|
$('#testPushalot-result').html('Please fill out the necessary fields above.');
|
||||||
|
$('#pushalot_authorizationtoken').addClass('warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#pushalot_authorizationtoken').removeClass('warning');
|
||||||
|
$(this).prop('disabled', true);
|
||||||
|
$('#testPushalot-result').html(loading);
|
||||||
|
$.get(sbRoot + '/home/testPushalot', {'authorizationToken': pushalot_authorizationtoken})
|
||||||
|
.done(function (data) {
|
||||||
|
$('#testPushalot-result').html(data);
|
||||||
|
$('#testPushalot').prop('disabled', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#testPushbullet').click(function () {
|
||||||
|
var pushbullet_access_token = $.trim($('#pushbullet_access_token').val());
|
||||||
|
var pushbullet_device_iden = $('#pushbullet_device_iden').val();
|
||||||
|
if (!pushbullet_access_token) {
|
||||||
|
$('#testPushbullet-result').html('Please fill out the necessary fields above.');
|
||||||
|
$('#pushbullet_access_token').addClass('warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#pushbullet_access_token').removeClass('warning');
|
||||||
|
$(this).prop('disabled', true);
|
||||||
|
$('#testPushbullet-result').html(loading);
|
||||||
|
$.get(sbRoot + '/home/testPushbullet', {'accessToken': pushbullet_access_token, 'device_iden': pushbullet_device_iden})
|
||||||
|
.done(function (data) {
|
||||||
|
$('#testPushbullet-result').html(data);
|
||||||
|
$('#testPushbullet').prop('disabled', false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function get_pushbullet_devices (msg) {
|
||||||
|
var pushbullet_access_token = $.trim($('#pushbullet_access_token').val());
|
||||||
|
if (!pushbullet_access_token) {
|
||||||
|
$('#testPushbullet-result').html('Please fill out the necessary fields above.');
|
||||||
|
$('#pushbullet_access_token').addClass('warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$(this).prop("disabled", true);
|
||||||
|
if (msg) {
|
||||||
|
$('#testPushbullet-result').html(loading);
|
||||||
|
}
|
||||||
|
var current_pushbullet_device = $('#pushbullet_device_iden').val();
|
||||||
|
$.get(sbRoot + '/home/getPushbulletDevices', {'accessToken': pushbullet_access_token})
|
||||||
|
.done(function (data) {
|
||||||
|
var devices = jQuery.parseJSON(data || '{}').devices;
|
||||||
|
var error = jQuery.parseJSON(data || '{}').error;
|
||||||
|
$('#pushbullet_device_list').html('');
|
||||||
|
if (devices) {
|
||||||
|
// add default option to send to all devices
|
||||||
|
$('#pushbullet_device_list').append('<option value="" selected="selected">-- All Devices --</option>');
|
||||||
|
for (var i = 0; i < devices.length; i++) {
|
||||||
|
// only list active device targets
|
||||||
|
if (devices[i].active == true) {
|
||||||
|
// if a device in the list matches our current iden, select it
|
||||||
|
if (current_pushbullet_device == devices[i].iden) {
|
||||||
|
$('#pushbullet_device_list').append('<option value="' + devices[i].iden + '" selected="selected">' + devices[i].manufacturer + ' ' + devices[i].nickname + '</option>');
|
||||||
|
} else {
|
||||||
|
$('#pushbullet_device_list').append('<option value="' + devices[i].iden + '">' + devices[i].manufacturer + ' ' + devices[i].nickname + '</option>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$('#getPushbulletDevices').prop('disabled', false);
|
||||||
|
if (msg) {
|
||||||
|
if (error.message) {
|
||||||
|
$('#testPushbullet-result').html(error.message);
|
||||||
|
} else {
|
||||||
|
$('#testPushbullet-result').html(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#pushbullet_device_list').change(function () {
|
||||||
|
$('#pushbullet_device_iden').val($('#pushbullet_device_list').val());
|
||||||
|
$('#testPushbullet-result').html('Don\'t forget to save your new Pushbullet settings.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#getPushbulletDevices').click(function () {
|
||||||
|
get_pushbullet_devices('Device list updated. Select specific device to use.');
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($('#use_pushbullet').prop('checked')) {
|
||||||
|
get_pushbullet_devices();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#twitterStep1').click(function() {
|
||||||
|
$('#testTwitter-result').html(loading);
|
||||||
|
$.get(sbRoot + '/home/twitterStep1', function (data) {window.open(data); })
|
||||||
|
.done(function () { $('#testTwitter-result').html('<b>Step1:</b> Confirm Authorization'); });
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#twitterStep2').click(function () {
|
||||||
|
var twitter_key = $.trim($('#twitter_key').val());
|
||||||
|
if (!twitter_key) {
|
||||||
|
$('#testTwitter-result').html('Please fill out the necessary fields above.');
|
||||||
|
$('#twitter_key').addClass('warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#twitter_key').removeClass('warning');
|
||||||
|
$('#testTwitter-result').html(loading);
|
||||||
|
$.get(sbRoot + '/home/twitterStep2', {'key': twitter_key},
|
||||||
|
function (data) { $('#testTwitter-result').html(data); });
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#testTwitter').click(function() {
|
||||||
|
$.get(sbRoot + '/home/testTwitter',
|
||||||
|
function (data) { $('#testTwitter-result').html(data); });
|
||||||
|
});
|
||||||
|
|
||||||
var elTraktAuth = $('#trakt-authenticate'), elTraktAuthResult = $('#trakt-authentication-result');
|
var elTraktAuth = $('#trakt-authenticate'), elTraktAuthResult = $('#trakt-authentication-result');
|
||||||
|
|
||||||
function trakt_send_auth(){
|
function trakt_send_auth(){
|
||||||
|
@ -510,6 +629,67 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function load_show_notify_lists() {
|
||||||
|
$.get(sbRoot + '/home/loadShowNotifyLists', function (data) {
|
||||||
|
var list, html, item, len= 0, el;
|
||||||
|
list = $.parseJSON(data);
|
||||||
|
html = [];
|
||||||
|
for (item in list) {
|
||||||
|
for (var k in list[item]) {
|
||||||
|
if ($.isArray(list[item][k])) {
|
||||||
|
len += list[item][k].length;
|
||||||
|
html.push('\t<optgroup label="' + k + '">');
|
||||||
|
for (var show in list[item][k]) {
|
||||||
|
html.push('\t\t<option value="' + list[item][k][show].id + '"'
|
||||||
|
+ ' data="' + list[item][k][show].list + '"'
|
||||||
|
+ '>' + list[item][k][show].name + '</option>');
|
||||||
|
}
|
||||||
|
html.push('\t</optgroup>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
el = $('#email_show');
|
||||||
|
el.html('<option value="-1">-- Select show --</option>'
|
||||||
|
+ html.join('\n'));
|
||||||
|
|
||||||
|
$('#show_email_list').val('');
|
||||||
|
|
||||||
|
el.change(function () {
|
||||||
|
$('#show_email_list').val(
|
||||||
|
$(this).find('option[value="' + $(this).val() + '"]').attr('data'))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Load the per show notify lists everytime this page is loaded
|
||||||
|
load_show_notify_lists();
|
||||||
|
|
||||||
|
// Update the internal data struct anytime settings are saved to the server
|
||||||
|
$('#email_show').bind('notify', function () { load_show_notify_lists(); });
|
||||||
|
|
||||||
|
$('#save_show_email').click(
|
||||||
|
function(){
|
||||||
|
var show = $('#email_show').val();
|
||||||
|
if ('-1' == show) {
|
||||||
|
$('#testEmail-result').html('No show selected for save.');
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$.post(sbRoot + '/home/save_show_email', {
|
||||||
|
show: show,
|
||||||
|
emails: $('#show_email_list').val()},
|
||||||
|
function (data){
|
||||||
|
// Reload the per show notify lists to reflect changes
|
||||||
|
load_show_notify_lists();
|
||||||
|
var result = $.parseJSON(data),
|
||||||
|
show = $('#email_show').find('option[value="' + result.id + '"]').text();
|
||||||
|
$('#testEmail-result').html(result.success
|
||||||
|
? 'Success. Notify list updated for show "' + show + '". Click below to test.'
|
||||||
|
: 'Error saving notify list for show %s' % show);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('#testEmail').click(function () {
|
$('#testEmail').click(function () {
|
||||||
var status, host, port, tls, from, user, pwd, err, to;
|
var status, host, port, tls, from, user, pwd, err, to;
|
||||||
status = $('#testEmail-result');
|
status = $('#testEmail-result');
|
||||||
|
@ -523,174 +703,27 @@
|
||||||
from = from.length > 0 ? from : 'root@localhost';
|
from = from.length > 0 ? from : 'root@localhost';
|
||||||
user = $('#email_user').val().trim();
|
user = $('#email_user').val().trim();
|
||||||
pwd = $('#email_password').val();
|
pwd = $('#email_password').val();
|
||||||
err = '';
|
err = [];
|
||||||
if (host === null) {
|
if (null == host) {
|
||||||
err += '<li style="color: red;">You must specify an SMTP hostname!</li>';
|
err.push('SMTP server hostname');
|
||||||
}
|
}
|
||||||
if (port === null) {
|
if (null == port) {
|
||||||
err += '<li style="color: red;">You must specify an SMTP port!</li>';
|
err.push('SMTP server host port');
|
||||||
} else if (port.match(/^\d+$/) === null || parseInt(port, 10) > 65535) {
|
} else if (null == port.match(/^\d+$/) || parseInt(port, 10) > 65535) {
|
||||||
err += '<li style="color: red;">SMTP port must be between 0 and 65535!</li>';
|
err.push('SMTP server host port must be between 0 and 65535');
|
||||||
}
|
}
|
||||||
if (err.length > 0) {
|
if (0 < err.length) {
|
||||||
err = '<ol>' + err + '</ol>';
|
status.html('Required: ' + err.join(', '));
|
||||||
status.html(err);
|
|
||||||
} else {
|
} else {
|
||||||
to = prompt('Enter an email address to send the test to:', null);
|
to = prompt('Enter an email address to send the test to:', '');
|
||||||
if (to === null || to.length === 0 || to.match(/.*@.*/) === null) {
|
if (null == to || 0 == to.length || null == to.match(/.*@.*/)) {
|
||||||
status.html('<p style="color: red;">You must provide a recipient email address!</p>');
|
status.html('Required: A valid address for email test');
|
||||||
} else {
|
} else {
|
||||||
$.get(sbRoot + '/home/testEmail', {host: host, port: port, smtp_from: from, use_tls: tls, user: user, pwd: pwd, to: to},
|
$.get(sbRoot + '/home/testEmail',
|
||||||
|
{host:host, port:port, smtp_from:from, use_tls:tls, user:user, pwd:pwd, to:to},
|
||||||
function(msg) {$('#testEmail-result').html(msg);});
|
function(msg) {$('#testEmail-result').html(msg);});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#testNMA').click(function () {
|
|
||||||
var nma_api = $.trim($('#nma_api').val());
|
|
||||||
var nma_priority = $('#nma_priority').val();
|
|
||||||
if (!nma_api) {
|
|
||||||
$('#testNMA-result').html('Please fill out the necessary fields above.');
|
|
||||||
$('#nma_api').addClass('warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('#nma_api').removeClass('warning');
|
|
||||||
$(this).prop('disabled', true);
|
|
||||||
$('#testNMA-result').html(loading);
|
|
||||||
$.get(sbRoot + '/home/testNMA', {'nma_api': nma_api, 'nma_priority': nma_priority})
|
|
||||||
.done(function (data) {
|
|
||||||
$('#testNMA-result').html(data);
|
|
||||||
$('#testNMA').prop('disabled', false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#testPushalot').click(function () {
|
|
||||||
var pushalot_authorizationtoken = $.trim($('#pushalot_authorizationtoken').val());
|
|
||||||
if (!pushalot_authorizationtoken) {
|
|
||||||
$('#testPushalot-result').html('Please fill out the necessary fields above.');
|
|
||||||
$('#pushalot_authorizationtoken').addClass('warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('#pushalot_authorizationtoken').removeClass('warning');
|
|
||||||
$(this).prop('disabled', true);
|
|
||||||
$('#testPushalot-result').html(loading);
|
|
||||||
$.get(sbRoot + '/home/testPushalot', {'authorizationToken': pushalot_authorizationtoken})
|
|
||||||
.done(function (data) {
|
|
||||||
$('#testPushalot-result').html(data);
|
|
||||||
$('#testPushalot').prop('disabled', false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#testPushbullet').click(function () {
|
|
||||||
var pushbullet_access_token = $.trim($('#pushbullet_access_token').val());
|
|
||||||
var pushbullet_device_iden = $('#pushbullet_device_iden').val();
|
|
||||||
if (!pushbullet_access_token) {
|
|
||||||
$('#testPushbullet-result').html('Please fill out the necessary fields above.');
|
|
||||||
$('#pushbullet_access_token').addClass('warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$('#pushbullet_access_token').removeClass('warning');
|
|
||||||
$(this).prop('disabled', true);
|
|
||||||
$('#testPushbullet-result').html(loading);
|
|
||||||
$.get(sbRoot + '/home/testPushbullet', {'accessToken': pushbullet_access_token, 'device_iden': pushbullet_device_iden})
|
|
||||||
.done(function (data) {
|
|
||||||
$('#testPushbullet-result').html(data);
|
|
||||||
$('#testPushbullet').prop('disabled', false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function get_pushbullet_devices (msg) {
|
|
||||||
var pushbullet_access_token = $.trim($('#pushbullet_access_token').val());
|
|
||||||
if (!pushbullet_access_token) {
|
|
||||||
$('#testPushbullet-result').html('Please fill out the necessary fields above.');
|
|
||||||
$('#pushbullet_access_token').addClass('warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$(this).prop("disabled", true);
|
|
||||||
if (msg) {
|
|
||||||
$('#testPushbullet-result').html(loading);
|
|
||||||
}
|
|
||||||
var current_pushbullet_device = $('#pushbullet_device_iden').val();
|
|
||||||
$.get(sbRoot + '/home/getPushbulletDevices', {'accessToken': pushbullet_access_token})
|
|
||||||
.done(function (data) {
|
|
||||||
var devices = jQuery.parseJSON(data || '{}').devices;
|
|
||||||
var error = jQuery.parseJSON(data || '{}').error;
|
|
||||||
$('#pushbullet_device_list').html('');
|
|
||||||
if (devices) {
|
|
||||||
// add default option to send to all devices
|
|
||||||
$('#pushbullet_device_list').append('<option value="" selected="selected">-- All Devices --</option>');
|
|
||||||
for (var i = 0; i < devices.length; i++) {
|
|
||||||
// only list active device targets
|
|
||||||
if (devices[i].active == true) {
|
|
||||||
// if a device in the list matches our current iden, select it
|
|
||||||
if (current_pushbullet_device == devices[i].iden) {
|
|
||||||
$('#pushbullet_device_list').append('<option value="' + devices[i].iden + '" selected="selected">' + devices[i].manufacturer + ' ' + devices[i].nickname + '</option>');
|
|
||||||
} else {
|
|
||||||
$('#pushbullet_device_list').append('<option value="' + devices[i].iden + '">' + devices[i].manufacturer + ' ' + devices[i].nickname + '</option>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$('#getPushbulletDevices').prop('disabled', false);
|
|
||||||
if (msg) {
|
|
||||||
if (error.message) {
|
|
||||||
$('#testPushbullet-result').html(error.message);
|
|
||||||
} else {
|
|
||||||
$('#testPushbullet-result').html(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#pushbullet_device_list').change(function () {
|
|
||||||
$('#pushbullet_device_iden').val($('#pushbullet_device_list').val());
|
|
||||||
$('#testPushbullet-result').html('Don\'t forget to save your new Pushbullet settings.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#getPushbulletDevices').click(function () {
|
|
||||||
get_pushbullet_devices('Device list updated. Select specific device to use.');
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($('#use_pushbullet').prop('checked')) {
|
|
||||||
get_pushbullet_devices();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#email_show').change(function () {
|
|
||||||
var key = parseInt($('#email_show').val(), 10);
|
|
||||||
$('#email_show_list').val(key >= 0 ? notify_data[key.toString()].list : '');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the internal data struct anytime settings are saved to the server
|
|
||||||
$('#email_show').bind('notify', function () { load_show_notify_lists(); });
|
|
||||||
|
|
||||||
function load_show_notify_lists() {
|
|
||||||
$.get(sbRoot + "/home/loadShowNotifyLists", function (data) {
|
|
||||||
var list, html, s;
|
|
||||||
list = $.parseJSON(data);
|
|
||||||
notify_data = list;
|
|
||||||
if (list._size === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
html = '<option value="-1">-- Select --</option>';
|
|
||||||
for (s in list) {
|
|
||||||
if (s.charAt(0) !== '_') {
|
|
||||||
html += '<option value="' + list[s].id + '">' + $('<div/>').text(list[s].name).html() + '</option>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$('#email_show').html(html);
|
|
||||||
$('#email_show_list').val('');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Load the per show notify lists everytime this page is loaded
|
|
||||||
load_show_notify_lists();
|
|
||||||
|
|
||||||
// show instructions for plex when enabled
|
|
||||||
$('#use_plex').click(function() {
|
|
||||||
if ( $(this).is(':checked') ) {
|
|
||||||
$('.plexinfo').removeClass('hide');
|
|
||||||
} else {
|
|
||||||
$('.plexinfo').addClass('hide');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if ($('input[id="use_plex"]').is(':checked')) {$('.plexinfo').removeClass('hide')}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -393,6 +393,7 @@ PUSHBULLET_ACCESS_TOKEN = None
|
||||||
PUSHBULLET_DEVICE_IDEN = None
|
PUSHBULLET_DEVICE_IDEN = None
|
||||||
|
|
||||||
USE_EMAIL = False
|
USE_EMAIL = False
|
||||||
|
EMAIL_OLD_SUBJECTS = None
|
||||||
EMAIL_NOTIFY_ONSNATCH = False
|
EMAIL_NOTIFY_ONSNATCH = False
|
||||||
EMAIL_NOTIFY_ONDOWNLOAD = False
|
EMAIL_NOTIFY_ONDOWNLOAD = False
|
||||||
EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD = False
|
EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD = False
|
||||||
|
@ -511,7 +512,7 @@ def initialize(consoleLogging=True):
|
||||||
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, PUSHOVER_PRIORITY, PUSHOVER_DEVICE, PUSHOVER_SOUND, \
|
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, PUSHOVER_PRIORITY, PUSHOVER_DEVICE, PUSHOVER_SOUND, \
|
||||||
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, USE_SYNOINDEX, \
|
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, USE_SYNOINDEX, \
|
||||||
USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||||
USE_EMAIL, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \
|
USE_EMAIL, EMAIL_OLD_SUBJECTS, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \
|
||||||
METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, METADATA_KODI, metadata_provider_dict, \
|
METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, METADATA_KODI, metadata_provider_dict, \
|
||||||
GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, recentSearchScheduler, NFO_RENAME, \
|
GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, recentSearchScheduler, NFO_RENAME, \
|
||||||
GUI_NAME, DEFAULT_HOME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, EPISODE_VIEW_LAYOUT, EPISODE_VIEW_SORT, EPISODE_VIEW_DISPLAY_PAUSED, EPISODE_VIEW_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \
|
GUI_NAME, DEFAULT_HOME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, EPISODE_VIEW_LAYOUT, EPISODE_VIEW_SORT, EPISODE_VIEW_DISPLAY_PAUSED, EPISODE_VIEW_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \
|
||||||
|
@ -922,6 +923,8 @@ def initialize(consoleLogging=True):
|
||||||
PUSHBULLET_DEVICE_IDEN = check_setting_str(CFG, 'Pushbullet', 'pushbullet_device_iden', '')
|
PUSHBULLET_DEVICE_IDEN = check_setting_str(CFG, 'Pushbullet', 'pushbullet_device_iden', '')
|
||||||
|
|
||||||
USE_EMAIL = bool(check_setting_int(CFG, 'Email', 'use_email', 0))
|
USE_EMAIL = bool(check_setting_int(CFG, 'Email', 'use_email', 0))
|
||||||
|
EMAIL_OLD_SUBJECTS = bool(check_setting_int(CFG, 'Email', 'email_old_subjects',
|
||||||
|
None is not EMAIL_HOST and any(EMAIL_HOST)))
|
||||||
EMAIL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Email', 'email_notify_onsnatch', 0))
|
EMAIL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Email', 'email_notify_onsnatch', 0))
|
||||||
EMAIL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Email', 'email_notify_ondownload', 0))
|
EMAIL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Email', 'email_notify_ondownload', 0))
|
||||||
EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Email', 'email_notify_onsubtitledownload', 0))
|
EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Email', 'email_notify_onsubtitledownload', 0))
|
||||||
|
@ -1740,6 +1743,7 @@ def save_config():
|
||||||
|
|
||||||
new_config['Email'] = {}
|
new_config['Email'] = {}
|
||||||
new_config['Email']['use_email'] = int(USE_EMAIL)
|
new_config['Email']['use_email'] = int(USE_EMAIL)
|
||||||
|
new_config['Email']['email_old_subjects'] = int(EMAIL_OLD_SUBJECTS)
|
||||||
new_config['Email']['email_notify_onsnatch'] = int(EMAIL_NOTIFY_ONSNATCH)
|
new_config['Email']['email_notify_onsnatch'] = int(EMAIL_NOTIFY_ONSNATCH)
|
||||||
new_config['Email']['email_notify_ondownload'] = int(EMAIL_NOTIFY_ONDOWNLOAD)
|
new_config['Email']['email_notify_ondownload'] = int(EMAIL_NOTIFY_ONDOWNLOAD)
|
||||||
new_config['Email']['email_notify_onsubtitledownload'] = int(EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD)
|
new_config['Email']['email_notify_onsubtitledownload'] = int(EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD)
|
||||||
|
|
|
@ -19,191 +19,186 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import smtplib
|
|
||||||
from email.mime.multipart import MIMEMultipart
|
|
||||||
from email.mime.text import MIMEText
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import sickbeard
|
import sickbeard
|
||||||
|
import smtplib
|
||||||
|
|
||||||
from sickbeard import logger, common
|
|
||||||
from sickbeard import db
|
from sickbeard import db
|
||||||
from sickbeard.exceptions import ex
|
from sickbeard import logger
|
||||||
|
from sickbeard.common import notifyStrings, NOTIFY_SNATCH, NOTIFY_DOWNLOAD, NOTIFY_SUBTITLE_DOWNLOAD
|
||||||
|
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email.utils import formatdate
|
||||||
|
|
||||||
|
|
||||||
class EmailNotifier:
|
class EmailNotifier:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
self.last_err = None
|
self.last_err = None
|
||||||
|
|
||||||
def test_notify(self, host, port, smtp_from, use_tls, user, pwd, to):
|
def test_notify(self, host, port, smtp_from, use_tls, user, pwd, to):
|
||||||
msg = MIMEText('This is a test message from SickGear. If you\'re reading this, the test succeeded.')
|
|
||||||
msg['Subject'] = 'SickGear: Test Message'
|
msg = MIMEText('Success. This is a SickGear test message. Typically sent on, %s' %
|
||||||
|
notifyStrings[NOTIFY_DOWNLOAD])
|
||||||
|
msg['Subject'] = 'SickGear: Test message'
|
||||||
msg['From'] = smtp_from
|
msg['From'] = smtp_from
|
||||||
msg['To'] = to
|
msg['To'] = to
|
||||||
|
msg['Date'] = formatdate(localtime=True)
|
||||||
return self._sendmail(host, port, smtp_from, use_tls, user, pwd, [to], msg, True)
|
return self._sendmail(host, port, smtp_from, use_tls, user, pwd, [to], msg, True)
|
||||||
|
|
||||||
def notify_snatch(self, ep_name, title='Snatched:'):
|
def _send_email(self, title, ep_name, lang='', extra='', force=False):
|
||||||
|
|
||||||
|
if not sickbeard.USE_EMAIL and not force:
|
||||||
|
return
|
||||||
|
|
||||||
|
ep_name = ep_name.encode('utf-8', 'replace')
|
||||||
|
show = self._parse_ep(ep_name)
|
||||||
|
to = self._generate_recipients(show)
|
||||||
|
if not any(to):
|
||||||
|
logger.log(u'No email recipients to notify, skipping', logger.WARNING)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
msg = MIMEMultipart('alternative')
|
||||||
|
msg.attach(MIMEText(
|
||||||
|
'<body style="font-family:Helvetica, Arial, sans-serif;">' +
|
||||||
|
'<h3>SickGear Notification - %s</h3>\n' % title +
|
||||||
|
'<p>Show: <b>' + re.search('(.+?) -.+', ep_name).group(1) +
|
||||||
|
'</b></p>\n<p>Episode: <b>' + re.search('.+ - (.+?-.+) -.+', ep_name).group(1) +
|
||||||
|
extra +
|
||||||
|
'</b></p>\n\n' +
|
||||||
|
'<footer style="margin-top:2.5em;padding:.7em 0;color:#777;border-top:#BBB solid 1px;">' +
|
||||||
|
'Powered by SickGear.</footer></body>',
|
||||||
|
'html'))
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
msg = MIMEText(ep_name)
|
||||||
|
except:
|
||||||
|
msg = MIMEText('Episode %s' % title)
|
||||||
|
|
||||||
|
msg['Subject'] = '%s%s: %s' % (lang, title, ep_name)
|
||||||
|
msg['From'] = sickbeard.EMAIL_FROM
|
||||||
|
msg['To'] = ','.join(to)
|
||||||
|
msg['Date'] = formatdate(localtime=True)
|
||||||
|
if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS,
|
||||||
|
sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg):
|
||||||
|
logger.log(u'%s notification sent to [%s] for "%s"' % (title, to, ep_name), logger.DEBUG)
|
||||||
|
else:
|
||||||
|
logger.log(u'%s notification ERROR: %s' % (title, self.last_err), logger.ERROR)
|
||||||
|
|
||||||
|
def notify_snatch(self, ep_name, title=notifyStrings[NOTIFY_SNATCH]):
|
||||||
"""
|
"""
|
||||||
Send a notification that an episode was snatched
|
Send a notification that an episode was snatched
|
||||||
|
|
||||||
ep_name: The name of the episode that was snatched
|
:param ep_name: The name of the episode that was snatched
|
||||||
title: The title of the notification (optional)
|
:param title: The title of the notification (optional)
|
||||||
"""
|
"""
|
||||||
ep_name = ep_name.encode('utf-8', 'replace')
|
|
||||||
|
|
||||||
if sickbeard.EMAIL_NOTIFY_ONSNATCH:
|
if sickbeard.EMAIL_NOTIFY_ONSNATCH:
|
||||||
show = self._parseEp(ep_name)
|
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Snatched' or title
|
||||||
to = self._generate_recepients(show)
|
self._send_email(title, ep_name)
|
||||||
if len(to) == 0:
|
|
||||||
logger.log('Skipping email notification because there are no configured recepients', logger.WARNING)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
msg = MIMEMultipart('alternative')
|
|
||||||
msg.attach(MIMEText(
|
|
||||||
"<body style='font-family:Helvetica, Arial, sans-serif;'><h3>SickGear Notification - Snatched</h3>\n<p>Show: <b>" + re.search(
|
|
||||||
'(.+?) -.+', ep_name).group(1) + '</b></p>\n<p>Episode: <b>' + re.search(
|
|
||||||
'.+ - (.+?-.+) -.+', ep_name).group(
|
|
||||||
1) + "</b></p>\n\n<footer style='margin-top: 2.5em; padding: .7em 0; color: #777; border-top: #BBB solid 1px;'>Powered by SickGear.</footer></body>",
|
|
||||||
'html'))
|
|
||||||
except:
|
|
||||||
msg = MIMEText(ep_name)
|
|
||||||
|
|
||||||
msg['Subject'] = 'Snatched: ' + ep_name
|
def notify_download(self, ep_name, title=notifyStrings[NOTIFY_DOWNLOAD]):
|
||||||
msg['From'] = sickbeard.EMAIL_FROM
|
|
||||||
msg['To'] = ','.join(to)
|
|
||||||
if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS,
|
|
||||||
sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg):
|
|
||||||
logger.log('Snatch notification sent to [%s] for "%s"' % (to, ep_name), logger.DEBUG)
|
|
||||||
else:
|
|
||||||
logger.log('Snatch notification ERROR: %s' % self.last_err, logger.ERROR)
|
|
||||||
|
|
||||||
def notify_download(self, ep_name, title='Completed:'):
|
|
||||||
"""
|
"""
|
||||||
Send a notification that an episode was downloaded
|
Send a notification that an episode was downloaded
|
||||||
|
|
||||||
ep_name: The name of the episode that was downloaded
|
:param ep_name: The name of the episode that was downloaded
|
||||||
title: The title of the notification (optional)
|
:param title: The title of the notification (optional)
|
||||||
"""
|
"""
|
||||||
ep_name = ep_name.encode('utf-8', 'replace')
|
|
||||||
|
|
||||||
if sickbeard.EMAIL_NOTIFY_ONDOWNLOAD:
|
if sickbeard.EMAIL_NOTIFY_ONDOWNLOAD:
|
||||||
show = self._parseEp(ep_name)
|
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Downloaded' or title
|
||||||
to = self._generate_recepients(show)
|
self._send_email(title, ep_name)
|
||||||
if len(to) == 0:
|
|
||||||
logger.log('Skipping email notification because there are no configured recepients', logger.WARNING)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
msg = MIMEMultipart('alternative')
|
|
||||||
msg.attach(MIMEText(
|
|
||||||
"<body style='font-family:Helvetica, Arial, sans-serif;'><h3>SickGear Notification - Downloaded</h3>\n<p>Show: <b>" + re.search(
|
|
||||||
'(.+?) -.+', ep_name).group(1) + '</b></p>\n<p>Episode: <b>' + re.search(
|
|
||||||
'.+ - (.+?-.+) -.+', ep_name).group(
|
|
||||||
1) + "</b></p>\n\n<footer style='margin-top: 2.5em; padding: .7em 0; color: #777; border-top: #BBB solid 1px;'>Powered by SickGear.</footer></body>",
|
|
||||||
'html'))
|
|
||||||
except:
|
|
||||||
msg = MIMEText(ep_name)
|
|
||||||
|
|
||||||
msg['Subject'] = 'Downloaded: ' + ep_name
|
def notify_subtitle_download(self, ep_name, lang, title=notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD]):
|
||||||
msg['From'] = sickbeard.EMAIL_FROM
|
|
||||||
msg['To'] = ','.join(to)
|
|
||||||
if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS,
|
|
||||||
sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg):
|
|
||||||
logger.log('Download notification sent to [%s] for "%s"' % (to, ep_name), logger.DEBUG)
|
|
||||||
else:
|
|
||||||
logger.log('Download notification ERROR: %s' % self.last_err, logger.ERROR)
|
|
||||||
|
|
||||||
def notify_subtitle_download(self, ep_name, lang, title='Downloaded subtitle:'):
|
|
||||||
"""
|
"""
|
||||||
Send a notification that an subtitle was downloaded
|
Send a notification that a subtitle was downloaded
|
||||||
|
|
||||||
ep_name: The name of the episode that was downloaded
|
:param ep_name: The name of the episode that was downloaded
|
||||||
lang: Subtitle language wanted
|
:param lang: Subtitle language
|
||||||
|
:param title: The title of the notification (optional)
|
||||||
"""
|
"""
|
||||||
ep_name = ep_name.encode('utf-8', 'replace')
|
|
||||||
|
|
||||||
if sickbeard.EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD:
|
if sickbeard.EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD:
|
||||||
show = self._parseEp(ep_name)
|
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Subtitle Downloaded' or title
|
||||||
to = self._generate_recepients(show)
|
self._send_email(title, ep_name, '%s ' % lang, '</b></p>\n<p>Language: <b>%s' % lang)
|
||||||
if len(to) == 0:
|
|
||||||
logger.log('Skipping email notification because there are no configured recepients', logger.WARNING)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
msg = MIMEMultipart('alternative')
|
|
||||||
msg.attach(MIMEText(
|
|
||||||
"<body style='font-family:Helvetica, Arial, sans-serif;'><h3>SickGear Notification - Subtitle Downloaded</h3>\n<p>Show: <b>" + re.search(
|
|
||||||
'(.+?) -.+', ep_name).group(1) + '</b></p>\n<p>Episode: <b>' + re.search(
|
|
||||||
'.+ - (.+?-.+) -.+', ep_name).group(
|
|
||||||
1) + '</b></p>\n<p>Language: <b>' + lang + "</b></p>\n\n<footer style='margin-top: 2.5em; padding: .7em 0; color: #777; border-top: #BBB solid 1px;'>Powered by SickGear.</footer></body>",
|
|
||||||
'html'))
|
|
||||||
except:
|
|
||||||
msg = MIMEText(ep_name + ': ' + lang)
|
|
||||||
|
|
||||||
msg['Subject'] = lang + ' Subtitle Downloaded: ' + ep_name
|
|
||||||
msg['From'] = sickbeard.EMAIL_FROM
|
|
||||||
msg['To'] = ','.join(to)
|
|
||||||
if self._sendmail(sickbeard.EMAIL_HOST, sickbeard.EMAIL_PORT, sickbeard.EMAIL_FROM, sickbeard.EMAIL_TLS,
|
|
||||||
sickbeard.EMAIL_USER, sickbeard.EMAIL_PASSWORD, to, msg):
|
|
||||||
logger.log('Download notification sent to [%s] for "%s"' % (to, ep_name), logger.DEBUG)
|
|
||||||
else:
|
|
||||||
logger.log('Download notification ERROR: %s' % self.last_err, logger.ERROR)
|
|
||||||
|
|
||||||
|
|
||||||
def notify_git_update(self, new_version='??'):
|
def notify_git_update(self, new_version='??'):
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _generate_recepients(self, show):
|
@staticmethod
|
||||||
|
def _generate_recipients(show):
|
||||||
|
|
||||||
addrs = []
|
addrs = []
|
||||||
|
|
||||||
# Grab the global recipients
|
# Grab the global recipients
|
||||||
|
if sickbeard.EMAIL_LIST:
|
||||||
for addr in sickbeard.EMAIL_LIST.split(','):
|
for addr in sickbeard.EMAIL_LIST.split(','):
|
||||||
if (len(addr.strip()) > 0):
|
if any(addr.strip()):
|
||||||
addrs.append(addr)
|
addrs.append(addr)
|
||||||
|
|
||||||
# Grab the recipients for the show
|
# Grab the recipients for the show
|
||||||
myDB = db.DBConnection()
|
if None is not show:
|
||||||
for s in show:
|
my_db = db.DBConnection()
|
||||||
for subs in myDB.select('SELECT notify_list FROM tv_shows WHERE show_name = ?', (s,)):
|
for name in show:
|
||||||
|
for subs in my_db.select('SELECT notify_list FROM tv_shows WHERE show_name = ?', (name,)):
|
||||||
if subs['notify_list']:
|
if subs['notify_list']:
|
||||||
for addr in subs['notify_list'].split(','):
|
for addr in subs['notify_list'].split(','):
|
||||||
if (len(addr.strip()) > 0):
|
if any(addr.strip()):
|
||||||
addrs.append(addr)
|
addrs.append(addr)
|
||||||
|
|
||||||
addrs = set(addrs)
|
addrs = set(addrs)
|
||||||
logger.log('Notification recepients: %s' % addrs, logger.DEBUG)
|
logger.log(u'Email recipients to notify: %s' % addrs, logger.DEBUG)
|
||||||
|
|
||||||
return addrs
|
return addrs
|
||||||
|
|
||||||
def _sendmail(self, host, port, smtp_from, use_tls, user, pwd, to, msg, smtpDebug=False):
|
def _sendmail(self, host, port, smtp_from, use_tls, user, pwd, to, msg, smtp_debug=False):
|
||||||
logger.log('HOST: %s; PORT: %s; FROM: %s, TLS: %s, USER: %s, PWD: %s, TO: %s' % (
|
|
||||||
host, port, smtp_from, use_tls, user, pwd, to), logger.DEBUG)
|
use_tls = 1 == sickbeard.helpers.tryInt(use_tls)
|
||||||
|
login = any(user) and any(pwd)
|
||||||
|
logger.log(u'Sendmail HOST: %s; PORT: %s; LOGIN: %s, TLS: %s, USER: %s, FROM: %s, TO: %s' % (
|
||||||
|
host, port, login, use_tls, user, smtp_from, to), logger.DEBUG)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
srv = smtplib.SMTP(host, int(port))
|
srv = smtplib.SMTP(host, int(port))
|
||||||
if smtpDebug:
|
if smtp_debug:
|
||||||
srv.set_debuglevel(1)
|
srv.set_debuglevel(1)
|
||||||
if (use_tls == '1' or use_tls == True) or (len(user) > 0 and len(pwd) > 0):
|
|
||||||
|
if use_tls or login:
|
||||||
srv.ehlo()
|
srv.ehlo()
|
||||||
logger.log('Sent initial EHLO command!', logger.DEBUG)
|
logger.log(u'Sent initial EHLO command', logger.DEBUG)
|
||||||
if use_tls == '1' or use_tls == True:
|
|
||||||
|
if use_tls:
|
||||||
srv.starttls()
|
srv.starttls()
|
||||||
logger.log('Sent STARTTLS command!', logger.DEBUG)
|
srv.ehlo()
|
||||||
if len(user) > 0 and len(pwd) > 0:
|
logger.log(u'Sent STARTTLS and EHLO command', logger.DEBUG)
|
||||||
|
|
||||||
|
if login:
|
||||||
srv.login(user, pwd)
|
srv.login(user, pwd)
|
||||||
logger.log('Sent LOGIN command!', logger.DEBUG)
|
logger.log(u'Sent LOGIN command', logger.DEBUG)
|
||||||
|
|
||||||
srv.sendmail(smtp_from, to, msg.as_string())
|
srv.sendmail(smtp_from, to, msg.as_string())
|
||||||
srv.quit()
|
srv.quit()
|
||||||
return True
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.last_err = '%s' % e
|
self.last_err = '%s' % e
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _parseEp(self, ep_name):
|
return True
|
||||||
ep_name = ep_name.encode('utf-8', 'replace')
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_ep(ep_name):
|
||||||
|
|
||||||
|
ep_name = ep_name.encode('utf-8', 'replace')
|
||||||
sep = ' - '
|
sep = ' - '
|
||||||
titles = ep_name.split(sep)
|
titles = ep_name.split(sep)
|
||||||
titles.sort(key=len, reverse=True)
|
titles.sort(key=len, reverse=True)
|
||||||
logger.log('TITLES: %s' % titles, logger.DEBUG)
|
logger.log(u'TITLES: %s' % titles, logger.DEBUG)
|
||||||
|
|
||||||
return titles
|
return titles
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -937,16 +937,38 @@ class Home(MainHandler):
|
||||||
def loadShowNotifyLists(self, *args, **kwargs):
|
def loadShowNotifyLists(self, *args, **kwargs):
|
||||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||||
|
|
||||||
myDB = db.DBConnection()
|
my_db = db.DBConnection()
|
||||||
rows = myDB.select('SELECT show_id, show_name, notify_list FROM tv_shows ORDER BY show_name ASC')
|
rows = my_db.select('SELECT indexer_id, indexer, notify_list FROM tv_shows ' +
|
||||||
|
'WHERE notify_list NOTNULL and notify_list != ""')
|
||||||
|
notify_lists = {}
|
||||||
|
for r in filter(lambda x: x['notify_list'].strip(), rows):
|
||||||
|
notify_lists['%s_%s' % (r['indexer'], r['indexer_id'])] = r['notify_list']
|
||||||
|
|
||||||
data = {}
|
sorted_show_lists = self.sorted_show_lists()
|
||||||
size = 0
|
response = []
|
||||||
for r in rows:
|
for current_group in sorted_show_lists:
|
||||||
data[r['show_id']] = {'id': r['show_id'], 'name': r['show_name'], 'list': r['notify_list']}
|
data = []
|
||||||
size += 1
|
for current_show in current_group[1]:
|
||||||
data['_size'] = size
|
uid = '%s_%s' % (current_show.indexer, current_show.indexerid)
|
||||||
return json.dumps(data)
|
data.append({'id': uid, 'name': current_show.name,
|
||||||
|
'list': '' if uid not in notify_lists else notify_lists[uid]})
|
||||||
|
if data:
|
||||||
|
response.append({current_group[0]: data})
|
||||||
|
|
||||||
|
return json.dumps(response)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def save_show_email(show=None, emails=None):
|
||||||
|
# self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||||
|
|
||||||
|
my_db = db.DBConnection()
|
||||||
|
success = False
|
||||||
|
parse = show.split('_')
|
||||||
|
if 1 < len(parse) and \
|
||||||
|
my_db.action('UPDATE tv_shows SET notify_list = ? WHERE indexer = ? AND indexer_id = ?',
|
||||||
|
[emails, parse[0], parse[1]]):
|
||||||
|
success = True
|
||||||
|
return json.dumps({'id': show, 'success': success})
|
||||||
|
|
||||||
def testEmail(self, host=None, port=None, smtp_from=None, use_tls=None, user=None, pwd=None, to=None):
|
def testEmail(self, host=None, port=None, smtp_from=None, use_tls=None, user=None, pwd=None, to=None):
|
||||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||||
|
@ -956,8 +978,7 @@ class Home(MainHandler):
|
||||||
host = config.clean_host(host)
|
host = config.clean_host(host)
|
||||||
|
|
||||||
if notifiers.email_notifier.test_notify(host, port, smtp_from, use_tls, user, pwd, to):
|
if notifiers.email_notifier.test_notify(host, port, smtp_from, use_tls, user, pwd, to):
|
||||||
return 'Test email sent successfully! Check inbox.'
|
return 'Success. Test email sent. Check inbox.'
|
||||||
else:
|
|
||||||
return 'ERROR: %s' % notifiers.email_notifier.last_err
|
return 'ERROR: %s' % notifiers.email_notifier.last_err
|
||||||
|
|
||||||
def testNMA(self, nma_api=None, nma_priority=0):
|
def testNMA(self, nma_api=None, nma_priority=0):
|
||||||
|
@ -1217,32 +1238,11 @@ class Home(MainHandler):
|
||||||
display_seasons += [1]
|
display_seasons += [1]
|
||||||
display_seasons += [highest_season]
|
display_seasons += [highest_season]
|
||||||
|
|
||||||
def titler(x):
|
t.sortedShowLists = self.sorted_show_lists()
|
||||||
return (remove_article(x), x)[not x or sickbeard.SORT_ARTICLE]
|
|
||||||
|
|
||||||
if sickbeard.SHOWLIST_TAGVIEW == 'custom':
|
|
||||||
t.sortedShowLists = []
|
|
||||||
for tag in sickbeard.SHOW_TAGS:
|
|
||||||
results = filter(lambda x: x.tag == tag, sickbeard.showList)
|
|
||||||
if results:
|
|
||||||
t.sortedShowLists.append([tag, sorted(results, lambda x, y: cmp(titler(x.name), titler(y.name)))])
|
|
||||||
elif sickbeard.SHOWLIST_TAGVIEW == 'anime':
|
|
||||||
shows = []
|
|
||||||
anime = []
|
|
||||||
for show in sickbeard.showList:
|
|
||||||
if show.is_anime:
|
|
||||||
anime.append(show)
|
|
||||||
else:
|
|
||||||
shows.append(show)
|
|
||||||
t.sortedShowLists = [['Shows', sorted(shows, lambda x, y: cmp(titler(x.name), titler(y.name)))],
|
|
||||||
['Anime', sorted(anime, lambda x, y: cmp(titler(x.name), titler(y.name)))]]
|
|
||||||
|
|
||||||
else:
|
|
||||||
t.sortedShowLists = [
|
|
||||||
['Show List', sorted(sickbeard.showList, lambda x, y: cmp(titler(x.name), titler(y.name)))]]
|
|
||||||
|
|
||||||
tvshows = []
|
tvshows = []
|
||||||
tvshow_names = []
|
tvshow_names = []
|
||||||
|
cur_sel = None
|
||||||
for tvshow_types in t.sortedShowLists:
|
for tvshow_types in t.sortedShowLists:
|
||||||
for tvshow in tvshow_types[1]:
|
for tvshow in tvshow_types[1]:
|
||||||
tvshows.append(tvshow.indexerid)
|
tvshows.append(tvshow.indexerid)
|
||||||
|
@ -1252,6 +1252,9 @@ class Home(MainHandler):
|
||||||
t.tvshow_id_csv = ','.join(str(x) for x in tvshows)
|
t.tvshow_id_csv = ','.join(str(x) for x in tvshows)
|
||||||
|
|
||||||
last_item = len(tvshow_names)
|
last_item = len(tvshow_names)
|
||||||
|
t.prev_title = ''
|
||||||
|
t.next_title = ''
|
||||||
|
if cur_sel:
|
||||||
t.prev_title = 'Prev show, %s' % tvshow_names[(cur_sel - 2, last_item - 1)[1 == cur_sel]]
|
t.prev_title = 'Prev show, %s' % tvshow_names[(cur_sel - 2, last_item - 1)[1 == cur_sel]]
|
||||||
t.next_title = 'Next show, %s' % tvshow_names[(cur_sel, 0)[last_item == cur_sel]]
|
t.next_title = 'Next show, %s' % tvshow_names[(cur_sel, 0)[last_item == cur_sel]]
|
||||||
|
|
||||||
|
@ -1276,6 +1279,35 @@ class Home(MainHandler):
|
||||||
|
|
||||||
return t.respond()
|
return t.respond()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sorted_show_lists():
|
||||||
|
|
||||||
|
def titler(x):
|
||||||
|
return (remove_article(x), x)[not x or sickbeard.SORT_ARTICLE]
|
||||||
|
|
||||||
|
if 'custom' == sickbeard.SHOWLIST_TAGVIEW:
|
||||||
|
sorted_show_lists = []
|
||||||
|
for tag in sickbeard.SHOW_TAGS:
|
||||||
|
results = filter(lambda x: x.tag == tag, sickbeard.showList)
|
||||||
|
if results:
|
||||||
|
sorted_show_lists.append([tag, sorted(results, lambda x, y: cmp(titler(x.name), titler(y.name)))])
|
||||||
|
elif 'anime' == sickbeard.SHOWLIST_TAGVIEW:
|
||||||
|
shows = []
|
||||||
|
anime = []
|
||||||
|
for show in sickbeard.showList:
|
||||||
|
if show.is_anime:
|
||||||
|
anime.append(show)
|
||||||
|
else:
|
||||||
|
shows.append(show)
|
||||||
|
sorted_show_lists = [['Shows', sorted(shows, lambda x, y: cmp(titler(x.name), titler(y.name)))],
|
||||||
|
['Anime', sorted(anime, lambda x, y: cmp(titler(x.name), titler(y.name)))]]
|
||||||
|
|
||||||
|
else:
|
||||||
|
sorted_show_lists = [
|
||||||
|
['Show List', sorted(sickbeard.showList, lambda x, y: cmp(titler(x.name), titler(y.name)))]]
|
||||||
|
|
||||||
|
return sorted_show_lists
|
||||||
|
|
||||||
def plotDetails(self, show, season, episode):
|
def plotDetails(self, show, season, episode):
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
result = myDB.select(
|
result = myDB.select(
|
||||||
|
|
Loading…
Reference in a new issue