Add Emby notifier

This commit is contained in:
Supremicus 2016-02-13 21:36:02 +10:00
parent c25452e2db
commit 0fc796c78f
16 changed files with 238 additions and 8 deletions

View file

@ -30,6 +30,7 @@
* Allow episode status "Skipped" to be changed to "Downloaded" * Allow episode status "Skipped" to be changed to "Downloaded"
* Allow found "Skipped" episode files to be set "Unknown" quality * Allow found "Skipped" episode files to be set "Unknown" quality
* Add CPU throttling preset "Disabled" to config/General/Advanced Settings * Add CPU throttling preset "Disabled" to config/General/Advanced Settings
* Add Emby notifier
### 0.11.5 (2016-02-01 19:40:00 UTC) ### 0.11.5 (2016-02-01 19:40:00 UTC)

Binary file not shown.

View file

@ -42,4 +42,5 @@
<glyph unicode="&#xe620;" d="M729.285 747.346c-9.132-30.831-28.073-51.848-37.205-82.679-132.709 71.811-295.755 38.606-380.324-41.339-120.632-114.044-110.831-335.021 0-458.869 104.56-116.85 295.774-154.495 525.012-140.554-38.264-16.616-85.433-33.193-140.556-37.206-82.799-6.027-196.406-14.449-276.974 0-39.848 7.146-91.010 43.376-119.884 66.144-167.865 132.35-233.101 424.197-74.409 611.825 100.933 119.34 325.516 182.221 504.34 82.678zM526.722 916.838c-1.84-32.609-8.412-60.484-8.267-95.081-248.806 3.894-421.217-176.218-421.663-421.663-0.358-197.764 115.293-316.215 235.636-409.261-183.138-3.013-286.509 139.053-318.316 305.912-36.184 189.848 44.123 381.295 157.092 487.807 82.29 77.591 202.286 138.542 355.518 132.286zM1018.661 164.459c-23.41-31.934-62.158-88.67-107.481-103.35-72.378-23.441-259.309-5.489-326.582 8.268-171.37 35.052-339.531 130.938-330.718 338.985 6.652 157.072 126.784 274.099 293.511 268.708 114.164-3.691 186.047-59.381 239.768-148.822-26.79-14.546-53.652-29.025-78.545-45.473-95.176 170.786-386.294 111.183-359.652-115.754 4.832-41.173 24.663-73.938 45.473-99.213 113.596-137.978 395.536-131.411 624.226-103.349z" /> <glyph unicode="&#xe620;" d="M729.285 747.346c-9.132-30.831-28.073-51.848-37.205-82.679-132.709 71.811-295.755 38.606-380.324-41.339-120.632-114.044-110.831-335.021 0-458.869 104.56-116.85 295.774-154.495 525.012-140.554-38.264-16.616-85.433-33.193-140.556-37.206-82.799-6.027-196.406-14.449-276.974 0-39.848 7.146-91.010 43.376-119.884 66.144-167.865 132.35-233.101 424.197-74.409 611.825 100.933 119.34 325.516 182.221 504.34 82.678zM526.722 916.838c-1.84-32.609-8.412-60.484-8.267-95.081-248.806 3.894-421.217-176.218-421.663-421.663-0.358-197.764 115.293-316.215 235.636-409.261-183.138-3.013-286.509 139.053-318.316 305.912-36.184 189.848 44.123 381.295 157.092 487.807 82.29 77.591 202.286 138.542 355.518 132.286zM1018.661 164.459c-23.41-31.934-62.158-88.67-107.481-103.35-72.378-23.441-259.309-5.489-326.582 8.268-171.37 35.052-339.531 130.938-330.718 338.985 6.652 157.072 126.784 274.099 293.511 268.708 114.164-3.691 186.047-59.381 239.768-148.822-26.79-14.546-53.652-29.025-78.545-45.473-95.176 170.786-386.294 111.183-359.652-115.754 4.832-41.173 24.663-73.938 45.473-99.213 113.596-137.978 395.536-131.411 624.226-103.349z" />
<glyph unicode="&#xe621;" d="M4.283 787.656c7.274-57.855 34.374-98.399 78.67-119.196 38.761-18.203 94.99-7.272 147.8-11.918 121.794-10.718 187.114-118.102 185.942-214.548-1.327-109.177-85.133-194.234-185.942-202.633-34.385-2.865-67.842 5.006-107.273 0-70.178-8.906-108.898-56.879-119.195-138.263 87.799 4.418 170.766-5.942 247.926 0 125.395 9.656 202.723 87.278 259.842 164.488 57.558-77.95 135.042-155.379 262.226-164.488 76.165-5.456 158.659 4.056 245.54 0-5.646 62.881-31.961 102.074-73.9 123.963-42.755 22.31-99.255 8.868-154.953 14.301-242.313 23.646-239.659 396.828 4.766 417.183 36.153 3.011 70.608-4.252 104.892 0 72.445 8.981 109.527 59.474 119.194 138.264-87.783-4.638-170.775 6.243-247.925 0-125.192-10.134-202.138-87.567-259.843-164.49-56.746 78.254-140.256 155.752-262.225 164.49-71.555 5.126-152.863-3.755-243.154 0-2.777-0.399-2.588-3.768-2.385-7.153h-0.003z" /> <glyph unicode="&#xe621;" d="M4.283 787.656c7.274-57.855 34.374-98.399 78.67-119.196 38.761-18.203 94.99-7.272 147.8-11.918 121.794-10.718 187.114-118.102 185.942-214.548-1.327-109.177-85.133-194.234-185.942-202.633-34.385-2.865-67.842 5.006-107.273 0-70.178-8.906-108.898-56.879-119.195-138.263 87.799 4.418 170.766-5.942 247.926 0 125.395 9.656 202.723 87.278 259.842 164.488 57.558-77.95 135.042-155.379 262.226-164.488 76.165-5.456 158.659 4.056 245.54 0-5.646 62.881-31.961 102.074-73.9 123.963-42.755 22.31-99.255 8.868-154.953 14.301-242.313 23.646-239.659 396.828 4.766 417.183 36.153 3.011 70.608-4.252 104.892 0 72.445 8.981 109.527 59.474 119.194 138.264-87.783-4.638-170.775 6.243-247.925 0-125.192-10.134-202.138-87.567-259.843-164.49-56.746 78.254-140.256 155.752-262.225 164.49-71.555 5.126-152.863-3.755-243.154 0-2.777-0.399-2.588-3.768-2.385-7.153h-0.003z" />
<glyph unicode="&#xe622;" d="M141.308 212.259c-74.194 0-134.474-60.515-134.474-134.262 0-74.15 60.285-133.986 134.472-133.986 74.459 0 134.675 59.84 134.675 133.986-0.001 73.747-60.21 134.262-134.673 134.262zM6.988 609.88v-193.637c126.078 0 244.648-49.305 333.939-138.637 89.178-89.113 138.41-208.223 138.41-334.772h194.488c0 367.842-299.23 667.046-666.837 667.046zM7.217 953.166v-193.735c449.698 0 815.72-366.379 815.72-816.597h194.229c0 556.934-453.123 1010.332-1009.949 1010.332z" /> <glyph unicode="&#xe622;" d="M141.308 212.259c-74.194 0-134.474-60.515-134.474-134.262 0-74.15 60.285-133.986 134.472-133.986 74.459 0 134.675 59.84 134.675 133.986-0.001 73.747-60.21 134.262-134.673 134.262zM6.988 609.88v-193.637c126.078 0 244.648-49.305 333.939-138.637 89.178-89.113 138.41-208.223 138.41-334.772h194.488c0 367.842-299.23 667.046-666.837 667.046zM7.217 953.166v-193.735c449.698 0 815.72-366.379 815.72-816.597h194.229c0 556.934-453.123 1010.332-1009.949 1010.332z" />
<glyph unicode="&#xe900;" d="M1016.803 487.017l-269.009 269.004-40.713-40.711-237.49 237.489-269.009-269.007 42.409-42.409-235.794-235.791 269.009-269.006 40.712 40.713 234.099-234.099 269.009 269.006-39.017 39.017 235.794 235.794zM396.084 255.013v382.247l327.964-189.976-327.964-192.271z" />
</font></defs></svg> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Binary file not shown.

