mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-05 17:43:37 +00:00
Add Emby notifier to config/Notifications (thanks to Supremicus for the jumpstart) with a homebrew description.
This commit is contained in:
parent
5d169de30d
commit
df4e61c661
27 changed files with 1045 additions and 620 deletions
|
@ -35,6 +35,7 @@
|
|||
* Add search show Name to Show List Layout: Poster
|
||||
* Change indicate when not sorting with article by dimming ("The", "A", "An") on Show List, Episode, History,
|
||||
Mass Update, Add with Browse and from Existing views
|
||||
* Add Emby notifier to config/Notifications
|
||||
|
||||
|
||||
### 0.11.6 (2016-02-18 23:10:00 UTC)
|
||||
|
|
|
@ -163,16 +163,19 @@ inc_top.tmpl
|
|||
|
||||
.ui-tabs .ui-tabs-panel{
|
||||
background-color:#3d3d3d !important;
|
||||
border:1px solid #111 !important
|
||||
border:1px solid #111 !important;
|
||||
border-top-width:0 !important
|
||||
}
|
||||
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active{
|
||||
border-bottom:1px solid #3d3d3d !important;
|
||||
border-top-left-radius:5px;
|
||||
border-top-right-radius:5px
|
||||
}
|
||||
|
||||
.ui-tabs-nav > :not(.ui-tabs-active){
|
||||
background:#333;
|
||||
border-bottom:2px solid #222 !important;
|
||||
border-top-left-radius:5px;
|
||||
border-top-right-radius:5px
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -42,4 +42,5 @@
|
|||
<glyph unicode="" 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="" 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="" 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" />
|
||||
</font></defs></svg>
|
||||
<glyph unicode="" 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>
|
||||
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Binary file not shown.
|
@ -126,14 +126,14 @@ fonts
|
|||
font-style:italic
|
||||
}
|
||||
|
||||
/* Droid Sans */
|
||||
/* SickGear Icons */
|
||||
@font-face{
|
||||
font-family:'sgicons';
|
||||
src:url('fonts/sgicons.eot');
|
||||
src:url('fonts/sgicons.eot?#iefix') format('embedded-opentype'),
|
||||
url('fonts/sgicons.woff') format('woff'),
|
||||
url('fonts/sgicons.ttf') format('truetype'),
|
||||
url('fonts/sgicons.svg#sgicons') format('svg');
|
||||
src:url('fonts/sgicons.eot?v1');
|
||||
src:url('fonts/sgicons.eot?v1#iefix') format('embedded-opentype'),
|
||||
url('fonts/sgicons.woff?v1') format('woff'),
|
||||
url('fonts/sgicons.ttf?v1') format('truetype'),
|
||||
url('fonts/sgicons.svg?v1#sgicons') format('svg');
|
||||
font-weight:normal;
|
||||
font-style:normal
|
||||
}
|
||||
|
@ -298,15 +298,18 @@ inc_top.tmpl
|
|||
|
||||
.ui-tabs .ui-tabs-panel{
|
||||
background-color:#F7F7F7 !important;
|
||||
border:1px solid #CCC !important
|
||||
border:1px solid #CCC !important;
|
||||
border-top-width:0 !important
|
||||
}
|
||||
|
||||
.ui-tabs .ui-tabs-nav li.ui-tabs-active{
|
||||
border-bottom:1px solid #F7F7F7 !important;
|
||||
border-top-left-radius:5px;
|
||||
border-top-right-radius:5px
|
||||
}
|
||||
|
||||
.ui-tabs-nav > :not(.ui-tabs-active){
|
||||
border-bottom:1px solid transparent !important;
|
||||
border-top-left-radius:5px;
|
||||
border-top-right-radius:5px
|
||||
}
|
||||
|
@ -499,6 +502,10 @@ inc_top.tmpl
|
|||
content:"\e621"
|
||||
}
|
||||
|
||||
.sgicon-emby:before {
|
||||
content: "\e900"
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
inc_bottom.tmpl
|
||||
========================================================================== */
|
||||
|
@ -946,6 +953,7 @@ div.formpaginate{
|
|||
margin-right:6px
|
||||
}
|
||||
|
||||
#edit-show #customQualityWrapper div.component-group-desc p,
|
||||
#addShowForm #customQualityWrapper div.component-group-desc p{
|
||||
font-size:14px
|
||||
}
|
||||
|
@ -1007,6 +1015,9 @@ div.formpaginate{
|
|||
padding:0 0 0 15px
|
||||
}
|
||||
|
||||
#edit-show #blackwhitelist,
|
||||
#edit-show #blackwhitelist h4,
|
||||
#edit-show #blackwhitelist p,
|
||||
#addShowForm #blackwhitelist,
|
||||
#addShowForm #blackwhitelist h4,
|
||||
#addShowForm #blackwhitelist p{
|
||||
|
@ -1662,6 +1673,7 @@ td.col-search{
|
|||
padding:15px 0 0
|
||||
}
|
||||
|
||||
#edit-show #config span.component-desc,
|
||||
#addShowForm #editShow.stepDiv span.component-desc{
|
||||
width:639px
|
||||
}
|
||||
|
@ -2152,6 +2164,10 @@ config*.tmpl
|
|||
min-height:200px
|
||||
}
|
||||
|
||||
#edit-show .component-group{
|
||||
padding:25px 30px
|
||||
}
|
||||
|
||||
.component-item{
|
||||
border-bottom:1px dotted #666;
|
||||
min-height:200px
|
||||
|
@ -2291,6 +2307,10 @@ select .selected:before{
|
|||
margin-bottom:10px
|
||||
}
|
||||
|
||||
#editShow .field-pair #SceneException h4{
|
||||
margin-bottom:5px
|
||||
}
|
||||
|
||||
#editShow .field-pair #customQuality h4{
|
||||
margin-bottom:1px
|
||||
}
|
||||
|
@ -2816,6 +2836,13 @@ div.blackwhitelist.white select,
|
|||
div.blackwhitelist.black select{
|
||||
height:110px
|
||||
}
|
||||
#edit-show div.blackwhitelist.pool{
|
||||
width:330px;
|
||||
height:265px;
|
||||
margin-left:248px;
|
||||
float:none
|
||||
}
|
||||
#edit-show div.blackwhitelist.pool select,
|
||||
div.blackwhitelist.pool,
|
||||
div.blackwhitelist.pool select{
|
||||
width:330px;
|
||||
|
@ -3379,6 +3406,12 @@ label{
|
|||
font-weight:normal
|
||||
}
|
||||
|
||||
.label-container{
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px
|
||||
}
|
||||
|
||||
pre{
|
||||
border:1px solid
|
||||
}
|
||||
|
@ -3433,6 +3466,7 @@ input sizing (for config pages)
|
|||
margin-top:-4px
|
||||
}
|
||||
|
||||
#config .input350,
|
||||
.input350{
|
||||
width:350px;
|
||||
margin-top:-4px
|
||||
|
@ -3610,6 +3644,7 @@ div.formpaginate .prev, div.formpaginate .next{
|
|||
}
|
||||
|
||||
/* step 3 related */
|
||||
#edit-show #customQualityWrapper #customQuality,
|
||||
#customQuality{
|
||||
display:block;
|
||||
padding:0 0 10px 0;
|
||||
|
|
BIN
gui/slick/images/addshows/add-anime.gif
Normal file
BIN
gui/slick/images/addshows/add-anime.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
gui/slick/images/addshows/add-imdb.gif
Normal file
BIN
gui/slick/images/addshows/add-imdb.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
gui/slick/images/notifiers/emby.png
Normal file
BIN
gui/slick/images/notifiers/emby.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -31,6 +31,176 @@
|
|||
</ul>
|
||||
|
||||
<div id="tabs-1">
|
||||
<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>Have a central media database with strong user management, e.g. for improved Kodi profile(s). Gain deep viewing and granular control on any device, e.g. replace Plex entirely, Emby + Kodi > Plex.</p>
|
||||
</div>
|
||||
<fieldset class="component-group-list">
|
||||
<div class="field-pair">
|
||||
#if not hasattr($sickbeard, 'EMBY_UPDATE_LIBRARY')#<span class="red-text">Restart SickGear to reveal new options here</span>#else#
|
||||
<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 enable features for Emby server(s) ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="content_use_emby">
|
||||
<div class="field-pair">
|
||||
<label for="emby_update_library">
|
||||
<span class="component-title">Update media library</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="emby_update_library" id="emby_update_library" #if $sickbeard.EMBY_UPDATE_LIBRARY then 'checked="checked"' else ''# />
|
||||
<p>push Emby to refresh a show that is post-processed</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="emby_host">
|
||||
<span class="component-title">Host(s) running Emby</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>IP:Port [, IP:Port] (e.g. 192.168.0.1:8096, 192.168.1.2:8096)</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="emby_apikey">
|
||||
<span class="component-title">API key(s)</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">
|
||||
<p>(comma separated)</p>
|
||||
<div class="clear-left"><p>one key per host from Emby/Manage 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">
|
||||
#end if
|
||||
</div><!-- /content_use_emby //-->
|
||||
</fieldset>
|
||||
</div><!-- /emby component-group //-->
|
||||
|
||||
<div class="component-group">
|
||||
<div class="component-group-desc">
|
||||
<img class="notifier-icon" src="$sbRoot/images/notifiers/kodi.png" alt="" title="Kodi" />
|
||||
<h3><a href="<%= anon_url('http://kodi.tv/') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Kodi</a></h3>
|
||||
<p>Kodi (formerly known as XBMC) is an award-winning free and open source (GPL) software media player and entertainment hub.</p>
|
||||
</div>
|
||||
<fieldset class="component-group-list">
|
||||
<div class="field-pair">
|
||||
<label class="cleafix" for="use_kodi">
|
||||
<span class="component-title">Enable</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" class="enabler" name="use_kodi" id="use_kodi" #if $sickbeard.USE_KODI then 'checked="checked"' else ''# />
|
||||
<p>should SickGear send Kodi commands ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="content_use_kodi">
|
||||
<div class="field-pair">
|
||||
<label for="kodi_always_on">
|
||||
<span class="component-title">Always on</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_always_on" id="kodi_always_on" #if $sickbeard.KODI_ALWAYS_ON then 'checked="checked"' else ''# />
|
||||
<p>log errors when unreachable</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_library">
|
||||
<span class="component-title">Update shows known to Kodi</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_library" id="kodi_update_library" #if $sickbeard.KODI_UPDATE_LIBRARY then 'checked="checked"' else ''# />
|
||||
<p>push Kodi to refresh a show that is post-processed</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_full">
|
||||
<span class="component-title">Perform full library update</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_full" id="kodi_update_full" #if $sickbeard.KODI_UPDATE_FULL then 'checked="checked"' else ''# />
|
||||
<p>only when "Update shows" fails. Tip: enables Kodi to add new shows</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_onlyfirst">
|
||||
<span class="component-title">Only update first host</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_onlyfirst" id="kodi_update_onlyfirst" #if $sickbeard.KODI_UPDATE_ONLYFIRST then 'checked="checked"' else ''# />
|
||||
<p>only send library updates to the first active host</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_host">
|
||||
<span class="component-title">Host(s) running Kodi</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="kodi_host" id="kodi_host" value="$sickbeard.KODI_HOST" class="form-control input-sm input350" />
|
||||
<div class="clear-left"><p>IP:Port [, IP:Port] (e.g. 192.168.0.1:8080, 192.168.1.2:8080)</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_username">
|
||||
<span class="component-title">Kodi web server username</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="kodi_username" id="kodi_username" value="$sickbeard.KODI_USERNAME" class="form-control input-sm input250" />
|
||||
<p>(blank for none)</p>
|
||||
<div class="clear-left"><p>in Kodi System/Settings/Services/Web server</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_password">
|
||||
<span class="component-title">Kodi web server password</span>
|
||||
<span class="component-desc">
|
||||
<input type="password" name="kodi_password" id="kodi_password" value="#echo '*' * len($sickbeard.KODI_PASSWORD)#" class="form-control input-sm input250" />
|
||||
<p>(blank for none)</p>
|
||||
<div class="clear-left"><p>in Kodi System/Settings/Services/Web server</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_onsnatch">
|
||||
<span class="component-title">Notify on snatch</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_onsnatch" id="kodi_notify_onsnatch" #if $sickbeard.KODI_NOTIFY_ONSNATCH then 'checked="checked"' else ''# />
|
||||
<p>download start notification</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_ondownload">
|
||||
<span class="component-title">Notify on download</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_ondownload" id="kodi_notify_ondownload" #if $sickbeard.KODI_NOTIFY_ONDOWNLOAD then 'checked="checked"' else ''# />
|
||||
<p>download finish notification</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_onsubtitledownload">
|
||||
<span class="component-title">Notify on subtitle download</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_onsubtitledownload" id="kodi_notify_onsubtitledownload" #if $sickbeard.KODI_NOTIFY_ONSUBTITLEDOWNLOAD then 'checked="checked"' else ''# />
|
||||
<p>subtitle downloaded notification</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="testNotification" id="testKODI-result">Click below to test.</div>
|
||||
<input class="btn" type="button" value="Test Kodi" id="testKODI" />
|
||||
<input type="submit" class="config_submitter btn" value="Save Changes" />
|
||||
</div><!-- /content_use_kodi //-->
|
||||
</fieldset>
|
||||
</div><!-- /kodi component-group //-->
|
||||
|
||||
<div class="component-group">
|
||||
|
||||
<div class="component-group-desc">
|
||||
|
@ -156,122 +326,6 @@
|
|||
|
||||
</div><!-- /xbmc component-group //-->
|
||||
|
||||
<div class="component-group">
|
||||
<div class="component-group-desc">
|
||||
<img class="notifier-icon" src="$sbRoot/images/notifiers/kodi.png" alt="" title="Kodi" />
|
||||
<h3><a href="<%= anon_url('http://kodi.tv/') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Kodi</a></h3>
|
||||
<p>Kodi (formerly known as XBMC) is an award-winning free and open source (GPL) software media player and entertainment hub.</p>
|
||||
</div>
|
||||
<fieldset class="component-group-list">
|
||||
<div class="field-pair">
|
||||
<label class="cleafix" for="use_kodi">
|
||||
<span class="component-title">Enable</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" class="enabler" name="use_kodi" id="use_kodi" #if $sickbeard.USE_KODI then 'checked="checked"' else ''# />
|
||||
<p>should SickGear send Kodi commands ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="content_use_kodi">
|
||||
<div class="field-pair">
|
||||
<label for="kodi_always_on">
|
||||
<span class="component-title">Always on</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_always_on" id="kodi_always_on" #if $sickbeard.KODI_ALWAYS_ON then 'checked="checked"' else ''# />
|
||||
<p>log errors when unreachable ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_onsnatch">
|
||||
<span class="component-title">Notify on snatch</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_onsnatch" id="kodi_notify_onsnatch" #if $sickbeard.KODI_NOTIFY_ONSNATCH then 'checked="checked"' else ''# />
|
||||
<p>send a notification when a download starts ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_ondownload">
|
||||
<span class="component-title">Notify on download</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_ondownload" id="kodi_notify_ondownload" #if $sickbeard.KODI_NOTIFY_ONDOWNLOAD then 'checked="checked"' else ''# />
|
||||
<p>send a notification when a download finishes ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_notify_onsubtitledownload">
|
||||
<span class="component-title">Notify on subtitle download</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_notify_onsubtitledownload" id="kodi_notify_onsubtitledownload" #if $sickbeard.KODI_NOTIFY_ONSUBTITLEDOWNLOAD then 'checked="checked"' else ''# />
|
||||
<p>send a notification when subtitles are downloaded ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_library">
|
||||
<span class="component-title">Update shows known to Kodi</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_library" id="kodi_update_library" #if $sickbeard.KODI_UPDATE_LIBRARY then 'checked="checked"' else ''# />
|
||||
<p>with changes under the path of processed shows ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_full">
|
||||
<span class="component-title">Perform full library update</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_full" id="kodi_update_full" #if $sickbeard.KODI_UPDATE_FULL then 'checked="checked"' else ''# />
|
||||
<p>if "Update shows" fails (e.g. to have Kodi find newly added shows)</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_update_onlyfirst">
|
||||
<span class="component-title">Only update first host</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="kodi_update_onlyfirst" id="kodi_update_onlyfirst" #if $sickbeard.KODI_UPDATE_ONLYFIRST then 'checked="checked"' else ''# />
|
||||
<p>only send library updates to the first active host ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_host">
|
||||
<span class="component-title">Host(s) running Kodi</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="kodi_host" id="kodi_host" value="$sickbeard.KODI_HOST" class="form-control input-sm input350" />
|
||||
<div class="clear-left"><p>IP:Port [, IP:Port] (e.g. 192.168.0.1:8080, 192.168.1.2:8080)</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_username">
|
||||
<span class="component-title">Kodi web server username</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="kodi_username" id="kodi_username" value="$sickbeard.KODI_USERNAME" class="form-control input-sm input250" />
|
||||
<p>(blank for none)</p>
|
||||
<div class="clear-left"><p>in Kodi System/Settings/Services/Web server</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="kodi_password">
|
||||
<span class="component-title">Kodi web server password</span>
|
||||
<span class="component-desc">
|
||||
<input type="password" name="kodi_password" id="kodi_password" value="#echo '*' * len($sickbeard.KODI_PASSWORD)#" class="form-control input-sm input250" />
|
||||
<p>(blank for none)</p>
|
||||
<div class="clear-left"><p>in Kodi System/Settings/Services/Web server</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="testNotification" id="testKODI-result">Click below to test.</div>
|
||||
<input class="btn" type="button" value="Test Kodi" id="testKODI" />
|
||||
<input type="submit" class="config_submitter btn" value="Save Changes" />
|
||||
</div><!-- /content_use_kodi //-->
|
||||
</fieldset>
|
||||
</div><!-- /kodi component-group //-->
|
||||
|
||||
<div class="component-group">
|
||||
<div class="component-group-desc">
|
||||
<img class="notifier-icon" src="$sbRoot/images/notifiers/plex.png" alt="" title="Plex Media Server" />
|
||||
|
@ -396,7 +450,6 @@
|
|||
</fieldset>
|
||||
</div><!-- /plex component-group -->
|
||||
|
||||
|
||||
<div class="component-group">
|
||||
<div class="component-group-desc">
|
||||
<img class="notifier-icon" src="$sbRoot/images/notifiers/nmj.png" alt="" title="Networked Media Jukebox" />
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
#import sickbeard.blackandwhitelist
|
||||
##
|
||||
#set global $title = 'Edit ' + $show.name
|
||||
#set global $header = 'Edit ' + $show.name
|
||||
#set global $header = $show.name
|
||||
#set global $sbPath = '..'
|
||||
#set global $topmenu = 'home'
|
||||
#set global $page_body_attr = 'edit-show'
|
||||
##
|
||||
#import os.path
|
||||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
|
||||
|
@ -16,13 +17,10 @@
|
|||
<script type="text/javascript" src="$sbRoot/js/qualityChooser.js?v=$sbPID"></script>
|
||||
<script type="text/javascript" src="$sbRoot/js/editShow.js?v=$sbPID"></script>
|
||||
<script>
|
||||
var config = {
|
||||
show_lang: "$show.lang",
|
||||
show_isanime: #echo ['!1','!0'][$show.is_anime]#
|
||||
}
|
||||
var config = {showLang: '$show.lang', showIsAnime: #echo ['!1','!0'][$show.is_anime]#}
|
||||
</script>
|
||||
#if $varExists('header')
|
||||
<h1 class="header">$header</h1>
|
||||
<h1 class="header"><span class="grey-text">Edit</span> $header</h1>
|
||||
#else
|
||||
<h1 class="title">$title</h1>
|
||||
#end if
|
||||
|
@ -30,209 +28,233 @@
|
|||
##
|
||||
#set $html_checked = ' checked="checked"'
|
||||
#set $html_disabled = ' disabled="disabled"'
|
||||
<form action="editShow" method="post" id="addShowForm">
|
||||
<input type="hidden" name="show" value="$show.indexerid">
|
||||
<div id="config">
|
||||
<div id="config-content" class="linefix container">
|
||||
<form action="editShow" method="post" id="editShow" style="width:894px">
|
||||
<input type="hidden" name="show" value="$show.indexerid">
|
||||
|
||||
<div id="editShow" class="stepDiv linefix">
|
||||
<div id="config-components">
|
||||
<ul>
|
||||
<li><a href="#core-component-group1">Common</a></li>
|
||||
<li><a href="#core-component-group2">Search</a></li>
|
||||
<li><a href="#core-component-group3">Post-Processing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="paused">
|
||||
<span class="component-title">Paused</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="paused" id="paused"#if 1 == $show.paused then $html_checked else ''#>
|
||||
<p>enable to pause searching providers for show episodes</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="core-component-group1" class="component-group">
|
||||
|
||||
<div class="field-pair">
|
||||
<div class="field-pair">
|
||||
<label for="paused">
|
||||
<span class="component-title">Paused</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="paused" id="paused"#echo ('', $html_checked)[$show.paused]#>
|
||||
<p>#echo ('enable to not', 'disable to')[$show.paused]# search or match releases for <b class="boldest grey-text">$show.name</b></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair#if $sickbeard.SHOWLIST_TAGVIEW != 'custom'# hidden#end if#">
|
||||
<label for="tag">
|
||||
<span class="component-title">Group show under</span>
|
||||
<span class="component-desc">
|
||||
<select name="tag" id="tag" class="form-control form-control-inline input-sm">
|
||||
#for $tag in $sickbeard.SHOW_TAGS:
|
||||
<option value="$tag" #if $tag == $show.tag then 'selected="selected"' else ''#>$tag#echo ('', ' (default)')['Show List' == $tag]#</option>
|
||||
#end for
|
||||
</select>
|
||||
<span>on the "Show List" page</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<span class="label-container">
|
||||
<span class="component-title">Alternative show name(s)</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" id="SceneName" class="form-control form-control-inline input-sm input200">
|
||||
<select id="SceneNameSeason" class="form-control form-control-inline input-sm input100" style="#echo ('visibility:hidden','float:left')[$show.anime]#">
|
||||
<option value="-1">Series</option>
|
||||
#if $show.anime:
|
||||
#for $season in $seasonResults:
|
||||
<option value="$season[0]">Season $season[0]</option>
|
||||
#end for
|
||||
#end if
|
||||
</select>
|
||||
<input class="btn btn-inline" type="button" value="Add" id="addSceneName">
|
||||
<p style="float:left">e.g. The Show, The Show (2016), The Show (US)</p>
|
||||
<p class="clear-left note">post-processing or searching may require an alternative if a "Show not found" error is reported</p>
|
||||
</span>
|
||||
<span id="SceneException" class="component-desc" style="display:none">
|
||||
<h4 class="grey-text">Alternative a.k.a scene exceptions list (multi-selectable)</h4>
|
||||
<select id="exceptions_list" name="exceptions_list" multiple="multiple" class="input350" style="min-height:90px; float:left" >
|
||||
#for $cur_exception_season in $show.exceptions:
|
||||
#for $cur_exception in $show.exceptions[$cur_exception_season]:
|
||||
<option value="$cur_exception_season|$cur_exception">#if $show.is_anime#S#echo ($cur_exception_season, '*')[$cur_exception_season == -1]#: #end if#$cur_exception</option>
|
||||
#end for
|
||||
#end for
|
||||
</select>
|
||||
<span><p class="note">#if $show.is_anime#S* = Any series. #end if#This case insensitive list overrides the original name to process</p></span>
|
||||
<div>
|
||||
<input id="removeSceneName" value="Remove" class="btn pull-left" type="button" style="margin-top: 10px;"/>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="rls_ignore_words">
|
||||
<span class="component-title">Ignore result with any word</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="rls_ignore_words" id="rls_ignore_words" value="$show.rls_ignore_words" class="form-control form-control-inline input-sm input350">
|
||||
<p>e.g. [[regex:]word1, word2, ..., word_n, regex_n]</p>
|
||||
<p class="note">ignore search result <em class="grey-text">if its title contains any</em> of these comma seperated words or regular expressions</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="rls_require_words">
|
||||
<span class="component-title">Require at least one word</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="rls_require_words" id="rls_require_words" value="$show.rls_require_words" class="form-control form-control-inline input-sm input350">
|
||||
<p>e.g. [[regex:]word1, word2, ..., word_n, regex_n]</p>
|
||||
<p class="note">ignore search result <em class="grey-text">unless its title contains one</em> of these comma seperated words or regular expressions</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
#set $qualities = $common.Quality.splitQuality(int($show.quality))
|
||||
#set global $anyQualities = $qualities[0]
|
||||
#set global $bestQualities = $qualities[1]
|
||||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_qualityChooser.tmpl')
|
||||
|
||||
#if $anyQualities + $bestQualities
|
||||
<div class="field-pair show-if-quality-custom">
|
||||
<label for="archive_firstmatch">
|
||||
<span class="component-title">End upgrade on first match</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="archive_firstmatch" id="archive_firstmatch"#if $show.archive_firstmatch == 1 then $html_checked else ''#>
|
||||
<p>mark an episode complete after the first best match is found from the <em>Upgrade to</em> quality list</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="SceneName">
|
||||
<span class="component-title">Scene exception</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" id="SceneName" class="form-control form-control-inline input-sm input200">
|
||||
<select id="SceneNameSeason" class="form-control form-control-inline input-sm input100" style="#echo ('visibility:hidden','float:left')[$show.anime]#">
|
||||
<option value="-1">Series</option>
|
||||
#if $show.anime:
|
||||
#for $season in $seasonResults:
|
||||
<option value="$season[0]">Season $season[0]</option>
|
||||
#end for
|
||||
#end if
|
||||
</select>
|
||||
<input class="btn btn-inline" type="button" value="Add" id="addSceneName">
|
||||
#set $addSceneNameText = ('', ' or seasons')[$show.anime]
|
||||
<p class="clear-left note">add alternative release names$addSceneNameText found on search providers for <b class="boldest grey-text">$show.name</b></p>
|
||||
</span>
|
||||
<span class="component-desc">
|
||||
<div id="SceneException">
|
||||
<h4 class="grey-text">Exceptions list (multi-selectable)</h4>
|
||||
<select id="exceptions_list" name="exceptions_list" multiple="multiple" class="input350" style="min-height:90px; float:left" >
|
||||
#for $cur_exception_season in $show.exceptions:
|
||||
#for $cur_exception in $show.exceptions[$cur_exception_season]:
|
||||
<option value="$cur_exception_season|$cur_exception">S#echo ($cur_exception_season, '*')[$cur_exception_season == -1]#: $cur_exception</option>
|
||||
#end for
|
||||
#end for
|
||||
</select>
|
||||
<span><p class="note">this list overrides the original name<br />to search, it doesn't append to it</p></span>
|
||||
<div>
|
||||
<input id="removeSceneName" value="Remove" class="btn pull-left" type="button" style="margin-top: 10px;"/>
|
||||
<div class="field-pair show-if-quality-custom" style="display:none">
|
||||
<label for="archive_firstmatch">
|
||||
<span class="component-title">Upgrade once</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="archive_firstmatch" id="archive_firstmatch"#echo ('', $html_checked)[$show.archive_firstmatch]#>
|
||||
<p>stop upgrading after matching the first best <em>Upgrade to</em> quality</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
</div>
|
||||
</span>
|
||||
</label>
|
||||
<div style="clear:right"> </div>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="rls_ignore_words">
|
||||
<span class="component-title">Ignore result with any word</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="rls_ignore_words" id="rls_ignore_words" value="$show.rls_ignore_words" class="form-control form-control-inline input-sm input350">
|
||||
<p>e.g. [[regex:]word1, word2, ..., word_n, regex_n]</p>
|
||||
<p class="note">ignore search result <em class="grey-text">if its title contains any</em> of these comma seperated words or regular expressions</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div><!-- /component-group1 //-->
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="rls_require_words">
|
||||
<span class="component-title">Require at least one word</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="rls_require_words" id="rls_require_words" value="$show.rls_require_words" class="form-control form-control-inline input-sm input350">
|
||||
<p>e.g. [[regex:]word1, word2, ..., word_n, regex_n]</p>
|
||||
<p class="note">ignore search result <em class="grey-text">unless its title contains one</em> of these comma seperated words or regular expressions</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="core-component-group2" class="component-group">
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="location">
|
||||
<span class="component-title">Location for files</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="location" id="location" value="$show._location" class="form-control form-control-inline input-sm input350">
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="air_by_date">
|
||||
<span class="component-title">Air by date release names</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="air_by_date" id="air_by_date"#echo ('', $html_checked)[$show.air_by_date]#>
|
||||
<p>#echo ('enable if releases contain dates', 'disable for episodic releases')[$show.air_by_date]#, example: <em class="grey-text">Show.#echo ('03.02.2010', 'S02E03')[$show.air_by_date]#</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="flatten_folders">
|
||||
<span class="component-title">Flat folder structure</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="flatten_folders" id="flatten_folders"#if 1 == $show.flatten_folders and not $sickbeard.NAMING_FORCE_FOLDERS then $html_checked else ''##if $sickbeard.NAMING_FORCE_FOLDERS then $html_disabled else ''#>
|
||||
<p>enable to prevent creating the folders normally used to group seasons</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="scene">
|
||||
<span class="component-title">Scene numbering</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="scene" id="scene"#echo ('', $html_checked)[$show.scene]#>
|
||||
<p>find episodes numbered by release groups instead of the TV network <em class="grey-text">(#if $show_has_scene_map then 'scene/manual numbers' else 'manual numbers only '# available)</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="air_by_date">
|
||||
<span class="component-title">Air by date episode names</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="air_by_date" id="air_by_date"#if 1 == $show.air_by_date then $html_checked else ''#>
|
||||
<p>enable if episode releases are named ... <em class="grey-text">Show.03.02.2010</em> instead of <em class="grey-text">Show.S02E03</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="dvdorder">
|
||||
<span class="component-title">Use DVD titles and numbers</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="dvdorder" id="dvdorder"#echo ('', $html_checked)[$show.dvdorder]#>
|
||||
<p>#echo ('enable to use DVD title and episode ordering', 'disable to use TV network title, number and aired order')[$show.dvdorder]#.
|
||||
After changing this setting, a "force full update" is essential, and existing episodes must be manually renamed</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="dvdorder">
|
||||
<span class="component-title">Use DVD order</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="dvdorder" id="dvdorder"#if 1 == $show.dvdorder then $html_checked else ''#>
|
||||
<p>for episode titles, numbering etc. instead of the order the show aired on the network</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="indexerLangSelectEdit">
|
||||
<span class="component-title">Info language</span>
|
||||
<span class="component-desc">
|
||||
<select name="indexerLang" id="indexerLangSelectEdit" class="form-control form-control-inline input-sm"></select>
|
||||
<span>fetch show information in this language</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="scene">
|
||||
<span class="component-title">Scene numbering</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="scene" id="scene"#if $show.scene == 1 then $html_checked else ''#>
|
||||
<p>search for episodes numbered by scene groups instead of by the TV network <em class="grey-text">(#if $show_has_scene_map then 'scene/manual numbers' else 'manual numbers only '# available)</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="sports">
|
||||
<span class="component-title">Show is sports</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="sports" id="sports"#echo ('', $html_checked)[$show.sports]#>
|
||||
<p>treat this show as a sporting or MMA event</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair" style="margin-bottom:10px">
|
||||
<label for="indexerLangSelectEdit">
|
||||
<span class="component-title">Info language</span>
|
||||
<span class="component-desc">
|
||||
<select name="indexerLang" id="indexerLangSelectEdit" class="form-control form-control-inline input-sm"></select>
|
||||
<span>attempt to fetch show data and episode filenames in this language</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="anime">
|
||||
<span class="component-title">Show is anime</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="anime" id="anime"#echo ('', $html_checked)[$show.is_anime]#>
|
||||
<p>releases for this show are named like ... <em class="grey-text">Show.265</em> instead of <em class="grey-text">Show.S02E03</em></p>
|
||||
#if not $show.is_anime#<span id="anime-options" style="display:none">Update Show then edit again to view additional options here</span>#end if#
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="subtitles">
|
||||
<span class="component-title">Subtitles</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="subtitles" id="subtitles"#if 1 == $show.subtitles and $sickbeard.USE_SUBTITLES then $html_checked else ''##if not $sickbeard.USE_SUBTITLES then $html_disabled else ''#>
|
||||
<p#if not $sickbeard.USE_SUBTITLES then ' class="grey-text"><del' else ''#>attempt to download episode subtitles for this show#if not $sickbeard.USE_SUBTITLES then '</del> ... (<span class="red-text">note: first <a href="%s/config/subtitles/">enable the subtitle system here</a></span>)' % $sbRoot else ''#</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair#if $sickbeard.SHOWLIST_TAGVIEW != 'custom' then ' hidden' else ''#" style="margin-bottom:10px">
|
||||
<label for="tag">
|
||||
<span class="component-title">Show is in group</span>
|
||||
<span class="component-desc">
|
||||
<select name="tag" id="tag" class="form-control form-control-inline input-sm">
|
||||
#for $tag in $sickbeard.SHOW_TAGS:
|
||||
<option value="$tag" #if $tag == $show.tag then 'selected="selected"' else ''#>$tag#echo ('', ' (default)')['Show List' == $tag]#</option>
|
||||
#end for
|
||||
</select>
|
||||
<span>and is displayed on the show list page under this section</span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="sports">
|
||||
<span class="component-title">Show is sports</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="sports" id="sports"#if 1 == $show.sports then $html_checked else ''#>
|
||||
<p>enable to treat this show as a sporting or MMA event</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="anime">
|
||||
<span class="component-title">Show is anime</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="anime" id="anime"#if $show.is_anime then $html_checked else ''#>
|
||||
<p>enable if this show is anime and episode releases are named ... <em class="grey-text">Show.265</em> instead of <em class="grey-text">Show.S02E03</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
#if $show.is_anime:
|
||||
#if $show.is_anime
|
||||
#import sickbeard.blackandwhitelist
|
||||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_blackwhitelist.tmpl')
|
||||
<script type="text/javascript" src="$sbRoot/js/blackwhite.js?v=$sbPID"></script>
|
||||
<script type="text/javascript" src="$sbRoot/js/blackwhite.js?v=$sbPID"></script>
|
||||
#end if
|
||||
<input type="submit" id="submit" value="Submit" class="btn btn-primary" />
|
||||
</form>
|
||||
</div><!-- /component-group2 //-->
|
||||
|
||||
<div id="core-component-group3" class="component-group">
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="location">
|
||||
<span class="component-title">Location for files</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="location" id="location" value="$show._location" class="form-control form-control-inline input-sm input350">
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="flatten_folders">
|
||||
<span class="component-title">Flat folder hierarchy</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="flatten_folders" id="flatten_folders"#echo ('', $html_checked)[$show.flatten_folders and not $sickbeard.NAMING_FORCE_FOLDERS]##echo ('', $html_disabled)[$sickbeard.NAMING_FORCE_FOLDERS]#>
|
||||
<p>prevent creating season folders to group files</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="subtitles">
|
||||
<span class="component-title">Subtitles</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="subtitles" id="subtitles"#echo ('', $html_checked)[$show.subtitles and $sickbeard.USE_SUBTITLES]##echo ($html_disabled, '')[$sickbeard.USE_SUBTITLES]#>
|
||||
<p#if not $sickbeard.USE_SUBTITLES# class="grey-text"><del#end if#>download episode subtitles for this show#if not $sickbeard.USE_SUBTITLES#</del> ... (<span class="red-text">note: first <a href="$sbRoot/config/subtitles/">enable the subtitle system here</a></span>)#end if#</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div><!-- /component-group3 //-->
|
||||
|
||||
</div>
|
||||
|
||||
<div style="margin-top:15px">
|
||||
<input type="submit" id="submit" value="Update Show" class="btn btn-primary" />
|
||||
<a href="$sbRoot/home/displayShow?show=$show.indexerid" class="btn btn-primary" style="margin-left:10px">Cancel Edit</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#import sickbeard
|
||||
#from sickbeard.common import Quality, qualityPresets, qualityPresetStrings
|
||||
|
||||
#set $html_selected = ' selected="selected"'
|
||||
<div class="field-pair">
|
||||
<label for="qualityPreset" class="clearfix">
|
||||
#set $overall_quality = $Quality.combineQualities($anyQualities, $bestQualities)
|
||||
|
@ -9,8 +10,8 @@
|
|||
#set $selected = None
|
||||
<select id="qualityPreset" name="quality_preset" class="form-control form-control-inline input-sm">
|
||||
<option value="0">Custom</option>
|
||||
#for $curPreset in sorted($qualityPresets):
|
||||
<option value="$curPreset" #if $curPreset == $overall_quality then "selected=\"selected\"" else ""# #if $qualityPresetStrings[$curPreset].endswith("0p") then "style=\"padding-left: 15px;\"" else ""#>$qualityPresetStrings[$curPreset]</option>
|
||||
#for $curPreset in $qualityPresets:
|
||||
<option value="$curPreset"#echo ('', $html_selected)[$curPreset == $overall_quality]##echo ('', ' style="padding-left:15px"')[$qualityPresetStrings[$curPreset].endswith('0p')]#>$qualityPresetStrings[$curPreset]</option>
|
||||
#end for
|
||||
</select>
|
||||
<span>preferred episode quality to download</span>
|
||||
|
@ -19,18 +20,19 @@
|
|||
</div>
|
||||
|
||||
<div id="customQualityWrapper">
|
||||
<div id="customQuality" class="show-if-quality-custom">
|
||||
<div id="customQuality" class="show-if-quality-custom" style="display:none">
|
||||
<div class="component-group-desc">
|
||||
<p>An <em>Initial</em> quality episode must be found before an <em>Upgrade to</em> selection is considered.</p>
|
||||
<p>Upgrades continue until the highest selected of <em>Upgrade to</em> is matched.</p>
|
||||
</div>
|
||||
|
||||
<span class="component-desc">
|
||||
<div style="float:left; padding-right: 40px">
|
||||
<div style="float:left;padding-right:40px">
|
||||
<h4 class="jumbo">Initial</h4>
|
||||
#set $anyQualityList = filter(lambda x: x > $Quality.NONE, $Quality.qualityStrings)
|
||||
<select id="anyQualities" name="anyQualities" multiple="multiple" size="$len($anyQualityList)" class="form-control form-control-inline input-sm">
|
||||
#for $curQuality in sorted($anyQualityList):
|
||||
<option value="$curQuality" #if $curQuality in $anyQualities then "selected=\"selected\"" else ""#>$Quality.qualityStrings[$curQuality]</option>
|
||||
<option value="$curQuality"#echo ('', $html_selected)[$curQuality in $anyQualities]#>$Quality.qualityStrings[$curQuality]</option>
|
||||
#end for
|
||||
</select>
|
||||
</div>
|
||||
|
@ -40,7 +42,7 @@
|
|||
#set $bestQualityList = filter(lambda x: x > $Quality.SDTV and x < $Quality.UNKNOWN, $Quality.qualityStrings)
|
||||
<select id="bestQualities" name="bestQualities" multiple="multiple" size="$len($bestQualityList)" class="form-control form-control-inline input-sm">
|
||||
#for $curQuality in sorted($bestQualityList):
|
||||
<option value="$curQuality" #if $curQuality in $bestQualities then "selected=\"selected\"" else ""#>$Quality.qualityStrings[$curQuality]</option>
|
||||
<option value="$curQuality"#echo ('', $html_selected)[$curQuality in $bestQualities]#>$Quality.qualityStrings[$curQuality]</option>
|
||||
#end for
|
||||
</select>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#import sickbeard
|
||||
#import urllib
|
||||
#from sickbeard.helpers import anon_url
|
||||
#slurp
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -125,19 +126,22 @@
|
|||
<li><a href="$sbRoot/manage/manageSearches/" tabindex="$tab#set $tab += 1#"><i class="sgicon-search"></i>Manage Searches</a></li>
|
||||
<li><a href="$sbRoot/manage/showQueueOverview/" tabindex="$tab#set $tab += 1#"><i class="sgicon-showqueue"></i>Show Queue Overview</a></li>
|
||||
<li><a href="$sbRoot/manage/episodeStatuses/" tabindex="$tab#set $tab += 1#"><i class="sgicon-episodestatus"></i>Episode Status Management</a></li>
|
||||
#if $sickbeard.USE_PLEX and $sickbeard.PLEX_SERVER_HOST != ''
|
||||
<li><a href="$sbRoot/home/updatePLEX/" tabindex="$tab#set $tab += 1#"><i class="sgicon-plex"></i>Update PLEX</a></li>
|
||||
#if hasattr($sickbeard, 'USE_EMBY') and $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_XBMC and $sickbeard.XBMC_HOST != ''
|
||||
<li><a href="$sbRoot/home/updateXBMC/" tabindex="$tab#set $tab += 1#"><i class="sgicon-xbmc"></i>Update XBMC</a></li>
|
||||
#end if
|
||||
#if $sickbeard.USE_KODI and $sickbeard.KODI_HOST != ''
|
||||
#if hasattr($sickbeard, 'USE_KODI') and $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>
|
||||
#end if
|
||||
#if $sickbeard.USE_FAILED_DOWNLOADS
|
||||
#if hasattr($sickbeard, 'USE_XBMC') and $sickbeard.USE_XBMC and $sickbeard.XBMC_HOST != ''
|
||||
<li><a href="$sbRoot/home/updateXBMC/" tabindex="$tab#set $tab += 1#"><i class="sgicon-xbmc"></i>Update XBMC</a></li>
|
||||
#end if
|
||||
#if hasattr($sickbeard, 'USE_PLEX') and $sickbeard.USE_PLEX and $sickbeard.PLEX_SERVER_HOST != ''
|
||||
<li><a href="$sbRoot/home/updatePLEX/" tabindex="$tab#set $tab += 1#"><i class="sgicon-plex"></i>Update PLEX</a></li>
|
||||
#end if
|
||||
#if hasattr($sickbeard, 'USE_FAILED_DOWNLOADS') and $sickbeard.USE_FAILED_DOWNLOADS
|
||||
<li><a href="$sbRoot/manage/failedDownloads/" tabindex="$tab#set $tab += 1#"><i class="sgicon-failed"></i>Failed Downloads</a></li>
|
||||
#end if
|
||||
#if $sickbeard.USE_SUBTITLES
|
||||
#if hasattr($sickbeard, 'USE_SUBTITLES') and $sickbeard.USE_SUBTITLES
|
||||
<li><a href="$sbRoot/manage/subtitleMissed/" tabindex="$tab#set $tab += 1#"><i class="sgicon-subtitles"></i>Missed Subtitle Management</a></li>
|
||||
#end if
|
||||
</ul>
|
||||
|
@ -213,11 +217,10 @@
|
|||
#end if
|
||||
##
|
||||
#if sys.version_info < (2, 7, 9):
|
||||
<div class="alert alert-danger upgrade-notification" role="alert">
|
||||
<span>
|
||||
SickGear will be dropping support for Python 2.7.8 and below. We recommend updating to latest version:
|
||||
<a href="https://www.python.org/downloads/" onclick="window.open(this.href); return false;">Download here</a>
|
||||
</span>
|
||||
<div class="alert alert-danger upgrade-notification upgrade-py" role="alert">
|
||||
<p>As per notify 29 Nov 2015, SickGear no longer supports Python 2.7.8 and older<br />
|
||||
Please upgrade to Python <b>2.7.9</b> or newer (not 3.x.x): <a href="<%= anon_url('https://www.python.org/downloads/') %>" onclick="window.open(this.href);return !1;">Download here</a>
|
||||
</p>
|
||||
</div>
|
||||
#end if
|
||||
#if $sickbeard.NEWEST_VERSION_STRING
|
||||
|
|
|
@ -37,22 +37,30 @@
|
|||
});
|
||||
});
|
||||
|
||||
$('#testXBMC').click(function () {
|
||||
var xbmc_host = $.trim($('#xbmc_host').val());
|
||||
var xbmc_username = $.trim($('#xbmc_username').val());
|
||||
var xbmc_password = $.trim($('#xbmc_password').val());
|
||||
if (!xbmc_host) {
|
||||
$('#testXBMC-result').html('Please fill out the necessary fields above.');
|
||||
$('#xbmc_host').addClass('warning');
|
||||
$('#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;
|
||||
}
|
||||
$('#xbmc_host').removeClass('warning');
|
||||
$('#emby_host, #emby_apikey').removeClass('warning');
|
||||
$(this).prop('disabled', true);
|
||||
$('#testXBMC-result').html(loading);
|
||||
$.get(sbRoot + '/home/testXBMC', {'host': xbmc_host, 'username': xbmc_username, 'password': xbmc_password})
|
||||
$('#testEMBY-result').html(loading);
|
||||
$.get(sbRoot + '/home/testEMBY', {'host': emby_host, 'apikey': emby_apikey})
|
||||
.done(function (data) {
|
||||
$('#testXBMC-result').html(data);
|
||||
$('#testXBMC').prop('disabled', false);
|
||||
$('#testEMBY-result').html(data);
|
||||
$('#testEMBY').prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -75,6 +83,25 @@
|
|||
});
|
||||
});
|
||||
|
||||
$('#testXBMC').click(function () {
|
||||
var xbmc_host = $.trim($('#xbmc_host').val());
|
||||
var xbmc_username = $.trim($('#xbmc_username').val());
|
||||
var xbmc_password = $.trim($('#xbmc_password').val());
|
||||
if (!xbmc_host) {
|
||||
$('#testXBMC-result').html('Please fill out the necessary fields above.');
|
||||
$('#xbmc_host').addClass('warning');
|
||||
return;
|
||||
}
|
||||
$('#xbmc_host').removeClass('warning');
|
||||
$(this).prop('disabled', true);
|
||||
$('#testXBMC-result').html(loading);
|
||||
$.get(sbRoot + '/home/testXBMC', {'host': xbmc_host, 'username': xbmc_username, 'password': xbmc_password})
|
||||
.done(function (data) {
|
||||
$('#testXBMC-result').html(data);
|
||||
$('#testXBMC').prop('disabled', false);
|
||||
});
|
||||
});
|
||||
|
||||
// show instructions for plex when enabled
|
||||
$('#use_plex').click(function() {
|
||||
if ( $(this).is(':checked') ) {
|
||||
|
|
|
@ -2,81 +2,72 @@
|
|||
|
||||
$(document).ready(function () {
|
||||
|
||||
$.getJSON(sbRoot + '/home/addShows/getIndexerLanguages', {}, function (data) {
|
||||
var resultStr, flag, selected, current_lang_added = '';
|
||||
|
||||
if (data.results.length === 0) {
|
||||
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + config.show_lang + '.png)"';
|
||||
resultStr = '<option value="' + config.show_lang + '" selected="selected"' + flag + '>' + config.show_lang + '</option>';
|
||||
} else {
|
||||
current_lang_added = false;
|
||||
$.each(data.results, function (index, obj) {
|
||||
|
||||
if (obj === config.show_lang) {
|
||||
selected = ' selected="selected"';
|
||||
current_lang_added = true;
|
||||
}
|
||||
else {
|
||||
selected = '';
|
||||
}
|
||||
|
||||
flag = ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + obj + '.png);"';
|
||||
resultStr += '<option value="' + obj + '"' + selected + flag + '>' + obj + '</option>';
|
||||
});
|
||||
|
||||
if (!current_lang_added) {
|
||||
resultStr += '<option value=" ' + config.show_lang + '" selected="selected"> ' + config.show_lang + '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
$('#indexerLangSelectEdit').html(resultStr);
|
||||
|
||||
});
|
||||
|
||||
|
||||
var all_exceptions = [];
|
||||
|
||||
$('#location').fileBrowser({title: 'Select Show Location'});
|
||||
|
||||
$('#submit').click(function () {
|
||||
all_exceptions = [];
|
||||
function htmlFlag(lang) {
|
||||
return ' class="flag" style="background-image:url(' + sbRoot + '/images/flags/' + lang + '.png)"'
|
||||
}
|
||||
|
||||
$('#exceptions_list').find('option').each (function () {
|
||||
all_exceptions.push($(this).val());
|
||||
$.getJSON(sbRoot + '/home/addShows/getIndexerLanguages', {}, function (data) {
|
||||
var result = '', currentLangAdded = '', selected = ' selected="selected"';
|
||||
|
||||
if (0 == data.results.length) {
|
||||
result = '<option value="' + config.showLang + '"' + selected + htmlFlag(config.showLang) + '>'
|
||||
+ config.showLang + '</option>';
|
||||
} else {
|
||||
currentLangAdded = !1;
|
||||
$.each(data.results, function (index, strLang) {
|
||||
|
||||
var htmlSelected = '';
|
||||
if (strLang === config.showLang) {
|
||||
currentLangAdded = !0;
|
||||
htmlSelected = selected;
|
||||
}
|
||||
|
||||
result += '<option value="' + strLang + '"' + htmlSelected + htmlFlag(strLang) + '>'
|
||||
+ strLang + '</option>';
|
||||
});
|
||||
|
||||
if (!currentLangAdded)
|
||||
result += '<option value="' + config.showLang + '" ' + selected + '>' + config.showLang + '</option>';
|
||||
}
|
||||
|
||||
$('#indexerLangSelectEdit').html(result);
|
||||
});
|
||||
|
||||
function getExceptions() {
|
||||
var allExceptions = [];
|
||||
|
||||
$('#exceptions_list').find('option').each(function () {
|
||||
allExceptions.push($(this).val());
|
||||
});
|
||||
|
||||
$('#exceptions_list').val(all_exceptions);
|
||||
if (config.show_isanime) {
|
||||
return allExceptions
|
||||
}
|
||||
|
||||
$('#submit').click(function () {
|
||||
$('#exceptions_list').val(getExceptions());
|
||||
if (config.showIsAnime)
|
||||
generate_bwlist();
|
||||
}
|
||||
});
|
||||
|
||||
$('#addSceneName').click(function () {
|
||||
var scene_ex = $('#SceneName').val();
|
||||
var scene_ex_season = $('#SceneNameSeason').val();
|
||||
var option = $('<option>');
|
||||
all_exceptions = [];
|
||||
var elSceneName = $('#SceneName'), elSceneNameSeason = $('#SceneNameSeason'),
|
||||
sceneEx = elSceneName.val(), sceneExSeason = elSceneNameSeason.val();
|
||||
|
||||
$('#exceptions_list').find('option').each (function () {
|
||||
all_exceptions.push($(this).val());
|
||||
});
|
||||
elSceneName.val('');
|
||||
elSceneNameSeason.val('');
|
||||
|
||||
$('#SceneName').val('');
|
||||
$('#SceneNameSeason').val('');
|
||||
|
||||
if ($.inArray(scene_ex_season + '|' + scene_ex, all_exceptions) > -1 || (scene_ex === '')) {
|
||||
if (-1 < $.inArray(sceneExSeason + '|' + sceneEx, getExceptions()) || ('' === sceneEx))
|
||||
return;
|
||||
}
|
||||
$('#SceneException').show();
|
||||
|
||||
option.attr('value', scene_ex_season + '|' + scene_ex);
|
||||
if (scene_ex_season === "-1") {
|
||||
option.html('S*: ' + scene_ex);
|
||||
}
|
||||
else {
|
||||
option.html('S' + scene_ex_season + ': ' + scene_ex);
|
||||
}
|
||||
return option.appendTo('#exceptions_list');
|
||||
$('#SceneException').fadeIn('fast', 'linear');
|
||||
|
||||
var option = $('<option>');
|
||||
option.attr('value', sceneExSeason + '|' + sceneEx);
|
||||
option.html((config.showIsAnime ? 'S' + ('-1' === sceneExSeason ? '*' : sceneExSeason) + ': ' : '') + sceneEx);
|
||||
|
||||
return option.appendTo($('#exceptions_list'));
|
||||
});
|
||||
|
||||
$('#removeSceneName').click(function () {
|
||||
|
@ -86,21 +77,41 @@ $(document).ready(function () {
|
|||
});
|
||||
|
||||
$.fn.toggle_SceneException = function () {
|
||||
all_exceptions = [];
|
||||
var elSceneException = $('#SceneException');
|
||||
|
||||
$('#exceptions_list').find('option').each (function () {
|
||||
all_exceptions.push($(this).val());
|
||||
});
|
||||
|
||||
if ('' === all_exceptions) {
|
||||
$('#SceneException').hide();
|
||||
}
|
||||
else {
|
||||
$('#SceneException').show();
|
||||
}
|
||||
if (0 == getExceptions().length)
|
||||
elSceneException.fadeOut('fast', 'linear');
|
||||
else
|
||||
elSceneException.fadeIn('fast', 'linear');
|
||||
};
|
||||
|
||||
$(this).toggle_SceneException();
|
||||
|
||||
var elABD = $('#air_by_date'), elScene = $('#scene'), elSports = $('#sports'), elAnime = $('#anime');
|
||||
|
||||
});
|
||||
function uncheck(el){el.prop('checked', !1)}
|
||||
function checked(el){return el.prop('checked')}
|
||||
|
||||
function isAnime(){
|
||||
uncheck(elABD); uncheck(elSports);
|
||||
if (config.showIsAnime){ $('#blackwhitelist').fadeIn('fast', 'linear'); } return !0; }
|
||||
function isScene(){ uncheck(elABD); uncheck(elSports); }
|
||||
function isABD(){ uncheck(elAnime); uncheck(elScene); $('#blackwhitelist').fadeOut('fast', 'linear'); }
|
||||
function isSports(){ uncheck(elAnime); uncheck(elScene); $('#blackwhitelist').fadeOut('fast', 'linear'); }
|
||||
|
||||
if (checked(elAnime)) { isAnime(); }
|
||||
if (checked(elScene)) { isScene(); }
|
||||
if (checked(elABD)) { isABD(); }
|
||||
if (checked(elSports)) { isSports() }
|
||||
|
||||
elAnime.on('click', function() {
|
||||
if (checked(elAnime))
|
||||
isAnime() && !config.showIsAnime && $('#anime-options').fadeIn('fast', 'linear');
|
||||
else
|
||||
$('#blackwhitelist, #anime-options').fadeOut('fast', 'linear');
|
||||
});
|
||||
elScene.on('click', function() { isScene(); });
|
||||
elABD.on('click', function() { isABD(); });
|
||||
elSports.on('click', function() { isSports() });
|
||||
|
||||
});
|
||||
|
|
|
@ -27,10 +27,12 @@ function initActions() {
|
|||
$('#SubMenu a:contains("Show Queue Overview")').addClass('btn').html('<i class="sgicon-showqueue"></i>Show Queue Overview');
|
||||
$('#SubMenu a[href$="/manage/failedDownloads/"]').addClass('btn').html('<i class="sgicon-failed"></i>Failed Downloads');
|
||||
$('#SubMenu a:contains("Notification")').addClass('btn').html('<i class="sgicon-notification"></i>Notifications');
|
||||
$('#SubMenu a:contains("Update show in XBMC")').addClass('btn').html('<i class="sgicon-xbmc"></i>Update show in 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[href$="/home/updateEMBY/"]').addClass('btn').html('<i class="sgicon-emby"></i>Update Emby');
|
||||
$('#SubMenu a[href$="/home/updateKODI/"]').addClass('btn').html('<i class="sgicon-kodi"></i>Update Kodi');
|
||||
$('#SubMenu a[href$="/home/updateXBMC/"]').addClass('btn').html('<i class="sgicon-xbmc"></i>Update XBMC');
|
||||
$('#SubMenu a:contains("Update show in Emby")').addClass('btn').html('<i class="sgicon-emby"></i>Update show in Emby');
|
||||
$('#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 XBMC")').addClass('btn').html('<i class="sgicon-xbmc"></i>Update show in XBMC');
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
|
|
@ -2,7 +2,7 @@ function setFromPresets (preset) {
|
|||
var elCustomQuality = $('.show-if-quality-custom'),
|
||||
selected = 'selected';
|
||||
if (preset = parseInt(preset)) {
|
||||
elCustomQuality.hide();
|
||||
elCustomQuality.fadeOut('fast', 'linear');
|
||||
|
||||
var upgrade = !0;
|
||||
$('#anyQualities, #bestQualities').find('option').each(function() {
|
||||
|
@ -18,7 +18,7 @@ function setFromPresets (preset) {
|
|||
$(this).attr(selected, ((preset & parseInt($(this).val())) ? selected : false));
|
||||
});
|
||||
} else
|
||||
elCustomQuality.show();
|
||||
elCustomQuality.fadeIn('fast', 'linear');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
@ -30,4 +30,4 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
setFromPresets(elQualityPreset.find(selected).val());
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,8 +42,10 @@ from indexers.indexer_config import INDEXER_TVDB
|
|||
from indexers.indexer_api import indexerApi
|
||||
from indexers.indexer_exceptions import indexer_shownotfound, indexer_exception, indexer_error, \
|
||||
indexer_episodenotfound, indexer_attributenotfound, indexer_seasonnotfound, indexer_userabort, indexerExcepts
|
||||
from sickbeard.exceptions import ex
|
||||
from sickbeard.providers.generic import GenericProvider
|
||||
from sickbeard import encodingKludge as ek
|
||||
from lib.adba.aniDBerrors import (AniDBError, AniDBBannedError)
|
||||
from lib.configobj import ConfigObj
|
||||
from lib.libtrakt import TraktAPI
|
||||
import trakt_helpers
|
||||
|
@ -253,17 +255,10 @@ TORRENT_HIGH_BANDWIDTH = False
|
|||
TORRENT_LABEL = ''
|
||||
TORRENT_VERIFY_CERT = False
|
||||
|
||||
USE_XBMC = False
|
||||
XBMC_ALWAYS_ON = True
|
||||
XBMC_NOTIFY_ONSNATCH = False
|
||||
XBMC_NOTIFY_ONDOWNLOAD = False
|
||||
XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = False
|
||||
XBMC_UPDATE_LIBRARY = False
|
||||
XBMC_UPDATE_FULL = False
|
||||
XBMC_UPDATE_ONLYFIRST = False
|
||||
XBMC_HOST = ''
|
||||
XBMC_USERNAME = None
|
||||
XBMC_PASSWORD = None
|
||||
USE_EMBY = False
|
||||
EMBY_UPDATE_LIBRARY = False
|
||||
EMBY_HOST = None
|
||||
EMBY_APIKEY = None
|
||||
|
||||
USE_KODI = False
|
||||
KODI_ALWAYS_ON = True
|
||||
|
@ -277,6 +272,18 @@ KODI_HOST = ''
|
|||
KODI_USERNAME = None
|
||||
KODI_PASSWORD = None
|
||||
|
||||
USE_XBMC = False
|
||||
XBMC_ALWAYS_ON = True
|
||||
XBMC_NOTIFY_ONSNATCH = False
|
||||
XBMC_NOTIFY_ONDOWNLOAD = False
|
||||
XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = False
|
||||
XBMC_UPDATE_LIBRARY = False
|
||||
XBMC_UPDATE_FULL = False
|
||||
XBMC_UPDATE_ONLYFIRST = False
|
||||
XBMC_HOST = ''
|
||||
XBMC_USERNAME = None
|
||||
XBMC_PASSWORD = None
|
||||
|
||||
USE_PLEX = False
|
||||
PLEX_NOTIFY_ONSNATCH = False
|
||||
PLEX_NOTIFY_ONDOWNLOAD = False
|
||||
|
@ -488,12 +495,15 @@ def initialize(consoleLogging=True):
|
|||
SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_HOST, \
|
||||
NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \
|
||||
TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_VERIFY_CERT, \
|
||||
USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \
|
||||
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_EMBY, EMBY_UPDATE_LIBRARY, EMBY_HOST, EMBY_APIKEY, \
|
||||
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_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD,\
|
||||
XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
|
||||
USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
PLEX_UPDATE_LIBRARY, PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_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_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \
|
||||
PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, MAX_BACKLOG_FREQUENCY, BACKLOG_STARTUP, SKIP_REMOVED_FILES, \
|
||||
BACKLOG_FREQUENCY, 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, \
|
||||
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, \
|
||||
|
@ -535,8 +545,9 @@ def initialize(consoleLogging=True):
|
|||
CheckSection(CFG, 'Blackhole')
|
||||
CheckSection(CFG, 'SABnzbd')
|
||||
CheckSection(CFG, 'NZBget')
|
||||
CheckSection(CFG, 'XBMC')
|
||||
CheckSection(CFG, 'Emby')
|
||||
CheckSection(CFG, 'Kodi')
|
||||
CheckSection(CFG, 'XBMC')
|
||||
CheckSection(CFG, 'PLEX')
|
||||
CheckSection(CFG, 'Growl')
|
||||
CheckSection(CFG, 'Prowl')
|
||||
|
@ -781,17 +792,10 @@ def initialize(consoleLogging=True):
|
|||
TORRENT_LABEL = check_setting_str(CFG, 'TORRENT', 'torrent_label', '')
|
||||
TORRENT_VERIFY_CERT = bool(check_setting_int(CFG, 'TORRENT', 'torrent_verify_cert', 0))
|
||||
|
||||
USE_XBMC = bool(check_setting_int(CFG, 'XBMC', 'use_xbmc', 0))
|
||||
XBMC_ALWAYS_ON = bool(check_setting_int(CFG, 'XBMC', 'xbmc_always_on', 1))
|
||||
XBMC_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_onsnatch', 0))
|
||||
XBMC_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_ondownload', 0))
|
||||
XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_onsubtitledownload', 0))
|
||||
XBMC_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_library', 0))
|
||||
XBMC_UPDATE_FULL = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_full', 0))
|
||||
XBMC_UPDATE_ONLYFIRST = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_onlyfirst', 0))
|
||||
XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
|
||||
XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
|
||||
XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
|
||||
USE_EMBY = bool(check_setting_int(CFG, 'Emby', 'use_emby', 0))
|
||||
EMBY_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Emby', 'emby_update_library', 0))
|
||||
EMBY_HOST = check_setting_str(CFG, 'Emby', 'emby_host', '')
|
||||
EMBY_APIKEY = check_setting_str(CFG, 'Emby', 'emby_apikey', '')
|
||||
|
||||
USE_KODI = bool(check_setting_int(CFG, 'Kodi', 'use_kodi', 0))
|
||||
KODI_ALWAYS_ON = bool(check_setting_int(CFG, 'Kodi', 'kodi_always_on', 1))
|
||||
|
@ -805,6 +809,18 @@ def initialize(consoleLogging=True):
|
|||
KODI_USERNAME = check_setting_str(CFG, 'Kodi', 'kodi_username', '')
|
||||
KODI_PASSWORD = check_setting_str(CFG, 'Kodi', 'kodi_password', '')
|
||||
|
||||
USE_XBMC = bool(check_setting_int(CFG, 'XBMC', 'use_xbmc', 0))
|
||||
XBMC_ALWAYS_ON = bool(check_setting_int(CFG, 'XBMC', 'xbmc_always_on', 1))
|
||||
XBMC_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_onsnatch', 0))
|
||||
XBMC_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_ondownload', 0))
|
||||
XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify_onsubtitledownload', 0))
|
||||
XBMC_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_library', 0))
|
||||
XBMC_UPDATE_FULL = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_full', 0))
|
||||
XBMC_UPDATE_ONLYFIRST = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update_onlyfirst', 0))
|
||||
XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
|
||||
XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
|
||||
XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
|
||||
|
||||
USE_PLEX = bool(check_setting_int(CFG, 'Plex', 'use_plex', 0))
|
||||
PLEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Plex', 'plex_notify_onsnatch', 0))
|
||||
PLEX_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Plex', 'plex_notify_ondownload', 0))
|
||||
|
@ -1335,7 +1351,12 @@ def halt():
|
|||
pass
|
||||
|
||||
if ADBA_CONNECTION:
|
||||
ADBA_CONNECTION.logout()
|
||||
try:
|
||||
ADBA_CONNECTION.logout()
|
||||
except AniDBBannedError as e:
|
||||
logger.log(u'ANIDB Error %s' % ex(e), logger.DEBUG)
|
||||
except AniDBError as e:
|
||||
pass
|
||||
logger.log(u'Waiting for the ANIDB CONNECTION thread to exit')
|
||||
try:
|
||||
ADBA_CONNECTION.join(10)
|
||||
|
@ -1591,18 +1612,11 @@ def save_config():
|
|||
new_config['TORRENT']['torrent_label'] = TORRENT_LABEL
|
||||
new_config['TORRENT']['torrent_verify_cert'] = int(TORRENT_VERIFY_CERT)
|
||||
|
||||
new_config['XBMC'] = {}
|
||||
new_config['XBMC']['use_xbmc'] = int(USE_XBMC)
|
||||
new_config['XBMC']['xbmc_always_on'] = int(XBMC_ALWAYS_ON)
|
||||
new_config['XBMC']['xbmc_notify_onsnatch'] = int(XBMC_NOTIFY_ONSNATCH)
|
||||
new_config['XBMC']['xbmc_notify_ondownload'] = int(XBMC_NOTIFY_ONDOWNLOAD)
|
||||
new_config['XBMC']['xbmc_notify_onsubtitledownload'] = int(XBMC_NOTIFY_ONSUBTITLEDOWNLOAD)
|
||||
new_config['XBMC']['xbmc_update_library'] = int(XBMC_UPDATE_LIBRARY)
|
||||
new_config['XBMC']['xbmc_update_full'] = int(XBMC_UPDATE_FULL)
|
||||
new_config['XBMC']['xbmc_update_onlyfirst'] = int(XBMC_UPDATE_ONLYFIRST)
|
||||
new_config['XBMC']['xbmc_host'] = XBMC_HOST
|
||||
new_config['XBMC']['xbmc_username'] = XBMC_USERNAME
|
||||
new_config['XBMC']['xbmc_password'] = helpers.encrypt(XBMC_PASSWORD, ENCRYPTION_VERSION)
|
||||
new_config['Emby'] = {}
|
||||
new_config['Emby']['use_emby'] = int(USE_EMBY)
|
||||
new_config['Emby']['emby_update_library'] = int(EMBY_UPDATE_LIBRARY)
|
||||
new_config['Emby']['emby_host'] = EMBY_HOST
|
||||
new_config['Emby']['emby_apikey'] = EMBY_APIKEY
|
||||
|
||||
new_config['Kodi'] = {}
|
||||
new_config['Kodi']['use_kodi'] = int(USE_KODI)
|
||||
|
@ -1617,6 +1631,19 @@ def save_config():
|
|||
new_config['Kodi']['kodi_username'] = KODI_USERNAME
|
||||
new_config['Kodi']['kodi_password'] = helpers.encrypt(KODI_PASSWORD, ENCRYPTION_VERSION)
|
||||
|
||||
new_config['XBMC'] = {}
|
||||
new_config['XBMC']['use_xbmc'] = int(USE_XBMC)
|
||||
new_config['XBMC']['xbmc_always_on'] = int(XBMC_ALWAYS_ON)
|
||||
new_config['XBMC']['xbmc_notify_onsnatch'] = int(XBMC_NOTIFY_ONSNATCH)
|
||||
new_config['XBMC']['xbmc_notify_ondownload'] = int(XBMC_NOTIFY_ONDOWNLOAD)
|
||||
new_config['XBMC']['xbmc_notify_onsubtitledownload'] = int(XBMC_NOTIFY_ONSUBTITLEDOWNLOAD)
|
||||
new_config['XBMC']['xbmc_update_library'] = int(XBMC_UPDATE_LIBRARY)
|
||||
new_config['XBMC']['xbmc_update_full'] = int(XBMC_UPDATE_FULL)
|
||||
new_config['XBMC']['xbmc_update_onlyfirst'] = int(XBMC_UPDATE_ONLYFIRST)
|
||||
new_config['XBMC']['xbmc_host'] = XBMC_HOST
|
||||
new_config['XBMC']['xbmc_username'] = XBMC_USERNAME
|
||||
new_config['XBMC']['xbmc_password'] = helpers.encrypt(XBMC_PASSWORD, ENCRYPTION_VERSION)
|
||||
|
||||
new_config['Plex'] = {}
|
||||
new_config['Plex']['use_plex'] = int(USE_PLEX)
|
||||
new_config['Plex']['plex_notify_onsnatch'] = int(PLEX_NOTIFY_ONSNATCH)
|
||||
|
|
|
@ -1125,6 +1125,10 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
|
|||
req_headers.update(headers)
|
||||
session.headers.update(req_headers)
|
||||
|
||||
mute_connect_err = kwargs.get('mute_connect_err')
|
||||
if mute_connect_err:
|
||||
del(kwargs['mute_connect_err'])
|
||||
|
||||
# request session ssl verify
|
||||
session.verify = False
|
||||
|
||||
|
@ -1177,7 +1181,7 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
|
|||
logger.log(u'HTTP error %s while loading URL %s' % (e.errno, e.request.url), logger.WARNING)
|
||||
return
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
if not kwargs.get('mute_connect_err'):
|
||||
if not mute_connect_err:
|
||||
logger.log(u'Connection error msg:%s while loading URL %s' % (e.message, e.request.url), logger.WARNING)
|
||||
return
|
||||
except requests.exceptions.ReadTimeout as e:
|
||||
|
|
|
@ -16,8 +16,9 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import xbmc
|
||||
import emby
|
||||
import kodi
|
||||
import xbmc
|
||||
import plex
|
||||
import nmj
|
||||
import nmjv2
|
||||
|
@ -40,8 +41,9 @@ from lib import libtrakt
|
|||
import emailnotify
|
||||
|
||||
# home theater / nas
|
||||
xbmc_notifier = xbmc.XBMCNotifier()
|
||||
emby_notifier = emby.EmbyNotifier()
|
||||
kodi_notifier = kodi.KodiNotifier()
|
||||
xbmc_notifier = xbmc.XBMCNotifier()
|
||||
plex_notifier = plex.PLEXNotifier()
|
||||
nmj_notifier = nmj.NMJNotifier()
|
||||
nmjv2_notifier = nmjv2.NMJv2Notifier()
|
||||
|
@ -64,8 +66,8 @@ email_notifier = emailnotify.EmailNotifier()
|
|||
|
||||
notifiers = [
|
||||
libnotify_notifier, # Libnotify notifier goes first because it doesn't involve blocking on network activity.
|
||||
xbmc_notifier,
|
||||
kodi_notifier,
|
||||
xbmc_notifier,
|
||||
plex_notifier,
|
||||
nmj_notifier,
|
||||
nmjv2_notifier,
|
||||
|
|
170
sickbeard/notifiers/emby.py
Normal file
170
sickbeard/notifiers/emby.py
Normal file
|
@ -0,0 +1,170 @@
|
|||
# coding=utf-8
|
||||
#
|
||||
# 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 sickbeard
|
||||
from sickbeard import logger
|
||||
|
||||
|
||||
class EmbyNotifier:
|
||||
def __init__(self):
|
||||
self.sg_logo_url = 'https://raw.githubusercontent.com/SickGear/SickGear/master/gui/slick/images/ico/' + \
|
||||
'apple-touch-icon-precomposed.png'
|
||||
self.response = None
|
||||
self.test_mode = False
|
||||
|
||||
def _notify_emby(self, msg, hosts=None, apikeys=None):
|
||||
""" Internal wrapper for the test_notify function
|
||||
|
||||
Args:
|
||||
msg: Message body of the notice to send
|
||||
|
||||
Returns:
|
||||
2-Tuple True if msg successfully sent otherwise False, Failure message string or None
|
||||
"""
|
||||
|
||||
if not sickbeard.USE_EMBY and not self.test_mode:
|
||||
self._log(u'Notification not enabled, skipping this notification', logger.DEBUG)
|
||||
return False, None
|
||||
|
||||
hosts, keys, message = self._check_config(hosts, apikeys)
|
||||
if not hosts:
|
||||
return False, message
|
||||
|
||||
total_success = True
|
||||
messages = []
|
||||
|
||||
args = dict(post_json={'Name': 'SickGear', 'Description': msg, 'ImageUrl': self.sg_logo_url})
|
||||
for i, cur_host in enumerate(hosts):
|
||||
|
||||
self.response = None
|
||||
response = sickbeard.helpers.getURL(
|
||||
'http://%s/emby/Notifications/Admin' % cur_host,
|
||||
headers={'Content-type': 'application/json', 'X-MediaBrowser-Token': keys[i]},
|
||||
timeout=10, hooks=dict(response=self._cb_response), **args)
|
||||
if not response or self.response:
|
||||
if self.response and 401 == self.response.get('status_code'):
|
||||
total_success = False
|
||||
messages += ['Fail: Cannot authenticate API key with %s' % cur_host]
|
||||
self._log(u'Failed to authenticate with %s' % cur_host)
|
||||
continue
|
||||
elif not response and not self.response or not self.response.get('ok'):
|
||||
total_success = False
|
||||
messages += ['Fail: No supported Emby server found at %s' % cur_host]
|
||||
self._log(u'Warning, could not connect with server at ' + cur_host)
|
||||
continue
|
||||
messages += ['OK: %s' % cur_host]
|
||||
|
||||
return total_success, '<br />\n'.join(messages)
|
||||
|
||||
def _update_library(self, show=None):
|
||||
|
||||
hosts, keys, message = self._check_config()
|
||||
if not hosts:
|
||||
self._log(u'Issue with hosts or api keys, check your settings')
|
||||
return False
|
||||
|
||||
from sickbeard.indexers.indexer_config import INDEXER_TVDB
|
||||
args = show and INDEXER_TVDB == show.indexer \
|
||||
and dict(post_json={'TvdbId': '%s' % show.indexerid}) or dict(data=None)
|
||||
mode_to_log = show and 'show "%s"' % show.name or 'all shows'
|
||||
total_success = True
|
||||
for i, cur_host in enumerate(hosts):
|
||||
|
||||
self.response = None
|
||||
# noinspection PyArgumentList
|
||||
response = sickbeard.helpers.getURL(
|
||||
'http://%s/emby/Library/Series/Updated' % cur_host,
|
||||
headers={'Content-type': 'application/json', 'X-MediaBrowser-Token': keys[i]},
|
||||
timeout=20, hooks=dict(response=self._cb_response), **args)
|
||||
# Emby will initiate a LibraryMonitor path refresh one minute after this success
|
||||
if self.response and 204 == self.response.get('status_code') and self.response.get('ok'):
|
||||
self._log(u'Success: update %s sent to host %s in a library updated call' % (mode_to_log, cur_host),
|
||||
logger.MESSAGE)
|
||||
continue
|
||||
elif self.response and 401 == self.response.get('status_code'):
|
||||
self._log(u'Failed to authenticate with %s' % cur_host)
|
||||
elif self.response and 404 == self.response.get('status_code'):
|
||||
self._log(u'Warning, Library update responded 404 not found at %s' % cur_host, logger.DEBUG)
|
||||
elif not response and not self.response or not self.response.get('ok'):
|
||||
self._log(u'Warning, could not connect with server at %s' % cur_host)
|
||||
else:
|
||||
self._log(u'Warning, unknown response %sfrom %s, can most likely be ignored'
|
||||
% (self.response and '%s ' % self.response.get('status_code') or '', cur_host), logger.DEBUG)
|
||||
total_success = False
|
||||
|
||||
return total_success
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def _cb_response(self, r, *args, **kwargs):
|
||||
|
||||
self.response = dict(status_code=r.status_code, ok=r.ok)
|
||||
return r
|
||||
|
||||
def _check_config(self, hosts=None, apikeys=None):
|
||||
|
||||
from sickbeard.helpers import starify
|
||||
|
||||
hosts, keys = hosts or sickbeard.EMBY_HOST, apikeys or sickbeard.EMBY_APIKEY
|
||||
hosts = [x.strip() for x in hosts.split(',') if x.strip()]
|
||||
keys = [x.strip() for x in keys.split(',') if x.strip()]
|
||||
|
||||
new_keys = []
|
||||
has_old_key = False
|
||||
for key in keys:
|
||||
if starify(key, True):
|
||||
has_old_key = True
|
||||
else:
|
||||
new_keys += [key]
|
||||
|
||||
apikeys = (new_keys, [x.strip() for x in sickbeard.EMBY_APIKEY.split(',') if x.strip()] + new_keys)[has_old_key]
|
||||
|
||||
if len(hosts) != len(apikeys):
|
||||
message = ('Not enough Api keys for hosts', 'More Api keys than hosts')[len(apikeys) > len(hosts)]
|
||||
self._log(u'%s, check your settings' % message)
|
||||
return False, False, message
|
||||
|
||||
return hosts, apikeys, 'OK'
|
||||
|
||||
@staticmethod
|
||||
def _log(msg, log_level=logger.WARNING):
|
||||
|
||||
logger.log(u'Emby: %s' % msg, log_level)
|
||||
|
||||
##############################################################################
|
||||
# Public functions
|
||||
##############################################################################
|
||||
|
||||
def test_notify(self, host, apikey):
|
||||
|
||||
self.test_mode = True
|
||||
result = self._notify_emby('Testing SickGear Emby notifier', host, apikey)
|
||||
self.test_mode = False
|
||||
return result
|
||||
|
||||
def update_library(self, show=None, force=False):
|
||||
""" Wrapper for the update library functions
|
||||
|
||||
:param show: TVShow object
|
||||
:param force: True force update process
|
||||
|
||||
Returns: None if no processing done, True if processing succeeded with no issues else False if any issues found
|
||||
"""
|
||||
if sickbeard.USE_EMBY and (sickbeard.EMBY_UPDATE_LIBRARY or force):
|
||||
return self._update_library(show)
|
||||
|
||||
|
||||
notifier = EmbyNotifier
|
|
@ -48,6 +48,26 @@ class KodiNotifier:
|
|||
self.prefix = ''
|
||||
self.test_mode = False
|
||||
|
||||
@staticmethod
|
||||
def _log(msg, log_level=logger.WARNING):
|
||||
|
||||
logger.log(u'Kodi: %s' % msg, log_level)
|
||||
|
||||
def _maybe_log(self, msg, log_level=logger.WARNING):
|
||||
|
||||
if msg and (sickbeard.KODI_ALWAYS_ON or self.test_mode):
|
||||
self._log(msg + (not sickbeard.KODI_ALWAYS_ON and self.test_mode and
|
||||
' (Test mode ignores "Always On")' or ''), log_level)
|
||||
|
||||
def _maybe_log_failed_detection(self, host, msg='connect to'):
|
||||
|
||||
self._maybe_log(u'Failed to %s %s, check device(s) and config.' % (msg, host), logger.ERROR)
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def cb_response(self, r, *args, **kwargs):
|
||||
self.response = dict(status_code=r.status_code)
|
||||
return r
|
||||
|
||||
def _get_kodi_version(self, host):
|
||||
""" Return Kodi JSON-RPC API version (odd # = dev, even # = stable)
|
||||
|
||||
|
@ -67,7 +87,8 @@ class KodiNotifier:
|
|||
6 | v12 (Frodo) / v13 (Gotham)
|
||||
"""
|
||||
|
||||
response = self._send_to_kodi_json(host, dict(method='JSONRPC.Version'), 10)
|
||||
timeout = 10
|
||||
response = self._send_to_kodi_json(host, dict(method='JSONRPC.Version'), timeout)
|
||||
if self.response and 401 == self.response.get('status_code'):
|
||||
return False
|
||||
|
||||
|
@ -77,13 +98,13 @@ class KodiNotifier:
|
|||
|
||||
# fallback to legacy HTTPAPI method
|
||||
test_command = {'command': 'Help'}
|
||||
if self._send_to_kodi(host, test_command):
|
||||
if self._send_to_kodi(host, test_command, timeout):
|
||||
# return fake version number to use the legacy method
|
||||
return 1
|
||||
|
||||
if self.response and 404 == self.response.get('status_code'):
|
||||
self.prefix = 'xbmc'
|
||||
if self._send_to_kodi(host, test_command):
|
||||
if self._send_to_kodi(host, test_command, timeout):
|
||||
# return fake version number to use the legacy method
|
||||
return 1
|
||||
|
||||
|
@ -125,7 +146,7 @@ class KodiNotifier:
|
|||
elif not api_version:
|
||||
total_success = False
|
||||
message += ['Fail: No supported Kodi found at %s' % cur_host]
|
||||
self._maybe_log_failed_detection(cur_host)
|
||||
self._maybe_log_failed_detection(cur_host, 'connect and detect version for')
|
||||
else:
|
||||
if 4 >= api_version:
|
||||
self._log(u'Detected %sversion <= 11, using HTTP API'
|
||||
|
@ -141,12 +162,62 @@ class KodiNotifier:
|
|||
'message': '%s' % msg,
|
||||
'image': '%s' % self.sg_logo_url})
|
||||
|
||||
response_notify = __method_send(cur_host, command)
|
||||
response_notify = __method_send(cur_host, command, 10)
|
||||
if response_notify:
|
||||
message += ['%s: %s' % ((response_notify, 'OK')['OK' in response_notify], cur_host)]
|
||||
|
||||
return total_success, '<br />\n'.join(message)
|
||||
|
||||
def _update_library(self, show_name=None):
|
||||
""" Wrapper for the update library functions
|
||||
|
||||
Call either the JSON-RPC over HTTP or the legacy HTTP API methods depending on the Kodi API version.
|
||||
|
||||
Uses a list of comma delimited hosts where only one is updated, the first to respond with success. This is a
|
||||
workaround for SQL backend users because updating multiple clients causes duplicate entries.
|
||||
|
||||
Future plan is to revisit how host/ip/username/pw/options are stored so that this may become more flexible.
|
||||
|
||||
Args:
|
||||
show_name: Name of a TV show to target for a library update
|
||||
|
||||
Returns: True if processing succeeded with no issues else False if any issues found
|
||||
"""
|
||||
if not sickbeard.KODI_HOST:
|
||||
self._log(u'No Kodi hosts specified, check your settings')
|
||||
return False
|
||||
|
||||
# either update each host, or only attempt to update until one successful result
|
||||
result = 0
|
||||
only_first = dict(show='', first='', first_note='')
|
||||
show_name and only_first.update(show=' for show;"%s"' % show_name)
|
||||
sickbeard.KODI_UPDATE_ONLYFIRST and only_first.update(dict(
|
||||
first=' first', first_note=' in line with the "Only update first host"%s' % ' setting'))
|
||||
|
||||
for cur_host in [x.strip() for x in sickbeard.KODI_HOST.split(',')]:
|
||||
|
||||
response = self._send_to_kodi_json(cur_host, dict(method='Profiles.GetCurrentProfile'))
|
||||
if self.response and 401 == self.response.get('status_code'):
|
||||
self._log(u'Failed to authenticate with %s' % cur_host, logger.DEBUG)
|
||||
continue
|
||||
if not response:
|
||||
self._maybe_log_failed_detection(cur_host)
|
||||
continue
|
||||
|
||||
if self._send_update_library(cur_host, show_name):
|
||||
only_first.update(dict(profile=response.get('label') or 'Master', host=cur_host))
|
||||
self._log('Success: profile;' +
|
||||
u'"%(profile)s" at%(first)s host;%(host)s updated%(show)s%(first_note)s' % only_first)
|
||||
else:
|
||||
self._maybe_log_failed_detection(cur_host)
|
||||
result += 1
|
||||
|
||||
if sickbeard.KODI_UPDATE_ONLYFIRST:
|
||||
return True
|
||||
|
||||
# needed for the 'update kodi' submenu command as it only cares of the final result vs the individual ones
|
||||
return 0 == result
|
||||
|
||||
def _send_update_library(self, host, show_name=None):
|
||||
""" Internal wrapper for the update library function
|
||||
|
||||
|
@ -164,7 +235,7 @@ class KodiNotifier:
|
|||
api_version = self._get_kodi_version(host)
|
||||
if api_version:
|
||||
# try to update just the show, if it fails, do full update if enabled
|
||||
__method_update = (self._update_library, self._update_library_json)[4 < api_version]
|
||||
__method_update = (self._update, self._update_json)[4 < api_version]
|
||||
if __method_update(host, show_name):
|
||||
return True
|
||||
|
||||
|
@ -181,7 +252,7 @@ class KodiNotifier:
|
|||
# Legacy HTTP API (pre Kodi 12) methods
|
||||
##############################################################################
|
||||
|
||||
def _send_to_kodi(self, host, command):
|
||||
def _send_to_kodi(self, host, command, timeout=30):
|
||||
""" Handle communication to Kodi servers via HTTP API
|
||||
|
||||
Args:
|
||||
|
@ -203,11 +274,12 @@ class KodiNotifier:
|
|||
args['auth'] = (self.username or sickbeard.KODI_USERNAME, self.password or sickbeard.KODI_PASSWORD)
|
||||
|
||||
url = 'http://%s/%sCmds/%sHttp' % (host, self.prefix or 'kodi', self.prefix or 'kodi')
|
||||
response = sickbeard.helpers.getURL(url=url, params=command, hooks=dict(response=self.cb_response), **args)
|
||||
response = sickbeard.helpers.getURL(url=url, params=command,
|
||||
timeout=timeout, hooks=dict(response=self.cb_response), **args)
|
||||
|
||||
return response or False
|
||||
|
||||
def _update_library(self, host=None, show_name=None):
|
||||
def _update(self, host=None, show_name=None):
|
||||
""" Handle updating Kodi host via HTTP API
|
||||
|
||||
Update the video library for a specific tv show if passed, otherwise update the whole library if option enabled.
|
||||
|
@ -323,12 +395,7 @@ class KodiNotifier:
|
|||
% (json.dumps(response['error']), host, json.dumps(command)), logger.ERROR)
|
||||
return result
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
def cb_response(self, r, *args, **kwargs):
|
||||
self.response = dict(status_code=r.status_code)
|
||||
return r
|
||||
|
||||
def _update_library_json(self, host=None, show_name=None):
|
||||
def _update_json(self, host=None, show_name=None):
|
||||
""" Handle updating Kodi host via HTTP JSON-RPC
|
||||
|
||||
Update the video library for a specific tv show if passed, otherwise update the whole library if option enabled.
|
||||
|
@ -410,99 +477,49 @@ class KodiNotifier:
|
|||
|
||||
return True
|
||||
|
||||
def _maybe_log_failed_detection(self, host):
|
||||
|
||||
self._maybe_log(u'Failed to detect version for %s, check configuration.' % host)
|
||||
|
||||
def _maybe_log(self, msg, log_level=None):
|
||||
|
||||
if msg and (sickbeard.KODI_ALWAYS_ON or self.test_mode):
|
||||
self._log(msg + (not sickbeard.KODI_ALWAYS_ON and self.test_mode and ' (Test mode always logs)' or ''),
|
||||
log_level)
|
||||
|
||||
@staticmethod
|
||||
def _log(msg, log_level=logger.WARNING):
|
||||
|
||||
logger.log(u'Kodi: %s' % msg, log_level)
|
||||
|
||||
##############################################################################
|
||||
# Public functions which will call the JSON or Legacy HTTP API methods
|
||||
##############################################################################
|
||||
|
||||
def notify_snatch(self, ep_name):
|
||||
|
||||
if sickbeard.KODI_NOTIFY_ONSNATCH:
|
||||
self._notify_kodi(ep_name, common.notifyStrings[common.NOTIFY_SNATCH])
|
||||
|
||||
def notify_download(self, ep_name):
|
||||
|
||||
if sickbeard.KODI_NOTIFY_ONDOWNLOAD:
|
||||
self._notify_kodi(ep_name, common.notifyStrings[common.NOTIFY_DOWNLOAD])
|
||||
|
||||
def notify_subtitle_download(self, ep_name, lang):
|
||||
|
||||
if sickbeard.KODI_NOTIFY_ONSUBTITLEDOWNLOAD:
|
||||
self._notify_kodi('%s: %s' % (ep_name, lang), common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD])
|
||||
|
||||
def notify_git_update(self, new_version='??'):
|
||||
|
||||
if sickbeard.USE_KODI:
|
||||
update_text = common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]
|
||||
title = common.notifyStrings[common.NOTIFY_GIT_UPDATE]
|
||||
self._notify_kodi('%s %s' % (update_text, new_version), title)
|
||||
|
||||
def test_notify(self, host, username, password):
|
||||
self.test_mode, self.username, self.password = True, username, password
|
||||
return self._notify_kodi('Testing SickGear Kodi notifier', 'Test Notification', kodi_hosts=host)
|
||||
|
||||
def update_library(self, showName=None):
|
||||
self.test_mode, self.username, self.password = True, username, password
|
||||
result = self._notify_kodi('Testing SickGear Kodi notifier', 'Test Notification', kodi_hosts=host)
|
||||
self.test_mode = False
|
||||
return result
|
||||
|
||||
def update_library(self, showName=None, force=False):
|
||||
""" Wrapper for the update library functions
|
||||
|
||||
Call either the JSON-RPC over HTTP or the legacy HTTP API methods depending on the Kodi API version.
|
||||
:param showName: Name of a TV show
|
||||
:param force: True force update process
|
||||
|
||||
Uses a list of comma delimited hosts where only one is updated, the first to respond with success. This is a
|
||||
workaround for SQL backend users because updating multiple clients causes duplicate entries.
|
||||
|
||||
Future plan is to revisit how host/ip/username/pw/options are stored so that this may become more flexible.
|
||||
|
||||
Args:
|
||||
showName: Name of a TV show to target for a library update
|
||||
|
||||
Returns:
|
||||
True or False
|
||||
Returns: None if no processing done, True if processing succeeded with no issues else False if any issues found
|
||||
"""
|
||||
|
||||
if sickbeard.USE_KODI and sickbeard.KODI_UPDATE_LIBRARY:
|
||||
if not sickbeard.KODI_HOST:
|
||||
self._log(u'No Kodi hosts specified, check your settings', logger.DEBUG)
|
||||
return False
|
||||
|
||||
# either update each host, or only attempt to update until one successful result
|
||||
result = 0
|
||||
only_first = dict(show='', first='', first_note='')
|
||||
showName and only_first.update(show=' for show;"%s"' % showName)
|
||||
sickbeard.KODI_UPDATE_ONLYFIRST and only_first.update(dict(
|
||||
first=' first', first_note=' in line with the "Only update first host"%s' % ' setting'))
|
||||
|
||||
for cur_host in [x.strip() for x in sickbeard.KODI_HOST.split(',')]:
|
||||
|
||||
response = self._send_to_kodi_json(cur_host, dict(method='Profiles.GetCurrentProfile'))
|
||||
if self.response and 401 == self.response.get('status_code'):
|
||||
self._log(u'Failed to authenticate with %s' % cur_host, logger.DEBUG)
|
||||
continue
|
||||
if not response:
|
||||
self._maybe_log_failed_detection(cur_host)
|
||||
continue
|
||||
|
||||
if self._send_update_library(cur_host, showName):
|
||||
only_first.update(dict(profile=response.get('label') or 'Master', host=cur_host))
|
||||
self._log('Success: profile;' +
|
||||
u'"%(profile)s" at%(first)s host;%(host)s updated%(show)s%(first_note)s' % only_first)
|
||||
else:
|
||||
self._maybe_log_failed_detection(cur_host)
|
||||
result += 1
|
||||
|
||||
if sickbeard.KODI_UPDATE_ONLYFIRST:
|
||||
return True
|
||||
|
||||
# needed for the 'update kodi' submenu command as it only cares of the final result vs the individual ones
|
||||
return 0 == result
|
||||
if sickbeard.USE_KODI and (sickbeard.KODI_UPDATE_LIBRARY or force):
|
||||
return self._update_library(showName)
|
||||
|
||||
|
||||
notifier = KodiNotifier
|
||||
|
|
|
@ -1035,12 +1035,15 @@ class PostProcessor(object):
|
|||
# send notifications
|
||||
notifiers.notify_download(ep_obj._format_pattern('%SN - %Sx%0E - %EN - %QN'))
|
||||
|
||||
# do the library update for XBMC
|
||||
notifiers.xbmc_notifier.update_library(ep_obj.show.name)
|
||||
# do the library update for Emby
|
||||
notifiers.emby_notifier.update_library(ep_obj.show)
|
||||
|
||||
# do the library update for Kodi
|
||||
notifiers.kodi_notifier.update_library(ep_obj.show.name)
|
||||
|
||||
# do the library update for XBMC
|
||||
notifiers.xbmc_notifier.update_library(ep_obj.show.name)
|
||||
|
||||
# do the library update for Plex
|
||||
notifiers.plex_notifier.update_library(ep_obj)
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ def search_propers():
|
|||
|
||||
logger.log(u'Beginning search for new propers')
|
||||
|
||||
age_shows, age_anime = 2, 14
|
||||
age_shows, age_anime = sickbeard.BACKLOG_DAYS + 2, 14
|
||||
aired_since_shows = datetime.datetime.today() - datetime.timedelta(days=age_shows)
|
||||
aired_since_anime = datetime.datetime.today() - datetime.timedelta(days=age_anime)
|
||||
recent_shows, recent_anime = _recent_history(aired_since_shows, aired_since_anime)
|
||||
|
@ -100,7 +100,7 @@ def _get_proper_list(aired_since_shows, recent_shows, recent_anime):
|
|||
name = _generic_name(x.name)
|
||||
if name not in propers:
|
||||
try:
|
||||
parse_result = np.parse(x.title)
|
||||
parse_result = np.parse(x.name)
|
||||
if parse_result.series_name and parse_result.episode_numbers and \
|
||||
parse_result.show.indexerid in recent_shows + recent_anime:
|
||||
logger.log(u'Found new proper: ' + x.name, logger.DEBUG)
|
||||
|
|
|
@ -599,7 +599,6 @@ class NZBProvider(object, GenericProvider):
|
|||
|
||||
index = 0
|
||||
alt_search = ('nzbs_org' == self.get_id())
|
||||
term_items_found = False
|
||||
do_search_alt = False
|
||||
|
||||
search_terms = []
|
||||
|
@ -614,21 +613,16 @@ class NZBProvider(object, GenericProvider):
|
|||
regex += [terms]
|
||||
proper_check = re.compile(r'(?i)(%s)' % '|'.join(regex))
|
||||
|
||||
urls = []
|
||||
while index < len(search_terms):
|
||||
search_params = {'q': search_terms[index], 'maxage': 4}
|
||||
search_params = {'q': search_terms[index], 'maxage': sickbeard.BACKLOG_DAYS + 2}
|
||||
if alt_search:
|
||||
|
||||
if do_search_alt:
|
||||
search_params['t'] = 'search'
|
||||
index += 1
|
||||
|
||||
if term_items_found:
|
||||
do_search_alt = True
|
||||
term_items_found = False
|
||||
else:
|
||||
if do_search_alt:
|
||||
search_params['t'] = 'search'
|
||||
|
||||
do_search_alt = (True, False)[do_search_alt]
|
||||
do_search_alt = not do_search_alt
|
||||
|
||||
else:
|
||||
index += 1
|
||||
|
@ -637,8 +631,9 @@ class NZBProvider(object, GenericProvider):
|
|||
|
||||
(title, url) = self._title_and_url(item)
|
||||
|
||||
if not proper_check.search(title):
|
||||
if not proper_check.search(title) or url in urls:
|
||||
continue
|
||||
urls.append(url)
|
||||
|
||||
if 'published_parsed' in item and item['published_parsed']:
|
||||
result_date = item.published_parsed
|
||||
|
@ -651,10 +646,8 @@ class NZBProvider(object, GenericProvider):
|
|||
if not search_date or search_date < result_date:
|
||||
search_result = classes.Proper(title, url, result_date, self.show)
|
||||
results.append(search_result)
|
||||
term_items_found = True
|
||||
do_search_alt = False
|
||||
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.5)
|
||||
|
||||
return results
|
||||
|
||||
|
|
|
@ -533,20 +533,25 @@ class Home(MainHandler):
|
|||
return [
|
||||
{'title': 'Add Shows', 'path': 'home/addShows/', },
|
||||
{'title': 'Manual Post-Processing', 'path': 'home/postprocess/'},
|
||||
{'title': 'Update XBMC', 'path': 'home/updateXBMC/', 'requires': self.haveXBMC},
|
||||
{'title': 'Update Emby', 'path': 'home/updateEMBY/', 'requires': self.haveEMBY},
|
||||
{'title': 'Update Kodi', 'path': 'home/updateKODI/', 'requires': self.haveKODI},
|
||||
{'title': 'Update XBMC', 'path': 'home/updateXBMC/', 'requires': self.haveXBMC},
|
||||
{'title': 'Update Plex', 'path': 'home/updatePLEX/', 'requires': self.havePLEX},
|
||||
{'title': 'Restart', 'path': 'home/restart/?pid=' + str(sickbeard.PID), 'confirm': True},
|
||||
{'title': 'Shutdown', 'path': 'home/shutdown/?pid=' + str(sickbeard.PID), 'confirm': True},
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def haveXBMC():
|
||||
return sickbeard.USE_XBMC and sickbeard.XBMC_UPDATE_LIBRARY
|
||||
def haveEMBY():
|
||||
return sickbeard.USE_EMBY
|
||||
|
||||
@staticmethod
|
||||
def haveKODI():
|
||||
return sickbeard.USE_KODI and sickbeard.KODI_UPDATE_LIBRARY
|
||||
return sickbeard.USE_KODI
|
||||
|
||||
@staticmethod
|
||||
def haveXBMC():
|
||||
return sickbeard.USE_XBMC and sickbeard.XBMC_UPDATE_LIBRARY
|
||||
|
||||
@staticmethod
|
||||
def havePLEX():
|
||||
|
@ -771,6 +776,29 @@ class Home(MainHandler):
|
|||
else:
|
||||
return 'Error sending tweet'
|
||||
|
||||
def testEMBY(self, host=None, apikey=None):
|
||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||
|
||||
hosts = config.clean_hosts(host)
|
||||
if not hosts:
|
||||
return 'Fail: At least one invalid host'
|
||||
|
||||
total_success, cur_message = notifiers.emby_notifier.test_notify(hosts, apikey)
|
||||
return (cur_message, u'Success. All Emby hosts tested.')[total_success]
|
||||
|
||||
def testKODI(self, host=None, username=None, password=None):
|
||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||
|
||||
hosts = config.clean_hosts(host)
|
||||
if not hosts:
|
||||
return 'Fail: At least one invalid host'
|
||||
|
||||
if None is not password and set('*') == set(password):
|
||||
password = sickbeard.KODI_PASSWORD
|
||||
|
||||
total_success, cur_message = notifiers.kodi_notifier.test_notify(hosts, username, password)
|
||||
return (cur_message, u'Success. All Kodi hosts tested.')[total_success]
|
||||
|
||||
def testXBMC(self, host=None, username=None, password=None):
|
||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||
|
||||
|
@ -789,19 +817,6 @@ class Home(MainHandler):
|
|||
|
||||
return finalResult
|
||||
|
||||
def testKODI(self, host=None, username=None, password=None):
|
||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||
|
||||
hosts = config.clean_hosts(host)
|
||||
if not hosts:
|
||||
return 'Fail: At least one invalid host'
|
||||
|
||||
if None is not password and set('*') == set(password):
|
||||
password = sickbeard.KODI_PASSWORD
|
||||
|
||||
total_success, cur_message = notifiers.kodi_notifier.test_notify(hosts, username, password)
|
||||
return (cur_message, u'Success. All Kodi hosts tested.')[total_success]
|
||||
|
||||
def testPMC(self, host=None, username=None, password=None):
|
||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||
|
||||
|
@ -1184,12 +1199,16 @@ class Home(MainHandler):
|
|||
t.submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid})
|
||||
t.submenu.append(
|
||||
{'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1&web=1' % showObj.indexerid})
|
||||
t.submenu.append({'title': 'Update show in XBMC',
|
||||
'path': 'home/updateXBMC?showName=%s' % urllib.quote_plus(
|
||||
showObj.name.encode('utf-8')), 'requires': self.haveXBMC})
|
||||
t.submenu.append({'title': 'Update show in Emby',
|
||||
'path': 'home/updateEMBY%s' %
|
||||
(INDEXER_TVDB == showObj.indexer and ('?show=%s' % showObj.indexerid) or '/'),
|
||||
'requires': self.haveEMBY})
|
||||
t.submenu.append({'title': 'Update show in Kodi',
|
||||
'path': 'home/updateKODI?showName=%s' % urllib.quote_plus(
|
||||
showObj.name.encode('utf-8')), 'requires': self.haveKODI})
|
||||
t.submenu.append({'title': 'Update show in XBMC',
|
||||
'path': 'home/updateXBMC?showName=%s' % urllib.quote_plus(
|
||||
showObj.name.encode('utf-8')), 'requires': self.haveXBMC})
|
||||
t.submenu.append({'title': 'Media Renamer', 'path': 'home/testRename?show=%d' % showObj.indexerid})
|
||||
if sickbeard.USE_SUBTITLES and not sickbeard.showQueueScheduler.action.isBeingSubtitled(
|
||||
showObj) and showObj.subtitles:
|
||||
|
@ -1617,6 +1636,30 @@ class Home(MainHandler):
|
|||
|
||||
self.redirect('/home/displayShow?show=' + str(showObj.indexerid))
|
||||
|
||||
def updateEMBY(self, show=None):
|
||||
|
||||
if notifiers.emby_notifier.update_library(
|
||||
sickbeard.helpers.findCertainShow(sickbeard.showList,helpers.tryInt(show, None)), force=True):
|
||||
ui.notifications.message('Library update command sent to Emby host(s): ' + sickbeard.EMBY_HOST)
|
||||
else:
|
||||
ui.notifications.error('Unable to contact one or more Emby host(s): ' + sickbeard.EMBY_HOST)
|
||||
self.redirect('/home/')
|
||||
|
||||
def updateKODI(self, showName=None):
|
||||
|
||||
# only send update to first host in the list -- workaround for kodi sql backend users
|
||||
if sickbeard.KODI_UPDATE_ONLYFIRST:
|
||||
# only send update to first host in the list -- workaround for kodi sql backend users
|
||||
host = sickbeard.KODI_HOST.split(',')[0].strip()
|
||||
else:
|
||||
host = sickbeard.KODI_HOST
|
||||
|
||||
if notifiers.kodi_notifier.update_library(showName=showName, force=True):
|
||||
ui.notifications.message('Library update command sent to Kodi host(s): ' + host)
|
||||
else:
|
||||
ui.notifications.error('Unable to contact one or more Kodi host(s): ' + host)
|
||||
self.redirect('/home/')
|
||||
|
||||
def updateXBMC(self, showName=None):
|
||||
|
||||
# only send update to first host in the list -- workaround for xbmc sql backend users
|
||||
|
@ -1632,21 +1675,6 @@ class Home(MainHandler):
|
|||
ui.notifications.error('Unable to contact one or more XBMC host(s): ' + host)
|
||||
self.redirect('/home/')
|
||||
|
||||
def updateKODI(self, showName=None):
|
||||
|
||||
# only send update to first host in the list -- workaround for kodi sql backend users
|
||||
if sickbeard.KODI_UPDATE_ONLYFIRST:
|
||||
# only send update to first host in the list -- workaround for kodi sql backend users
|
||||
host = sickbeard.KODI_HOST.split(',')[0].strip()
|
||||
else:
|
||||
host = sickbeard.KODI_HOST
|
||||
|
||||
if notifiers.kodi_notifier.update_library(showName=showName):
|
||||
ui.notifications.message('Library update command sent to Kodi host(s): ' + host)
|
||||
else:
|
||||
ui.notifications.error('Unable to contact one or more Kodi host(s): ' + host)
|
||||
self.redirect('/home/')
|
||||
|
||||
def updatePLEX(self, *args, **kwargs):
|
||||
result = notifiers.plex_notifier.update_library()
|
||||
if None is result:
|
||||
|
@ -4873,14 +4901,16 @@ class ConfigNotifications(Config):
|
|||
'b64': base64.urlsafe_b64encode(location)})
|
||||
return t.respond()
|
||||
|
||||
def saveNotifications(self, use_xbmc=None, xbmc_always_on=None, xbmc_notify_onsnatch=None,
|
||||
xbmc_notify_ondownload=None,
|
||||
xbmc_notify_onsubtitledownload=None, xbmc_update_onlyfirst=None,
|
||||
xbmc_update_library=None, xbmc_update_full=None, xbmc_host=None, xbmc_username=None,
|
||||
xbmc_password=None,
|
||||
def saveNotifications(self,
|
||||
use_emby=None, emby_update_library=None, emby_host=None, emby_apikey=None,
|
||||
use_kodi=None, kodi_always_on=None, kodi_notify_onsnatch=None, kodi_notify_ondownload=None,
|
||||
kodi_notify_onsubtitledownload=None, kodi_update_onlyfirst=None, kodi_update_library=None,
|
||||
kodi_update_full=None, kodi_host=None, kodi_username=None, kodi_password=None,
|
||||
kodi_notify_onsubtitledownload=None, kodi_update_onlyfirst=None,
|
||||
kodi_update_library=None, kodi_update_full=None,
|
||||
kodi_host=None, kodi_username=None, kodi_password=None,
|
||||
use_xbmc=None, xbmc_always_on=None, xbmc_notify_onsnatch=None, xbmc_notify_ondownload=None,
|
||||
xbmc_notify_onsubtitledownload=None, xbmc_update_onlyfirst=None,
|
||||
xbmc_update_library=None, xbmc_update_full=None,
|
||||
xbmc_host=None, xbmc_username=None, xbmc_password=None,
|
||||
use_plex=None, plex_notify_onsnatch=None, plex_notify_ondownload=None,
|
||||
plex_notify_onsubtitledownload=None, plex_update_library=None,
|
||||
plex_server_host=None, plex_host=None, plex_username=None, plex_password=None,
|
||||
|
@ -4922,18 +4952,24 @@ class ConfigNotifications(Config):
|
|||
|
||||
results = []
|
||||
|
||||
sickbeard.USE_XBMC = config.checkbox_to_value(use_xbmc)
|
||||
sickbeard.XBMC_ALWAYS_ON = config.checkbox_to_value(xbmc_always_on)
|
||||
sickbeard.XBMC_NOTIFY_ONSNATCH = config.checkbox_to_value(xbmc_notify_onsnatch)
|
||||
sickbeard.XBMC_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(xbmc_notify_ondownload)
|
||||
sickbeard.XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(xbmc_notify_onsubtitledownload)
|
||||
sickbeard.XBMC_UPDATE_LIBRARY = config.checkbox_to_value(xbmc_update_library)
|
||||
sickbeard.XBMC_UPDATE_FULL = config.checkbox_to_value(xbmc_update_full)
|
||||
sickbeard.XBMC_UPDATE_ONLYFIRST = config.checkbox_to_value(xbmc_update_onlyfirst)
|
||||
sickbeard.XBMC_HOST = config.clean_hosts(xbmc_host)
|
||||
sickbeard.XBMC_USERNAME = xbmc_username
|
||||
if set('*') != set(xbmc_password):
|
||||
sickbeard.XBMC_PASSWORD = xbmc_password
|
||||
sickbeard.USE_EMBY = config.checkbox_to_value(use_emby)
|
||||
sickbeard.EMBY_UPDATE_LIBRARY = config.checkbox_to_value(emby_update_library)
|
||||
sickbeard.EMBY_HOST = config.clean_hosts(emby_host)
|
||||
keys_changed = False
|
||||
all_keys = []
|
||||
old_keys = [x.strip() for x in sickbeard.EMBY_APIKEY.split(',') if x.strip()]
|
||||
new_keys = [x.strip() for x in emby_apikey.split(',') if x.strip()]
|
||||
for key in new_keys:
|
||||
if not starify(key, True):
|
||||
keys_changed = True
|
||||
all_keys += [key]
|
||||
continue
|
||||
for x in old_keys:
|
||||
if key.startswith(x[0:3]) and key.endswith(x[-4:]):
|
||||
all_keys += [x]
|
||||
break
|
||||
if keys_changed or (len(all_keys) != len(old_keys)):
|
||||
sickbeard.EMBY_APIKEY = ','.join(all_keys)
|
||||
|
||||
sickbeard.USE_KODI = config.checkbox_to_value(use_kodi)
|
||||
sickbeard.KODI_ALWAYS_ON = config.checkbox_to_value(kodi_always_on)
|
||||
|
@ -4948,6 +4984,19 @@ class ConfigNotifications(Config):
|
|||
if set('*') != set(kodi_password):
|
||||
sickbeard.KODI_PASSWORD = kodi_password
|
||||
|
||||
sickbeard.USE_XBMC = config.checkbox_to_value(use_xbmc)
|
||||
sickbeard.XBMC_ALWAYS_ON = config.checkbox_to_value(xbmc_always_on)
|
||||
sickbeard.XBMC_NOTIFY_ONSNATCH = config.checkbox_to_value(xbmc_notify_onsnatch)
|
||||
sickbeard.XBMC_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(xbmc_notify_ondownload)
|
||||
sickbeard.XBMC_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(xbmc_notify_onsubtitledownload)
|
||||
sickbeard.XBMC_UPDATE_LIBRARY = config.checkbox_to_value(xbmc_update_library)
|
||||
sickbeard.XBMC_UPDATE_FULL = config.checkbox_to_value(xbmc_update_full)
|
||||
sickbeard.XBMC_UPDATE_ONLYFIRST = config.checkbox_to_value(xbmc_update_onlyfirst)
|
||||
sickbeard.XBMC_HOST = config.clean_hosts(xbmc_host)
|
||||
sickbeard.XBMC_USERNAME = xbmc_username
|
||||
if set('*') != set(xbmc_password):
|
||||
sickbeard.XBMC_PASSWORD = xbmc_password
|
||||
|
||||
sickbeard.USE_PLEX = config.checkbox_to_value(use_plex)
|
||||
sickbeard.PLEX_NOTIFY_ONSNATCH = config.checkbox_to_value(plex_notify_onsnatch)
|
||||
sickbeard.PLEX_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(plex_notify_ondownload)
|
||||
|
|
Loading…
Reference in a new issue