Fix for newznab provider settings not saving properly

Added new show option, delete now removes show from showlist and deletes from hard drive, remove will just remove show from showlist but leave files on hard drive untouched
This commit is contained in:
echel0n 2014-08-29 03:29:56 -07:00
parent ea66c2c41b
commit 3cb1c573a3
6 changed files with 83 additions and 26 deletions

View file

@ -193,14 +193,14 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
#end if #end if
#if $hasattr($curNewznabProvider, 'search_mode'): #if $hasattr($curNewznabProvider, 'search_mode'):
<div class="field-pair">
<label class="nocheck clearfix"> <label class="nocheck clearfix">
<span class="component-title">Season Search Mode</span> <span class="component-title">Season Search Mode</span>
<span class="component-desc"> <span class="component-desc">
<div class="field-pair">
When searching for complete seasons<br> When searching for complete seasons<br>
you can choose to have it look for season<br> you can choose to have it look for season<br>
packs ONLY or choose to have it build a<br> packs ONLY or choose to have it build a<br>
complete season from just single episodes.</span> complete season from just single episodes.<br></span>
<span class="component-title"></span> <span class="component-title"></span>
<input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_sponly" value="sponly" class="radio" #if $curNewznabProvider.search_mode=="sponly" then "checked=\"checked\"" else ""# />Season Packs ONLY!<br /> <input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_sponly" value="sponly" class="radio" #if $curNewznabProvider.search_mode=="sponly" then "checked=\"checked\"" else ""# />Season Packs ONLY!<br />

View file