View file

@ -126,14 +126,14 @@ fonts
font-style:italic font-style:italic
} }
/* Droid Sans */ /* SickGear Icons */
@font-face{ @font-face{
font-family:'sgicons'; font-family:'sgicons';
src:url('fonts/sgicons.eot'); src:url('fonts/sgicons.eot?v1');
src:url('fonts/sgicons.eot?#iefix') format('embedded-opentype'), src:url('fonts/sgicons.eot?v1#iefix') format('embedded-opentype'),
url('fonts/sgicons.woff') format('woff'), url('fonts/sgicons.woff?v1') format('woff'),
url('fonts/sgicons.ttf') format('truetype'), url('fonts/sgicons.ttf?v1') format('truetype'),
url('fonts/sgicons.svg#sgicons') format('svg'); url('fonts/sgicons.svg?v1#sgicons') format('svg');
font-weight:normal; font-weight:normal;
font-style:normal font-style:normal
} }
@ -499,6 +499,10 @@ inc_top.tmpl
content:"\e621" content:"\e621"
} }
.sgicon-emby:before {
content: "\e900"
}
/* ======================================================================= /* =======================================================================
inc_bottom.tmpl inc_bottom.tmpl
========================================================================== */ ========================================================================== */

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -401,6 +401,47 @@
</fieldset> </fieldset>
</div><!-- /plex component-group --> </div><!-- /plex component-group -->
<div class="component-group">
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/emby.png" alt="" title="Emby" />
<h3><a href="<%= anon_url('http://emby.media/') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Emby</a></h3>
<p>Emby is a home media server built using other popular open source technologies.</p>
</div>
<fieldset class="component-group-list">
<div class="field-pair">
<label class="cleafix" for="use_emby">
<span class="component-title">Enable</span>
<span class="component-desc">
<input type="checkbox" class="enabler" name="use_emby" id="use_emby" #if $sickbeard.USE_EMBY then 'checked="checked"' else ''#>
<p>should SickGear send update commands to Emby ?</p>
</span>
</label>
</div>
<div id="content_use_emby">
<div class="field-pair">
<label for="emby_host">
<span class="component-title">Emby server IP:Port</span>
<span class="component-desc">
<input type="text" name="emby_host" id="emby_host" value="$sickbeard.EMBY_HOST" class="form-control input-sm input250">
<div class="clear-left"><p>host running Emby server (e.g. 192.168.0.1:8096)</p></div>
</span>
</label>
</div>
<div class="field-pair">
<label for="emby_apikey">
<span class="component-title">Emby API key</span>
<span class="component-desc">
<input type="text" name="emby_apikey" id="emby_apikey" value="<%= starify(sickbeard.EMBY_APIKEY) %>" class="form-control input-sm input250">
<div class="clear-left"><p>(Emby server > Advanced > Security)</p></div>
</span>
</label>
</div>
<div class="testNotification" id="testEMBY-result">Click below to test.</div>
<input class="btn" type="button" value="Test Emby" id="testEMBY">
<input type="submit" class="config_submitter btn" value="Save Changes">
</div><!-- /content_use_emby //-->
</fieldset>
</div><!-- /emby component-group //-->
<div class="component-group"> <div class="component-group">
<div class="component-group-desc"> <div class="component-group-desc">

