Skip to content

Commit 0e81fe9

Browse files
author
Patrick Vos
committed
Merge branch 'development'
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.
2 parents 3349eff + f1eabba commit 0e81fe9

27 files changed

+519
-390
lines changed

data/interfaces/default/config_notifications.tmpl

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
<br />
20-
<h2>Home Theater</h2>
20+
<h2>Home Theater / NAS</h2>
2121
<br />
2222

2323

@@ -366,17 +366,18 @@
366366

367367
<div class="component-group clearfix">
368368
<div class="component-group-desc">
369-
<img class="notifier-icon" src="$sbRoot/images/notifiers/synoindex.png" alt="" title="Synology Indexer" />
370-
<h3><a href="http://synology.com/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Synology Indexer</a></h3>
369+
<img class="notifier-icon" src="$sbRoot/images/notifiers/synoindex.png" alt="" title="Synology" />
370+
<h3><a href="http://synology.com/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Synology</a></h3>
371+
<p>The Synology DiskStation NAS.</p>
371372
<p>Synology Indexer is the daemon running on the Synology NAS to build its media database.</p>
373+
<p>Synology Notifier is the notification system of Synology DSM.</p>
372374
</div>
373-
374375
<fieldset class="component-group-list">
375376
<div class="field-pair">
376377
<input type="checkbox" class="enabler" name="use_synoindex" id="use_synoindex" #if $sickbeard.USE_SYNOINDEX then "checked=\"checked\"" else ""# />
377378
<label class="clearfix" for="use_synoindex">
378379
<span class="component-title">Enable</span>
379-
<span class="component-desc">Should Sick Beard send notifications to the synoindex daemon?<br /><br />
380+
<span class="component-desc">Should Sick Beard send Synology commands?<br /><br />
380381
</span>
381382
</label>
382383
<label class="nocheck clearfix" for="use_synoindex">
@@ -386,8 +387,31 @@
386387
</div>
387388

388389
<div id="content_use_synoindex">
390+
<div class="field-pair">
391+
<input type="checkbox" name="synoindex_notify_onsnatch" id="synoindex_notify_onsnatch" #if $sickbeard.SYNOINDEX_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
392+
<label class="clearfix" for="synoindex_notify_onsnatch">
393+
<span class="component-title">Notify on Snatch</span>
394+
<span class="component-desc">Send notification when we start a download?</span>
395+
</label>
396+
</div>
397+
<div class="field-pair">
398+
<input type="checkbox" name="synoindex_notify_ondownload" id="synoindex_notify_ondownload" #if $sickbeard.SYNOINDEX_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
399+
<label class="clearfix" for="synoindex_notify_ondownload">
400+
<span class="component-title">Notify on Download</span>
401+
<span class="component-desc">Send notification when we finish a download?</span>
402+
</label>
403+
</div>
404+
<div class="field-pair">
405+
<input type="checkbox" name="synoindex_update_library" id="synoindex_update_library" #if $sickbeard.SYNOINDEX_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
406+
<label class="clearfix" for="synoindex_update_library">
407+
<span class="component-title">Update Library</span>
408+
<span class="component-desc">Update Synology library when we finish a download?</span>
409+
</label>
410+
</div>
411+
<div class="testNotification" id="testSynoNotify-result">Click below to test.</div>
412+
<input type="button" class="btn" value="Test Notice (SynoDSMnotify)" id="testSynoNotify" />
389413
<input type="submit" class="btn config_submitter" value="Save Changes" />
390-
</div><!-- /content_use_pytivo //-->
414+
</div><!-- /content_use_synoindex //-->
391415

