Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
Cleanup Notifiers code. Pull #832
  * Safeguard notifiers from affecting the post-processing routine,
    catch and log exceptions.
  * Added notification support for Synology (notifies Synology DSM)
    and migrate settings
    If you are having problems getting this to work
    reference: http://forum.synology.com/enu/viewtopic.php?f=27&t=55627
  * Cleaned up logging entries, trying to standardize on what level we report
    and verbiage (not using contractions, prune out duplicate/excessive entries)

Cleanup release names and release group for releases,
also fix the re-scan process from overwriting existing stored release_name
so that we keep the original cleaned up release in tact.
  * Remove non-release group from release group such as RP and NZBGEEK
  * Remove known media extensions .avi, .mkv, .mp4, etc and download extensions
    like .nzb, .torrent from release name

Change detection non seasons packs

Change Roman numerals conversion (PR-589)

Change our scheduled tasks to use delay start instead of just kicking off
immediately to let SB finish it's start-up routines.
Also silent logging until the actual routine is ran,
prevent erroneous logging when we were just checking to see if it was time
to actually start the scheduled task.

  * We delay the currentSearch (rss) by 5 mins
  * We delay the autoPostProcesser by 5 mins
  * We delay the backlogSearch (limited/full) by 17 mins
  * We delay the properFinder/showUpdate by 1 cycle (1hr)

This overall should help let slower NAS systems finish updating
/ spin up drives / establish network connectivity before SB starts its logic.
  • Loading branch information
Patrick Vos committed May 25, 2014
2 parents 3349eff + f1eabba commit 0e81fe9
Show file tree
Hide file tree
Showing 27 changed files with 519 additions and 390 deletions.
48 changes: 36 additions & 12 deletions data/interfaces/default/config_notifications.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


<br />
<h2>Home Theater</h2>
<h2>Home Theater / NAS</h2>
<br />


Expand Down Expand Up @@ -366,17 +366,18 @@

<div class="component-group clearfix">
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/synoindex.png" alt="" title="Synology Indexer" />
<h3><a href="http://synology.com/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Synology Indexer</a></h3>
<img class="notifier-icon" src="$sbRoot/images/notifiers/synoindex.png" alt="" title="Synology" />
<h3><a href="http://synology.com/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Synology</a></h3>
<p>The Synology DiskStation NAS.</p>
<p>Synology Indexer is the daemon running on the Synology NAS to build its media database.</p>
<p>Synology Notifier is the notification system of Synology DSM.</p>
</div>

<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" class="enabler" name="use_synoindex" id="use_synoindex" #if $sickbeard.USE_SYNOINDEX then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_synoindex">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send notifications to the synoindex daemon?<br /><br />
<span class="component-desc">Should Sick Beard send Synology commands?<br /><br />
</span>
</label>
<label class="nocheck clearfix" for="use_synoindex">
Expand All @@ -386,8 +387,31 @@
</div>

<div id="content_use_synoindex">
<div class="field-pair">
<input type="checkbox" name="synoindex_notify_onsnatch" id="synoindex_notify_onsnatch" #if $sickbeard.SYNOINDEX_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
<label class="clearfix" for="synoindex_notify_onsnatch">
<span class="component-title">Notify on Snatch</span>
<span class="component-desc">Send notification when we start a download?</span>
</label>
</div>
<div class="field-pair">
<input type="checkbox" name="synoindex_notify_ondownload" id="synoindex_notify_ondownload" #if $sickbeard.SYNOINDEX_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
<label class="clearfix" for="synoindex_notify_ondownload">
<span class="component-title">Notify on Download</span>
<span class="component-desc">Send notification when we finish a download?</span>
</label>
</div>
<div class="field-pair">
<input type="checkbox" name="synoindex_update_library" id="synoindex_update_library" #if $sickbeard.SYNOINDEX_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
<label class="clearfix" for="synoindex_update_library">
<span class="component-title">Update Library</span>
<span class="component-desc">Update Synology library when we finish a download?</span>
</label>
</div>
<div class="testNotification" id="testSynoNotify-result">Click below to test.</div>
<input type="button" class="btn" value="Test Notice (SynoDSMnotify)" id="testSynoNotify" />
<input type="submit" class="btn config_submitter" value="Save Changes" />
</div><!-- /content_use_pytivo //-->
</div><!-- /content_use_synoindex //-->