View file

@ -134,6 +134,9 @@
#if $sickbeard.USE_KODI and $sickbeard.KODI_HOST != '' #if $sickbeard.USE_KODI and $sickbeard.KODI_HOST != ''
<li><a href="$sbRoot/home/updateKODI/" tabindex="$tab#set $tab += 1#"><i class="sgicon-kodi"></i>Update Kodi</a></li> <li><a href="$sbRoot/home/updateKODI/" tabindex="$tab#set $tab += 1#"><i class="sgicon-kodi"></i>Update Kodi</a></li>
#end if #end if
#if $sickbeard.USE_EMBY and $sickbeard.EMBY_HOST != '' and $sickbeard.EMBY_APIKEY != ''
<li><a href="$sbRoot/home/updateEMBY/" tabindex="$tab#set $tab += 1#"><i class="sgicon-emby"></i>Update Emby</a></li>
#end if
#if $sickbeard.USE_FAILED_DOWNLOADS #if $sickbeard.USE_FAILED_DOWNLOADS
<li><a href="$sbRoot/manage/failedDownloads/" tabindex="$tab#set $tab += 1#"><i class="sgicon-failed"></i>Failed Downloads</a></li> <li><a href="$sbRoot/manage/failedDownloads/" tabindex="$tab#set $tab += 1#"><i class="sgicon-failed"></i>Failed Downloads</a></li>
#end if #end if