392416
</fieldset>
393417
</div><!-- /synoindex component-group //-->
@@ -397,14 +421,14 @@
397421
<div class="component-group-desc">
398422
<img class="notifier-icon" src="$sbRoot/images/notifiers/pytivo.png" alt="" title="pyTivo" />
399423
<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>
400-
<p>pyTivo is both an HMO and GoBack server. This notifier will load the completed downloads to your Tivo.</p>
424+
<p>pyTivo is both an HMO and GoBack server. This notifier will load the completed downloads to your Tivo.</p>
401425
</div>
402426
<fieldset class="component-group-list">
403427
<div class="field-pair">
404428
<input type="checkbox" class="enabler" name="use_pytivo" id="use_pytivo" #if $sickbeard.USE_PYTIVO then "checked=\"checked\"" else ""# />
405429
<label class="clearfix" for="use_pytivo">
406430
<span class="component-title">Enable</span>
407-
<span class="component-desc">Should Sick Beard send notifications to pyTivo?<br /><br /></span>
431+
<span class="component-desc">Should Sick Beard update commands to pyTivo?<br /><br /></span>
408432
</label>
409433
<label class="nocheck clearfix" for="use_pytivo">
410434
<span class="component-title">&nbsp;</span>
@@ -637,7 +661,7 @@
637661
<input type="checkbox" class="enabler" name="use_pushover" id="use_pushover" #if $sickbeard.USE_PUSHOVER then "checked=\"checked\"" else ""# />
638662
<label class="clearfix" for="use_pushover">
639663
<span class="component-title">Enable</span>
640-
<span class="component-desc">Should Sick Beard send notifications through Pushover?</span>
664+
<span class="component-desc">Should Sick Beard send Pushover notifications?</span>
641665
</label>
642666
</div>
643667

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

@@ -792,7 +816,7 @@
792816
</div><br />
793817

794818
<br />
795-
<h2>Online</h2>
819+
<h2>Social</h2>
796820
<br />
797821

798822

data/js/configNotifications.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,15 @@ $(document).ready(function () {
257257
$("#testNMA").attr("disabled", false);
258258
});
259259
});
260+
261+
$("#testSynoNotify").click(function () {
262+
$(this).attr("disabled", true);
263+
$("#testSynoNotify-result").html(loading);
264+
$.get(sbRoot + "/home/testSynoNotify")
265+
.done(function (data) {
266+
$("#testSynoNotify-result").html(data);
267+
$("#testSynoNotify").attr("disabled", false);
268+
});
269+
});
270+
260271
});

sickbeard/__init__.py

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
CONFIG_FILE = None
5959

6060
# this is the version of the config we EXPECT to find
61-
CONFIG_VERSION = 5
61+
CONFIG_VERSION = 6
6262

6363
PROG_DIR = '.'
6464
MY_FULLNAME = None
@@ -267,6 +267,9 @@
267267
NMJ_MOUNT = None
268268

269269
USE_SYNOINDEX = False
270+
SYNOINDEX_NOTIFY_ONSNATCH = False
271+
SYNOINDEX_NOTIFY_ONDOWNLOAD = False
272+
SYNOINDEX_UPDATE_LIBRARY = False
270273

271274
USE_NMJv2 = False
272275
NMJv2_HOST = None
@@ -341,7 +344,8 @@ def initialize(consoleLogging=True):
341344
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \
342345
USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
343346
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, \
344-
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, \
347+
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, \
348+
USE_SYNOINDEX, SYNOINDEX_NOTIFY_ONSNATCH, SYNOINDEX_NOTIFY_ONDOWNLOAD, SYNOINDEX_UPDATE_LIBRARY, \
345349
USE_LISTVIEW, METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_MEDE8ER, METADATA_PS3, metadata_provider_dict, \
346350
GIT_PATH, MOVE_ASSOCIATED_FILES, \
347351
COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, METADATA_WDTV, METADATA_TIVO, IGNORE_WORDS, CREATE_MISSING_SHOW_DIRS, \
@@ -602,6 +606,9 @@ def initialize(consoleLogging=True):
602606