</fieldset>
</div><!-- /synoindex component-group //-->
Expand All @@ -397,14 +421,14 @@
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/pytivo.png" alt="" title="pyTivo" />
<h3><a href="http://pytivo.sourceforge.net/wiki/index.php/PyTivo" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">pyTivo</a></h3>
<p>pyTivo is both an HMO and GoBack server. This notifier will load the completed downloads to your Tivo.</p>
<p>pyTivo is both an HMO and GoBack server. This notifier will load the completed downloads to your Tivo.</p>
</div>
<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" class="enabler" name="use_pytivo" id="use_pytivo" #if $sickbeard.USE_PYTIVO then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_pytivo">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send notifications to pyTivo?<br /><br /></span>
<span class="component-desc">Should Sick Beard update commands to pyTivo?<br /><br /></span>
</label>
<label class="nocheck clearfix" for="use_pytivo">
<span class="component-title">&nbsp;</span>
Expand Down Expand Up @@ -637,7 +661,7 @@
<input type="checkbox" class="enabler" name="use_pushover" id="use_pushover" #if $sickbeard.USE_PUSHOVER then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_pushover">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send notifications through Pushover?</span>
<span class="component-desc">Should Sick Beard send Pushover notifications?</span>
</label>
</div>

Expand Down Expand Up @@ -678,14 +702,14 @@
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/boxcar.png" alt="" title="Boxcar" />
<h3><a href="http://boxcar.io/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Boxcar</a></h3>
<p>Read your messages where and when you want them! A subscription will be sent if needed.</p>
<p>Universal push notification for iOS. Read your messages where and when you want them! A subscription will be sent if needed.</p>
</div>
<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" class="enabler" name="use_boxcar" id="use_boxcar" #if $sickbeard.USE_BOXCAR then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_boxcar">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send notifications through Boxcar?</span>
<span class="component-desc">Should Sick Beard send Boxcar notifications?</span>
</label>
</div>

Expand Down Expand Up @@ -792,7 +816,7 @@
</div><br />

<br />
<h2>Online</h2>
<h2>Social</h2>
<br />


Expand Down
11 changes: 11 additions & 0 deletions data/js/configNotifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,15 @@ $(document).ready(function () {
$("#testNMA").attr("disabled", false);
});
});

$("#testSynoNotify").click(function () {
$(this).attr("disabled", true);
$("#testSynoNotify-result").html(loading);
$.get(sbRoot + "/home/testSynoNotify")
.done(function (data) {
$("#testSynoNotify-result").html(data);
$("#testSynoNotify").attr("disabled", false);
});
});

});
97 changes: 59 additions & 38 deletions sickbeard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
CONFIG_FILE = None

# this is the version of the config we EXPECT to find
CONFIG_VERSION = 5
CONFIG_VERSION = 6

PROG_DIR = '.'
MY_FULLNAME = None
Expand Down Expand Up @@ -267,6 +267,9 @@
NMJ_MOUNT = None

USE_SYNOINDEX = False
SYNOINDEX_NOTIFY_ONSNATCH = False
SYNOINDEX_NOTIFY_ONDOWNLOAD = False
SYNOINDEX_UPDATE_LIBRARY = False