View file

@ -123,6 +123,33 @@
}); });
}); });
$('#testEMBY').click(function () {
var emby_host = $('#emby_host').val();
var emby_apikey = $('#emby_apikey').val();
if (!emby_host || !emby_apikey) {
$('#testEMBY-result').html('Please fill out the necessary fields above.');
if (!emby_host) {
$('#emby_host').addClass('warning');
} else {
$('#emby_host').removeClass('warning');
}
if (!emby_apikey) {
$('#emby_apikey').addClass('warning');
} else {
$('#emby_apikey').removeClass('warning');
}
return;
}
$('#emby_host, #emby_apikey').removeClass('warning');
$(this).prop('disabled', true);
$('#testEMBY-result').html(loading);
$.get(sbRoot + '/home/testEMBY', {'host': emby_host, 'emby_apikey': emby_apikey})
.done(function (data) {
$('#testEMBY-result').html(data);
$('#testEMBY').prop('disabled', false);
});
});
$('#testBoxcar2').click(function () { $('#testBoxcar2').click(function () {
var boxcar2_accesstoken = $.trim($('#boxcar2_accesstoken').val()); var boxcar2_accesstoken = $.trim($('#boxcar2_accesstoken').val());
var boxcar2_sound = $('#boxcar2_sound').val() || 'default'; var boxcar2_sound = $('#boxcar2_sound').val() || 'default';

View file

@ -31,6 +31,7 @@ function initActions() {
$('#SubMenu a[href$="/home/updateXBMC/"]').addClass('btn').html('<i class="sgicon-xbmc"></i>Update XBMC'); $('#SubMenu a[href$="/home/updateXBMC/"]').addClass('btn').html('<i class="sgicon-xbmc"></i>Update XBMC');
$('#SubMenu a:contains("Update show in Kodi")').addClass('btn').html('<i class="sgicon-kodi"></i>Update show in Kodi'); $('#SubMenu a:contains("Update show in Kodi")').addClass('btn').html('<i class="sgicon-kodi"></i>Update show in Kodi');
$('#SubMenu a[href$="/home/updateKODI/"]').addClass('btn').html('<i class="sgicon-kodi"></i>Update Kodi'); $('#SubMenu a[href$="/home/updateKODI/"]').addClass('btn').html('<i class="sgicon-kodi"></i>Update Kodi');
$('#SubMenu a[href$="/home/updateEMBY/"]').addClass('btn').html('<i class="sgicon-emby"></i>Update Emby');
} }
$(document).ready(function(){ $(document).ready(function(){

View file

@ -287,6 +287,10 @@ PLEX_HOST = None
PLEX_USERNAME = None PLEX_USERNAME = None
PLEX_PASSWORD = None PLEX_PASSWORD = None
USE_EMBY = False
EMBY_HOST = None
EMBY_APIKEY = None
USE_GROWL = False USE_GROWL = False
GROWL_NOTIFY_ONSNATCH = False GROWL_NOTIFY_ONSNATCH = False
GROWL_NOTIFY_ONDOWNLOAD = False GROWL_NOTIFY_ONDOWNLOAD = False
@ -492,8 +496,8 @@ def initialize(consoleLogging=True):
XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \ XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \
USE_KODI, KODI_ALWAYS_ON, KODI_NOTIFY_ONSNATCH, KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD, KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, KODI_UPDATE_LIBRARY, KODI_HOST, KODI_USERNAME, KODI_PASSWORD, \ USE_KODI, KODI_ALWAYS_ON, KODI_NOTIFY_ONSNATCH, KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD, KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, KODI_UPDATE_LIBRARY, KODI_HOST, KODI_USERNAME, KODI_PASSWORD, \
USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \ USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \ USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, \
PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, MAX_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \ USE_EMBY, EMBY_HOST, EMBY_APIKEY, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, MAX_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \
showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, HOME_SEARCH_FOCUS, SORT_ARTICLE, showList, loadingShowList, UPDATE_SHOWS_ON_START, SHOW_UPDATE_HOUR, ALLOW_INCOMPLETE_SHOWDATA, \ showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, HOME_SEARCH_FOCUS, SORT_ARTICLE, showList, loadingShowList, UPDATE_SHOWS_ON_START, SHOW_UPDATE_HOUR, ALLOW_INCOMPLETE_SHOWDATA, \
NEWZNAB_DATA, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \ NEWZNAB_DATA, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \
QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, RECENTSEARCH_STARTUP, \ QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, RECENTSEARCH_STARTUP, \
@ -538,6 +542,7 @@ def initialize(consoleLogging=True):
CheckSection(CFG, 'XBMC') CheckSection(CFG, 'XBMC')
CheckSection(CFG, 'Kodi') CheckSection(CFG, 'Kodi')
CheckSection(CFG, 'PLEX') CheckSection(CFG, 'PLEX')
CheckSection(CFG, 'Emby')
CheckSection(CFG, 'Growl') CheckSection(CFG, 'Growl')
CheckSection(CFG, 'Prowl') CheckSection(CFG, 'Prowl')
CheckSection(CFG, 'Twitter') CheckSection(CFG, 'Twitter')
@ -815,6 +820,10 @@ def initialize(consoleLogging=True):
PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '') PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '')
PLEX_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_password', '') PLEX_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_password', '')
USE_EMBY = bool(check_setting_int(CFG, 'Emby', 'use_emby', 0))
EMBY_HOST = check_setting_str(CFG, 'Emby', 'emby_host', '')
EMBY_APIKEY = check_setting_str(CFG, 'Emby', 'emby_apikey', '')
USE_GROWL = bool(check_setting_int(CFG, 'Growl', 'use_growl', 0)) USE_GROWL = bool(check_setting_int(CFG, 'Growl', 'use_growl', 0))
GROWL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Growl', 'growl_notify_onsnatch', 0)) GROWL_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Growl', 'growl_notify_onsnatch', 0))
GROWL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Growl', 'growl_notify_ondownload', 0)) GROWL_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Growl', 'growl_notify_ondownload', 0))
@ -1628,6 +1637,11 @@ def save_config():
new_config['Plex']['plex_username'] = PLEX_USERNAME new_config['Plex']['plex_username'] = PLEX_USERNAME
new_config['Plex']['plex_password'] = helpers.encrypt(PLEX_PASSWORD, ENCRYPTION_VERSION) new_config['Plex']['plex_password'] = helpers.encrypt(PLEX_PASSWORD, ENCRYPTION_VERSION)
new_config['Emby'] = {}
new_config['Emby']['use_emby'] = int(USE_EMBY)
new_config['Emby']['emby_host'] = EMBY_HOST
new_config['Emby']['emby_apikey'] = EMBY_APIKEY
new_config['Growl'] = {} new_config['Growl'] = {}
new_config['Growl']['use_growl'] = int(USE_GROWL) new_config['Growl']['use_growl'] = int(USE_GROWL)
new_config['Growl']['growl_notify_onsnatch'] = int(GROWL_NOTIFY_ONSNATCH) new_config['Growl']['growl_notify_onsnatch'] = int(GROWL_NOTIFY_ONSNATCH)