@ -147,6 +147,7 @@ a > i.icon-question-sign { background-image: url("$sbRoot/images/glyphicons-half
\$("#SubMenu a[href*='/home/logout/']").addClass('btn').html('<span class="ui-icon ui-icon-power pull-left"></span> Logout'); \$("#SubMenu a[href*='/home/logout/']").addClass('btn').html('<span class="ui-icon ui-icon-power pull-left"></span> Logout');
\$("#SubMenu a:contains('Edit')").addClass('btn').html('<span class="ui-icon ui-icon-pencil pull-left"></span> Edit'); \$("#SubMenu a:contains('Edit')").addClass('btn').html('<span class="ui-icon ui-icon-pencil pull-left"></span> Edit');
\$("#SubMenu a:contains('Delete')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Delete'); \$("#SubMenu a:contains('Delete')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Delete');
\$("#SubMenu a:contains('Remove')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Remove');
\$("#SubMenu a:contains('Clear History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History'); \$("#SubMenu a:contains('Clear History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
\$("#SubMenu a:contains('Trim History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History'); \$("#SubMenu a:contains('Trim History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors'); \$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');

View file

@ -22,6 +22,7 @@ import string
from tornado.httputil import HTTPHeaders from tornado.httputil import HTTPHeaders
from tornado.web import RequestHandler from tornado.web import RequestHandler
from sickbeard import encodingKludge as ek from sickbeard import encodingKludge as ek
from sickbeard import logger
# use the built-in if it's available (python 2.6), if not use the included library # use the built-in if it's available (python 2.6), if not use the included library
try: try:
@ -80,7 +81,12 @@ def foldersAtPath(path, includeParent=False, includeFiles=False):
if path == parentPath and os.name == 'nt': if path == parentPath and os.name == 'nt':
parentPath = "" parentPath = ""
try:
fileList = [{'name': filename, 'path': ek.ek(os.path.join, path, filename)} for filename in ek.ek(os.listdir, path)] fileList = [{'name': filename, 'path': ek.ek(os.path.join, path, filename)} for filename in ek.ek(os.listdir, path)]
except OSError, e:
logger.log(u"Unable to open " + path + ": " + repr(e) + " / " + str(e), logger.WARNING)
fileList = [{'name': filename, 'path': ek.ek(os.path.join, parentPath, filename)} for filename in ek.ek(os.listdir, parentPath)]
if not includeFiles: if not includeFiles:
fileList = filter(lambda entry: ek.ek(os.path.isdir, entry['path']), fileList) fileList = filter(lambda entry: ek.ek(os.path.isdir, entry['path']), fileList)

View file

@ -23,6 +23,7 @@ import datetime
import threading import threading
import re import re
import glob import glob
import stat
import traceback import traceback
import sickbeard import sickbeard
@ -962,7 +963,7 @@ class TVShow(object):
return self.nextaired return self.nextaired
def deleteShow(self): def deleteShow(self, full=False):
sql_l = [["DELETE FROM tv_episodes WHERE showid = ?", [self.indexerid]], sql_l = [["DELETE FROM tv_episodes WHERE showid = ?", [self.indexerid]],
["DELETE FROM tv_shows WHERE indexer_id = ?", [self.indexerid]], ["DELETE FROM tv_shows WHERE indexer_id = ?", [self.indexerid]],
@ -973,7 +974,6 @@ class TVShow(object):
myDB = db.DBConnection() myDB = db.DBConnection()
myDB.mass_action(sql_l) myDB.mass_action(sql_l)
# remove self from show list # remove self from show list
sickbeard.showList = [x for x in sickbeard.showList if int(x.indexerid) != self.indexerid] sickbeard.showList = [x for x in sickbeard.showList if int(x.indexerid) != self.indexerid]
@ -983,6 +983,24 @@ class TVShow(object):
logger.log(u"Deleting cache file " + cache_file) logger.log(u"Deleting cache file " + cache_file)
os.remove(cache_file) os.remove(cache_file)
# remove entire show folder
if full:
try:
logger.log(u"Deleting show folder " + self.location)
# check first the read-only attribute
file_attribute = ek.ek(os.stat, self.location)[0]
if (not file_attribute & stat.S_IWRITE):
# File is read-only, so make it writeable
logger.log('Read only mode on folder ' + self.location + ' Will try to make it writeable', logger.DEBUG)
try:
ek.ek(os.chmod, self.location, stat.S_IWRITE)
except:
logger.log(u'Cannot change permissions of ' + self.location, logger.WARNING)
ek.ek(os.rmdir, self.location)
except OSError, e:
logger.log(u"Unable to delete " + self.location + ": " + repr(e) + " / " + str(e), logger.WARNING)
def populateCache(self): def populateCache(self):
cache_inst = image_cache.ImageCache() cache_inst = image_cache.ImageCache()

View file

@ -1036,8 +1036,10 @@ class Manage(MainHandler):
return _munge(t) return _munge(t)
def massEditSubmit(self, paused=None, anime=None, sports=None, scene=None, flatten_folders=None, quality_preset=False, def massEditSubmit(self, paused=None, anime=None, sports=None, scene=None, flatten_folders=None,
subtitles=None, air_by_date=None, anyQualities=[], bestQualities=[], toEdit=None, *args, **kwargs): quality_preset=False,
subtitles=None, air_by_date=None, anyQualities=[], bestQualities=[], toEdit=None, *args,
**kwargs):
dir_map = {} dir_map = {}
for cur_arg in kwargs: for cur_arg in kwargs:
@ -1112,7 +1114,8 @@ class Manage(MainHandler):
exceptions_list = [] exceptions_list = []
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list, curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities,
bestQualities, exceptions_list,
flatten_folders=new_flatten_folders, flatten_folders=new_flatten_folders,
paused=new_paused, sports=new_sports, paused=new_paused, sports=new_sports,
subtitles=new_subtitles, anime=new_anime, subtitles=new_subtitles, anime=new_anime,
@ -1601,7 +1604,8 @@ class ConfigSearch(MainHandler):
def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None, def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None,
sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None, sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None,
nzbget_category=None, nzbget_priority=100, nzbget_host=None, nzbget_use_https=None, dailysearch_frequency=None, nzbget_category=None, nzbget_priority=100, nzbget_host=None, nzbget_use_https=None,
dailysearch_frequency=None,
nzb_method=None, torrent_method=None, usenet_retention=None, backlog_frequency=None, nzb_method=None, torrent_method=None, usenet_retention=None, backlog_frequency=None,
download_propers=None, check_propers_interval=None, allow_high_priority=None, download_propers=None, check_propers_interval=None, allow_high_priority=None,
backlog_startup=None, dailysearch_startup=None, backlog_startup=None, dailysearch_startup=None,
@ -1992,19 +1996,42 @@ class ConfigProviders(MainHandler):
cur_url = config.clean_url(cur_url) cur_url = config.clean_url(cur_url)
newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key) newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
cur_id = newProvider.getID() cur_id = newProvider.getID()
# if it already exists then update it # if it already exists then update it
if cur_id in newznabProviderDict: if cur_id in newznabProviderDict:
newznabProviderDict[cur_id].name = cur_name newznabProviderDict[cur_id].name = cur_name
newznabProviderDict[cur_id].url = cur_url newznabProviderDict[cur_id].url = cur_url
newznabProviderDict[cur_id].key = cur_key newznabProviderDict[cur_id].key = cur_key
# a 0 in the key spot indicates that no key is needed # a 0 in the key spot indicates that no key is needed
if cur_key == '0': if cur_key == '0':
newznabProviderDict[cur_id].needs_auth = False newznabProviderDict[cur_id].needs_auth = False
else: else:
newznabProviderDict[cur_id].needs_auth = True newznabProviderDict[cur_id].needs_auth = True
try:
newznabProviderDict[cur_id].search_mode = str(kwargs[cur_id + '_search_mode']).strip()
except:
pass
try:
newznabProviderDict[cur_id].search_fallback = config.checkbox_to_value(
kwargs[cur_id + '_search_fallback'])
except:
pass
try:
newznabProviderDict[cur_id].enable_daily = config.checkbox_to_value(
kwargs[cur_id + '_enable_daily'])
except:
pass
try:
newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(
kwargs[cur_id + '_enable_backlog'])
except:
pass
else: else:
sickbeard.newznabProviderList.append(newProvider) sickbeard.newznabProviderList.append(newProvider)
@ -2166,14 +2193,14 @@ class ConfigProviders(MainHandler):
curTorrentProvider.enable_daily = config.checkbox_to_value( curTorrentProvider.enable_daily = config.checkbox_to_value(
kwargs[curTorrentProvider.getID() + '_enable_daily']) kwargs[curTorrentProvider.getID() + '_enable_daily'])
except: except:
curTorrentProvider.enable_daily = 0 curTorrentProvider.enable_daily = 1
if hasattr(curTorrentProvider, 'enable_backlog'): if hasattr(curTorrentProvider, 'enable_backlog'):
try: try:
curTorrentProvider.enable_backlog = config.checkbox_to_value( curTorrentProvider.enable_backlog = config.checkbox_to_value(
kwargs[curTorrentProvider.getID() + '_enable_backlog']) kwargs[curTorrentProvider.getID() + '_enable_backlog'])
except: except:
curTorrentProvider.enable_backlog = 0 curTorrentProvider.enable_backlog = 1
for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if
curProvider.providerType == sickbeard.GenericProvider.NZB]: curProvider.providerType == sickbeard.GenericProvider.NZB]:
@ -2208,14 +2235,14 @@ class ConfigProviders(MainHandler):
curNzbProvider.enable_daily = config.checkbox_to_value( curNzbProvider.enable_daily = config.checkbox_to_value(
kwargs[curNzbProvider.getID() + '_enable_daily']) kwargs[curNzbProvider.getID() + '_enable_daily'])
except: except:
curNzbProvider.enable_daily = 0 curNzbProvider.enable_daily = 1
if hasattr(curNzbProvider, 'enable_backlog'): if hasattr(curNzbProvider, 'enable_backlog'):
try: try:
curNzbProvider.enable_backlog = config.checkbox_to_value( curNzbProvider.enable_backlog = config.checkbox_to_value(
kwargs[curNzbProvider.getID() + '_enable_backlog']) kwargs[curNzbProvider.getID() + '_enable_backlog'])
except: except:
curNzbProvider.enable_backlog = 0 curNzbProvider.enable_backlog = 1
sickbeard.NEWZNAB_DATA = '!!!'.join([x.configStr() for x in sickbeard.newznabProviderList]) sickbeard.NEWZNAB_DATA = '!!!'.join([x.configStr() for x in sickbeard.newznabProviderList])
sickbeard.PROVIDER_ORDER = provider_list sickbeard.PROVIDER_ORDER = provider_list
@ -2810,7 +2837,8 @@ class NewHomeAddShows(MainHandler):
final_results = [] final_results = []
logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG) logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG)
recommendedlist = TraktCall("recommendations/shows.json/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD) recommendedlist = TraktCall("recommendations/shows.json/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME,
sickbeard.TRAKT_PASSWORD)
if recommendedlist == 'NULL': if recommendedlist == 'NULL':
logger.log(u"No shows found in your recommendedlist, aborting recommendedlist update", logger.DEBUG) logger.log(u"No shows found in your recommendedlist, aborting recommendedlist update", logger.DEBUG)
@ -2821,7 +2849,8 @@ class NewHomeAddShows(MainHandler):
return return
map(final_results.append, map(final_results.append,
([int(show['tvdb_id'] or 0) if sickbeard.TRAKT_DEFAULT_INDEXER == 1 else int(show['tvdb_id'] or 0), show['url'], show['title'], show['overview'], ([int(show['tvdb_id'] or 0) if sickbeard.TRAKT_DEFAULT_INDEXER == 1 else int(show['tvdb_id'] or 0),
show['url'], show['title'], show['overview'],
datetime.date.fromtimestamp(int(show['first_aired']) / 1000.0).strftime('%Y%m%d')] for show in datetime.date.fromtimestamp(int(show['first_aired']) / 1000.0).strftime('%Y%m%d')] for show in
recommendedlist if not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id'])))) recommendedlist if not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id']))))
@ -3577,7 +3606,10 @@ class Home(MainHandler):
if not sickbeard.showQueueScheduler.action.isBeingAdded(showObj): # @UndefinedVariable if not sickbeard.showQueueScheduler.action.isBeingAdded(showObj): # @UndefinedVariable
if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
t.submenu.append( t.submenu.append(
{'title': 'Delete', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'confirm': True}) {'title': 'Delete', 'path': 'home/deleteShow?show=%d&amp;full=1' % showObj.indexerid,
'confirm': True})
t.submenu.append(
{'title': 'Remove', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'confirm': True})
t.submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid}) t.submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid})
t.submenu.append( t.submenu.append(
{'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&amp;force=1' % showObj.indexerid}) {'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&amp;force=1' % showObj.indexerid})
@ -3909,7 +3941,7 @@ class Home(MainHandler):
redirect("/home/displayShow?show=" + show) redirect("/home/displayShow?show=" + show)
def deleteShow(self, show=None): def deleteShow(self, show=None, full=0):
if show is None: if show is None:
return self._genericMessage("Error", "Invalid show ID") return self._genericMessage("Error", "Invalid show ID")
@ -3927,7 +3959,7 @@ class Home(MainHandler):
# remove show from trakt.tv library # remove show from trakt.tv library
sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj) sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj)
showObj.deleteShow() showObj.deleteShow(bool(full))
ui.notifications.message('<b>%s</b> has been deleted' % showObj.name) ui.notifications.message('<b>%s</b> has been deleted' % showObj.name)
redirect("/home/") redirect("/home/")