603607
CheckSection(CFG, 'Synology')
604608
USE_SYNOINDEX = bool(check_setting_int(CFG, 'Synology', 'use_synoindex', 0))
609+
SYNOINDEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Synology', 'synoindex_notify_onsnatch', 0))
610+
SYNOINDEX_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Synology', 'synoindex_notify_ondownload', 0))
611+
SYNOINDEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Synology', 'synoindex_update_library', 0))
605612

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

668-
# initialize schedulars
669-
currentSearchScheduler = scheduler.Scheduler(searchCurrent.CurrentSearcher(),
670-
cycleTime=datetime.timedelta(minutes=SEARCH_FREQUENCY),
671-
threadName="SEARCH",
672-
runImmediately=True)
673-
674-
# the interval for this is stored inside the ShowUpdater class
675-
showUpdaterInstance = showUpdater.ShowUpdater()
676-
showUpdateScheduler = scheduler.Scheduler(showUpdaterInstance,
677-
cycleTime=showUpdaterInstance.updateInterval,
678-
threadName="SHOWUPDATER",
679-
runImmediately=False)
675+
# initialize schedulers
680676

677+
# updaters
681678
versionCheckScheduler = scheduler.Scheduler(versionChecker.CheckVersion(),
682-
cycleTime=datetime.timedelta(hours=12),
683-
threadName="CHECKVERSION",
684-
runImmediately=True)
679+
cycleTime=datetime.timedelta(hours=12),
680+
threadName="CHECKVERSION"
681+
)
685682

686683
showQueueScheduler = scheduler.Scheduler(show_queue.ShowQueue(),
687-
cycleTime=datetime.timedelta(seconds=3),
688-
threadName="SHOWQUEUE",
689-
silent=True)
684+
cycleTime=datetime.timedelta(seconds=3),
685+
threadName="SHOWQUEUE",
686+
silent=True)
690687

691-
searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(),
692-
cycleTime=datetime.timedelta(seconds=3),
693-
threadName="SEARCHQUEUE",
694-
silent=True)
688+
showUpdaterInstance = showUpdater.ShowUpdater() # the interval for this is stored inside the class
689+
showUpdateScheduler = scheduler.Scheduler(showUpdaterInstance,
690+
cycleTime=showUpdaterInstance.updateInterval,
691+
threadName="SHOWUPDATER",
692+
run_delay=showUpdaterInstance.updateInterval,
693+
silent=True
694+
)
695695

696-
properFinderInstance = properFinder.ProperFinder()
697-
properFinderScheduler = scheduler.Scheduler(properFinderInstance,
698-
cycleTime=properFinderInstance.updateInterval,
699-
threadName="FINDPROPERS",
700-
runImmediately=False)
701-
if not DOWNLOAD_PROPERS:
702-
properFinderScheduler.silent = True
696+
# searchers
697+
searchQueueScheduler = scheduler.Scheduler(search_queue.SearchQueue(),
698+
cycleTime=datetime.timedelta(seconds=3),
699+
threadName="SEARCHQUEUE",
700+
silent=True
701+
)
703702

704-
autoPostProcesserScheduler = scheduler.Scheduler(autoPostProcesser.PostProcesser(),
705-
cycleTime=datetime.timedelta(minutes=10),
706-
threadName="POSTPROCESSER",
707-
runImmediately=True)
708-
if not PROCESS_AUTOMATICALLY:
709-
autoPostProcesserScheduler.silent = True
703+
currentSearchScheduler = scheduler.Scheduler(searchCurrent.CurrentSearcher(),
704+
cycleTime=datetime.timedelta(minutes=SEARCH_FREQUENCY),
705+
threadName="SEARCH",
706+
run_delay=datetime.timedelta(minutes=5)
707+
)
710708

711709
backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(),
712710
cycleTime=datetime.timedelta(minutes=get_backlog_cycle_time()),
713711
threadName="BACKLOG",
714-
runImmediately=True)
712+
run_delay=datetime.timedelta(minutes=17)
713+
)
714+
715715
backlogSearchScheduler.action.cycleTime = BACKLOG_SEARCH_FREQUENCY
716716