View file

@ -21,6 +21,7 @@ import sickbeard
import xbmc import xbmc
import kodi import kodi
import plex import plex
import emby
import nmj import nmj
import nmjv2 import nmjv2
import synoindex import synoindex
@ -47,6 +48,7 @@ from sickbeard.common import *
xbmc_notifier = xbmc.XBMCNotifier() xbmc_notifier = xbmc.XBMCNotifier()
kodi_notifier = kodi.KODINotifier() kodi_notifier = kodi.KODINotifier()
plex_notifier = plex.PLEXNotifier() plex_notifier = plex.PLEXNotifier()
emby_notifier = emby.EmbyNotifier()
nmj_notifier = nmj.NMJNotifier() nmj_notifier = nmj.NMJNotifier()
nmjv2_notifier = nmjv2.NMJv2Notifier() nmjv2_notifier = nmjv2.NMJv2Notifier()
synoindex_notifier = synoindex.synoIndexNotifier() synoindex_notifier = synoindex.synoIndexNotifier()

View file

@ -0,0 +1,99 @@
# Author: Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/
#
# This file is part of SickGear.
#
# SickGear is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickGear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
import urllib
import urllib2
import sickbeard
from sickbeard import logger
from sickbeard.exceptions import ex
try:
import json
except ImportError:
import simplejson as json
class EmbyNotifier:
def _notify_emby(self, message, host=None, emby_apikey=None):
"""Handles notifying Emby Server host via HTTP API
Returns: True if the request succeeded, False otherwise
"""
# fill in omitted parameters
if not host:
host = sickbeard.EMBY_HOST
if not emby_apikey:
emby_apikey = sickbeard.EMBY_APIKEY
url = 'http://%s/emby/Notifications/Admin' % (host)
values = {'Name': 'SickGear', 'Description': message, 'ImageUrl': 'https://raw.githubusercontent.com/SickGear/SickGear/master/gui/slick/images/ico/apple-touch-icon-precomposed.png'}
data = json.dumps(values)
try:
req = urllib2.Request(url, data)
req.add_header('X-MediaBrowser-Token', emby_apikey)
req.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(req)
response.close()
except (urllib2.URLError, IOError) as e:
logger.log(u'EMBY: Warning: Couldn\'t contact Emby Server at ' + url + ' ' + ex(e), logger.WARNING)
return False
logger.log(u'EMBY: Notification successful.', logger.MESSAGE)
return True
def test_notify(self, host, emby_apikey):
return self._notify_emby('This is a test notification from SickGear', host, emby_apikey)
def update_library(self):
"""Handles updating the Emby Server host via HTTP API
Returns: True if the request succeeded, False otherwise
"""
if sickbeard.USE_EMBY:
if not sickbeard.EMBY_HOST:
logger.log(u'EMBY: No host specified, check your settings', logger.DEBUG)
return False
url = 'http://%s/emby/Library/Series/Updated' % (sickbeard.EMBY_HOST)
values = {}
data = urllib.urlencode(values)
try:
req = urllib2.Request(url, data)
req.add_header('X-MediaBrowser-Token', sickbeard.EMBY_APIKEY)
response = urllib2.urlopen(req)
response.close()
except (urllib2.URLError, IOError) as e:
logger.log(u'EMBY: Warning: Couldn\'t contact Emby Server at ' + url + ' ' + ex(e), logger.WARNING)
return False
logger.log(u'EMBY: Updating library on host: %s' % sickbeard.EMBY_HOST, logger.MESSAGE)
return True
notifier = EmbyNotifier