USE_NMJv2 = False
NMJv2_HOST = None
Expand Down Expand Up @@ -341,7 +344,8 @@ def initialize(consoleLogging=True):
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \
USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, \
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, USE_SYNOINDEX, \
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, \
USE_SYNOINDEX, SYNOINDEX_NOTIFY_ONSNATCH, SYNOINDEX_NOTIFY_ONDOWNLOAD, SYNOINDEX_UPDATE_LIBRARY, \
USE_LISTVIEW, METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_MEDE8ER, METADATA_PS3, metadata_provider_dict, \
GIT_PATH, MOVE_ASSOCIATED_FILES, \
COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, METADATA_WDTV, METADATA_TIVO, IGNORE_WORDS, CREATE_MISSING_SHOW_DIRS, \
Expand Down Expand Up @@ -602,6 +606,9 @@ def initialize(consoleLogging=True):

CheckSection(CFG, 'Synology')
USE_SYNOINDEX = bool(check_setting_int(CFG, 'Synology', 'use_synoindex', 0))
SYNOINDEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Synology', 'synoindex_notify_onsnatch', 0))
SYNOINDEX_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Synology', 'synoindex_notify_ondownload', 0))
SYNOINDEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Synology', 'synoindex_update_library', 0))

CheckSection(CFG, 'Trakt')
USE_TRAKT = bool(check_setting_int(CFG, 'Trakt', 'use_trakt', 0))
Expand Down Expand Up @@ -665,55 +672,66 @@ def initialize(consoleLogging=True):
newznabProviderList = providers.getNewznabProviderList(NEWZNAB_DATA)
providerList = providers.makeProviderList()

# initialize schedulars
currentSearchScheduler = scheduler.Scheduler(searchCurrent.CurrentSearcher(),
cycleTime=datetime.timedelta(minutes=SEARCH_FREQUENCY),
threadName="SEARCH",
runImmediately=True)

# the interval for this is stored inside the ShowUpdater class
showUpdaterInstance = showUpdater.ShowUpdater()
showUpdateScheduler = scheduler.Scheduler(showUpdaterInstance,
cycleTime=showUpdaterInstance.updateInterval,
threadName="SHOWUPDATER",
runImmediately=False)
# initialize schedulers

# updaters
versionCheckScheduler = scheduler.Scheduler(versionChecker.CheckVersion(),
cycleTime=datetime.timedelta(hours=12),
threadName="CHECKVERSION",
runImmediately=True)
cycleTime=datetime.timedelta(hours=12),
threadName="CHECKVERSION"
)

showQueueScheduler = scheduler.Scheduler(show_queue.ShowQueue(),
cycleTime=datetime.timedelta(seconds=3),
threadName="SHOWQUEUE",
silent=True)
cycleTime=datetime.timedelta(seconds=3),
threadName="SHOWQUEUE",
silent=True)

searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(),
cycleTime=datetime.timedelta(seconds=3),
threadName="SEARCHQUEUE",
silent=True)
showUpdaterInstance = showUpdater.ShowUpdater() # the interval for this is stored inside the class
showUpdateScheduler = scheduler.Scheduler(showUpdaterInstance,
cycleTime=showUpdaterInstance.updateInterval,
threadName="SHOWUPDATER",
run_delay=showUpdaterInstance.updateInterval,
silent=True
)

properFinderInstance = properFinder.ProperFinder()
properFinderScheduler = scheduler.Scheduler(properFinderInstance,
cycleTime=properFinderInstance.updateInterval,
threadName="FINDPROPERS",
runImmediately=False)
if not DOWNLOAD_PROPERS:
properFinderScheduler.silent = True
# searchers
searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(),
cycleTime=datetime.timedelta(seconds=3),
threadName="SEARCHQUEUE",
silent=True
)

autoPostProcesserScheduler = scheduler.Scheduler(autoPostProcesser.PostProcesser(),
cycleTime=datetime.timedelta(minutes=10),
threadName="POSTPROCESSER",
runImmediately=True)
if not PROCESS_AUTOMATICALLY:
autoPostProcesserScheduler.silent = True
currentSearchScheduler = scheduler.Scheduler(searchCurrent.CurrentSearcher(),
cycleTime=datetime.timedelta(minutes=SEARCH_FREQUENCY),
threadName="SEARCH",
run_delay=datetime.timedelta(minutes=5)
)

backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(),
cycleTime=datetime.timedelta(minutes=get_backlog_cycle_time()),
threadName="BACKLOG",
runImmediately=True)
run_delay=datetime.timedelta(minutes=17)
)

backlogSearchScheduler.action.cycleTime = BACKLOG_SEARCH_FREQUENCY

properFinderInstance = properFinder.ProperFinder() # the interval for this is stored inside the class
properFinderScheduler = scheduler.Scheduler(properFinderInstance,
cycleTime=properFinderInstance.updateInterval,
threadName="FINDPROPERS",
run_delay=properFinderInstance.updateInterval,
silent=True
)

# processors
autoPostProcesserScheduler = scheduler.Scheduler(autoPostProcesser.PostProcesser(),
cycleTime=datetime.timedelta(minutes=10),
threadName="POSTPROCESSER",
run_delay=datetime.timedelta(minutes=5)
)

if not PROCESS_AUTOMATICALLY:
autoPostProcesserScheduler.silent = True

showList = []
loadingShowList = {}

Expand Down Expand Up @@ -1114,6 +1132,9 @@ def save_config():

new_config['Synology'] = {}
new_config['Synology']['use_synoindex'] = int(USE_SYNOINDEX)
new_config['Synology']['synoindex_notify_onsnatch'] = int(SYNOINDEX_NOTIFY_ONSNATCH)
new_config['Synology']['synoindex_notify_ondownload'] = int(SYNOINDEX_NOTIFY_ONDOWNLOAD)
new_config['Synology']['synoindex_update_library'] = int(SYNOINDEX_UPDATE_LIBRARY)

new_config['NMJv2'] = {}
new_config['NMJv2']['use_nmjv2'] = int(USE_NMJv2)
Expand Down
7 changes: 7 additions & 0 deletions sickbeard/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,10 @@ def _migrate_metadata(metadata, metadata_name, use_banner):
sickbeard.METADATA_WDTV = _migrate_metadata(metadata_wdtv, 'WDTV', use_banner)
sickbeard.METADATA_TIVO = _migrate_metadata(metadata_tivo, 'TIVO', use_banner)
sickbeard.METADATA_MEDE8ER = _migrate_metadata(metadata_mede8er, 'Mede8er', use_banner)

# Migration v6: Synology notifier update
def _migrate_v6(self):
""" Updates Synology notifier to reflect that their now is an update library option instead misusing the enable option """

# clone use_synoindex to update_library since this now has notification options
sickbeard.SYNOINDEX_UPDATE_LIBRARY = bool(check_setting_int(self.config_obj, 'Synology', 'use_synoindex', 0))
27 changes: 27 additions & 0 deletions sickbeard/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from sickbeard.exceptions import MultipleShowObjectsException, ex
from sickbeard import logger, classes
from sickbeard.common import USER_AGENT, mediaExtensions, XML_NSMAP
from sickbeard.common import mediaExtensions

from sickbeard import db
from sickbeard import encodingKludge as ek
Expand Down Expand Up @@ -82,6 +83,32 @@ def indentXML(elem, level=0):
elem.tail = i


def remove_extension(name):
"""
Remove download or media extension from name (if any)
"""

if name and "." in name:
base_name, sep, extension = name.rpartition('.') # @UnusedVariable
if base_name and extension.lower() in ['nzb', 'torrent'] + mediaExtensions:
name = base_name

return name


def remove_non_release_groups(name):
"""
Remove non release groups from name
"""

if name and "-" in name:
name_group = name.rsplit('-', 1)
if name_group[-1].upper() in ["RP", "NZBGEEK"]:
name = name_group[0]

return name


def replaceExtension(filename, newExt):
'''
>>> replaceExtension('foo.avi', 'mkv')
Expand Down
Loading

0 comments on commit 0e81fe9

Please sign in to comment.