717+
properFinderInstance = properFinder.ProperFinder() # the interval for this is stored inside the class
718+
properFinderScheduler = scheduler.Scheduler(properFinderInstance,
719+
cycleTime=properFinderInstance.updateInterval,
720+
threadName="FINDPROPERS",
721+
run_delay=properFinderInstance.updateInterval,
722+
silent=True
723+
)
724+
725+
# processors
726+
autoPostProcesserScheduler = scheduler.Scheduler(autoPostProcesser.PostProcesser(),
727+
cycleTime=datetime.timedelta(minutes=10),
728+
threadName="POSTPROCESSER",
729+
run_delay=datetime.timedelta(minutes=5)
730+
)
731+
732+
if not PROCESS_AUTOMATICALLY:
733+
autoPostProcesserScheduler.silent = True
734+
717735
showList = []
718736
loadingShowList = {}
719737

@@ -1114,6 +1132,9 @@ def save_config():
11141132

11151133
new_config['Synology'] = {}
11161134
new_config['Synology']['use_synoindex'] = int(USE_SYNOINDEX)
1135+
new_config['Synology']['synoindex_notify_onsnatch'] = int(SYNOINDEX_NOTIFY_ONSNATCH)
1136+
new_config['Synology']['synoindex_notify_ondownload'] = int(SYNOINDEX_NOTIFY_ONDOWNLOAD)
1137+
new_config['Synology']['synoindex_update_library'] = int(SYNOINDEX_UPDATE_LIBRARY)
11171138

11181139
new_config['NMJv2'] = {}
11191140
new_config['NMJv2']['use_nmjv2'] = int(USE_NMJv2)

sickbeard/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,10 @@ def _migrate_metadata(metadata, metadata_name, use_banner):
645645
sickbeard.METADATA_WDTV = _migrate_metadata(metadata_wdtv, 'WDTV', use_banner)
646646
sickbeard.METADATA_TIVO = _migrate_metadata(metadata_tivo, 'TIVO', use_banner)
647647
sickbeard.METADATA_MEDE8ER = _migrate_metadata(metadata_mede8er, 'Mede8er', use_banner)
648+
649+
# Migration v6: Synology notifier update
650+
def _migrate_v6(self):
651+
""" Updates Synology notifier to reflect that their now is an update library option instead misusing the enable option """
652+
653+
# clone use_synoindex to update_library since this now has notification options
654+
sickbeard.SYNOINDEX_UPDATE_LIBRARY = bool(check_setting_int(self.config_obj, 'Synology', 'use_synoindex', 0))

sickbeard/helpers.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
from sickbeard.exceptions import MultipleShowObjectsException, ex
5151
from sickbeard import logger, classes
5252
from sickbeard.common import USER_AGENT, mediaExtensions, XML_NSMAP
53+
from sickbeard.common import mediaExtensions
5354

5455
from sickbeard import db
5556
from sickbeard import encodingKludge as ek
@@ -82,6 +83,32 @@ def indentXML(elem, level=0):
8283
elem.tail = i
8384

8485

86+
def remove_extension(name):
87+
"""
88+
Remove download or media extension from name (if any)
89+
"""
90+
91+
if name and "." in name:
92+
base_name, sep, extension = name.rpartition('.') # @UnusedVariable
93+
if base_name and extension.lower() in ['nzb', 'torrent'] + mediaExtensions:
94+
name = base_name
95+
96+
return name
97+
98+
99+
def remove_non_release_groups(name):
100+
"""
101+
Remove non release groups from name
102+
"""
103+
104+
if name and "-" in name:
105+
name_group = name.rsplit('-', 1)
106+
if name_group[-1].upper() in ["RP", "NZBGEEK"]:
107+
name = name_group[0]
108+
109+
return name
110+
111+
85112
def replaceExtension(filename, newExt):
86113
'''
87114
>>> replaceExtension('foo.avi', 'mkv')

0 commit comments

Comments
 (0)