View file

@ -1044,6 +1044,9 @@ class PostProcessor(object):
# do the library update for Plex # do the library update for Plex
notifiers.plex_notifier.update_library(ep_obj) notifiers.plex_notifier.update_library(ep_obj)
# do the library update for Emby
notifiers.emby_notifier.update_library()
# do the library update for NMJ # do the library update for NMJ
# nmj_notifier kicks off its library update when the notify_download is issued (inside notifiers) # nmj_notifier kicks off its library update when the notify_download is issued (inside notifiers)

View file

@ -535,6 +535,7 @@ class Home(MainHandler):
{'title': 'Update XBMC', 'path': 'home/updateXBMC/', 'requires': self.haveXBMC}, {'title': 'Update XBMC', 'path': 'home/updateXBMC/', 'requires': self.haveXBMC},
{'title': 'Update Kodi', 'path': 'home/updateKODI/', 'requires': self.haveKODI}, {'title': 'Update Kodi', 'path': 'home/updateKODI/', 'requires': self.haveKODI},
{'title': 'Update Plex', 'path': 'home/updatePLEX/', 'requires': self.havePLEX}, {'title': 'Update Plex', 'path': 'home/updatePLEX/', 'requires': self.havePLEX},
{'title': 'Update Emby', 'path': 'home/updateEMBY/', 'requires': self.haveEMBY},
{'title': 'Restart', 'path': 'home/restart/?pid=' + str(sickbeard.PID), 'confirm': True}, {'title': 'Restart', 'path': 'home/restart/?pid=' + str(sickbeard.PID), 'confirm': True},
{'title': 'Shutdown', 'path': 'home/shutdown/?pid=' + str(sickbeard.PID), 'confirm': True}, {'title': 'Shutdown', 'path': 'home/shutdown/?pid=' + str(sickbeard.PID), 'confirm': True},
] ]
@ -551,6 +552,10 @@ class Home(MainHandler):
def havePLEX(): def havePLEX():
return sickbeard.USE_PLEX and sickbeard.PLEX_UPDATE_LIBRARY return sickbeard.USE_PLEX and sickbeard.PLEX_UPDATE_LIBRARY
@staticmethod
def haveEMBY():
return sickbeard.USE_EMBY
@staticmethod @staticmethod
def _getEpisode(show, season=None, episode=None, absolute=None): def _getEpisode(show, season=None, episode=None, absolute=None):
if show is None: if show is None:
@ -844,6 +849,19 @@ class Home(MainHandler):
return finalResult return finalResult
def testEMBY(self, host=None, emby_apikey=None):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
if None is not emby_apikey and starify(emby_apikey, True):
emby_apikey = sickbeard.EMBY_APIKEY
host = config.clean_host(host)
result = notifiers.emby_notifier.test_notify(urllib.unquote_plus(host), emby_apikey)
if result:
return 'Test Emby notice sent successfully to ' + urllib.unquote_plus(host)
else:
return 'Test Emby notice failed to ' + urllib.unquote_plus(host)
def testLibnotify(self, *args, **kwargs): def testLibnotify(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')
@ -1660,6 +1678,15 @@ class Home(MainHandler):
ui.notifications.error('Unable to contact', 'Plex Media Server host(s): ' + result.replace(',', ', ')) ui.notifications.error('Unable to contact', 'Plex Media Server host(s): ' + result.replace(',', ', '))
self.redirect('/home/') self.redirect('/home/')
def updateEMBY(self):
if notifiers.emby_notifier.update_library():
ui.notifications.message(
'Library update command sent to Emby host: ' + sickbeard.EMBY_HOST)
else:
ui.notifications.error('Unable to contact Emby host: ' + sickbeard.EMBY_HOST)
self.redirect('/home/')
def setStatus(self, show=None, eps=None, status=None, direct=False): def setStatus(self, show=None, eps=None, status=None, direct=False):
if show is None or eps is None or status is None: if show is None or eps is None or status is None:
@ -4880,6 +4907,7 @@ class ConfigNotifications(Config):
use_plex=None, plex_notify_onsnatch=None, plex_notify_ondownload=None, use_plex=None, plex_notify_onsnatch=None, plex_notify_ondownload=None,
plex_notify_onsubtitledownload=None, plex_update_library=None, plex_notify_onsubtitledownload=None, plex_update_library=None,
plex_server_host=None, plex_host=None, plex_username=None, plex_password=None, plex_server_host=None, plex_host=None, plex_username=None, plex_password=None,
use_emby=None, emby_host=None, emby_apikey=None,
use_growl=None, growl_notify_onsnatch=None, growl_notify_ondownload=None, use_growl=None, growl_notify_onsnatch=None, growl_notify_ondownload=None,
growl_notify_onsubtitledownload=None, growl_host=None, growl_password=None, growl_notify_onsubtitledownload=None, growl_host=None, growl_password=None,
use_prowl=None, prowl_notify_onsnatch=None, prowl_notify_ondownload=None, use_prowl=None, prowl_notify_onsnatch=None, prowl_notify_ondownload=None,
@ -4955,6 +4983,12 @@ class ConfigNotifications(Config):
if set('*') != set(plex_password): if set('*') != set(plex_password):
sickbeard.PLEX_PASSWORD = plex_password sickbeard.PLEX_PASSWORD = plex_password
sickbeard.USE_EMBY = config.checkbox_to_value(use_emby)
sickbeard.EMBY_HOST = config.clean_host(emby_host)
key = emby_apikey.strip()
if not starify(key, True):
sickbeard.EMBY_APIKEY = key
sickbeard.USE_GROWL = config.checkbox_to_value(use_growl) sickbeard.USE_GROWL = config.checkbox_to_value(use_growl)
sickbeard.GROWL_NOTIFY_ONSNATCH = config.checkbox_to_value(growl_notify_onsnatch) sickbeard.GROWL_NOTIFY_ONSNATCH = config.checkbox_to_value(growl_notify_onsnatch)
sickbeard.GROWL_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(growl_notify_ondownload) sickbeard.GROWL_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(growl_notify_ondownload)