Added failed download handling for sabnzbd.
It will check for failed downloads from the sabnzbd api and then set the failed release to ignore and try the search again.
This commit is contained in:
1 parent
897a7ea122
commit
6225ed92b1
3 files changed
+92
-2
No files matched your search
@@ -7,17 +7,20 @@ import os
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Downloader(Plugin):
|
class Downloader(Plugin):
|
||||||
|
|
||||||
type = []
|
type = []
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
addEvent('download', self.download)
|
addEvent('download', self.download)
|
||||||
|
addEvent('getdownloadfailed', self.getdownloadfailed)
|
||||||
|
|
||||||
def download(self, data = {}):
|
def download(self, data = {}):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def getdownloadfailed(self, data = {}):
|
||||||
|
pass
|
||||||
|
|
||||||
def createNzbName(self, data, movie):
|
def createNzbName(self, data, movie):
|
||||||
return '%s%s' % (toSafeString(data.get('name')), self.cpTag(movie))
|
return '%s%s' % (toSafeString(data.get('name')), self.cpTag(movie))
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from couchpotato.core.helpers.encoding import tryUrlencode
|
|||||||
from couchpotato.core.helpers.variable import cleanHost
|
from couchpotato.core.helpers.variable import cleanHost
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
import traceback
|
import traceback
|
||||||
|
import urllib2
|
||||||
|
import json
|
||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
@@ -61,3 +63,44 @@ class Sabnzbd(Downloader):
|
|||||||
else:
|
else:
|
||||||
log.error("Unknown error: " + result[:40])
|
log.error("Unknown error: " + result[:40])
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def getdownloadfailed(self, data = {}, movie = {}, manual = False):
|
||||||
|
if self.isDisabled(manual) or not self.isCorrectType(data.get('type')):
|
||||||
|
return
|
||||||
|
|
||||||
|
log.info('Checking download status of "%s" at SABnzbd.', data.get('name'))
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'apikey': self.conf('api_key'),
|
||||||
|
'mode': 'history',
|
||||||
|
'ouput': 'json'
|
||||||
|
}
|
||||||
|
url = cleanHost(self.conf('host')) + "api?" + tryUrlencode(params)
|
||||||
|
log.debug('Opening: %s', url)
|
||||||
|
history = json.load(urllib2.urlopen(url))
|
||||||
|
|
||||||
|
nzbname = self.createNzbName(data, movie)
|
||||||
|
|
||||||
|
# Go through history items
|
||||||
|
for slot in history['history']['slots']:
|
||||||
|
log.debug('Found %s in SabNZBd history, which has %s', (slot['name'], slot['status']))
|
||||||
|
if slot['name'] == nzbname and slot['status'] == 'Failed':
|
||||||
|
log.debug('%s failed downloading, deleting...', slot['name'])
|
||||||
|
|
||||||
|
# Delete failed download
|
||||||
|
params = {
|
||||||
|
'apikey': self.conf('api_key'),
|
||||||
|
'mode': 'history',
|
||||||
|
'name': 'delete',
|
||||||
|
'value' : slot['id']
|
||||||
|
}
|
||||||
|
url = cleanHost(self.conf('host')) + "api?" + tryUrlencode(params)
|
||||||
|
try:
|
||||||
|
data = self.urlopen(url, timeout = 60, show_error = False)
|
||||||
|
except:
|
||||||
|
log.error(traceback.format_exc())
|
||||||
|
|
||||||
|
# Return failed
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
@@ -6,7 +6,7 @@ from couchpotato.core.helpers.request import jsonified
|
|||||||
from couchpotato.core.helpers.variable import getExt, mergeDicts, getTitle
|
from couchpotato.core.helpers.variable import getExt, mergeDicts, getTitle
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
from couchpotato.core.plugins.base import Plugin
|
from couchpotato.core.plugins.base import Plugin
|
||||||
from couchpotato.core.settings.model import Library, File, Profile
|
from couchpotato.core.settings.model import Library, File, Profile, Release as Relea
|
||||||
from couchpotato.environment import Env
|
from couchpotato.environment import Env
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -48,6 +48,8 @@ class Renamer(Plugin):
|
|||||||
log.info('Renamer is disabled to avoid infinite looping of the same error.')
|
log.info('Renamer is disabled to avoid infinite looping of the same error.')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.checkSnatchedStatusses()
|
||||||
|
|
||||||
# Check to see if the "to" folder is inside the "from" folder.
|
# Check to see if the "to" folder is inside the "from" folder.
|
||||||
if not os.path.isdir(self.conf('from')) or not os.path.isdir(self.conf('to')):
|
if not os.path.isdir(self.conf('from')) or not os.path.isdir(self.conf('to')):
|
||||||
log.debug('"To" and "From" have to exist.')
|
log.debug('"To" and "From" have to exist.')
|
||||||
@@ -471,3 +473,45 @@ class Renamer(Plugin):
|
|||||||
os.rmdir(folder)
|
os.rmdir(folder)
|
||||||
except:
|
except:
|
||||||
log.error('Couldn\'t remove empty directory %s: %s', (folder, traceback.format_exc()))
|
log.error('Couldn\'t remove empty directory %s: %s', (folder, traceback.format_exc()))
|
||||||
|
|
||||||
|
def checkSnatchedStatusses(self):
|
||||||
|
snatched_status = fireEvent('status.get', 'snatched', single = True)
|
||||||
|
ignored_status = fireEvent('status.get', 'ignored', single = True)
|
||||||
|
|
||||||
|
db = get_session()
|
||||||
|
rels = db.query(Relea).filter_by(status_id = snatched_status.get('id'))
|
||||||
|
|
||||||
|
log.debug('Checking snatched releases... %s', 'ops')
|
||||||
|
|
||||||
|
for rel in rels:
|
||||||
|
log.debug('Checking snatched release: %s' , rel.movie.library.titles[0].title)
|
||||||
|
item = {}
|
||||||
|
for info in rel.info:
|
||||||
|
item[info.identifier] = info.value
|
||||||
|
|
||||||
|
log.debug('Checking status snatched release: %s' , item.get('name'))
|
||||||
|
|
||||||
|
mymovie = rel.movie.to_dict({
|
||||||
|
'profile': {'types': {'quality': {}}},
|
||||||
|
'releases': {'status': {}, 'quality': {}},
|
||||||
|
'library': {'titles': {}, 'files':{}},
|
||||||
|
'files': {}
|
||||||
|
})
|
||||||
|
|
||||||
|
log.debug('Checking status snatched release: %s' , mymovie['library'].get('identifier'))
|
||||||
|
|
||||||
|
# check status
|
||||||
|
downloadfailed = fireEvent('getdownloadfailed', data = item, movie = mymovie)
|
||||||
|
|
||||||
|
if downloadfailed:
|
||||||
|
log.debug('Download of %s failed', item['name'])
|
||||||
|
|
||||||
|
# if failed set status to ignored
|
||||||
|
rel.status_id = ignored_status.get('id')
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# search/download again
|
||||||
|
log.info('Download of %s failed, trying next release...', item['name'])
|
||||||
|
fireEvent('searcher.single', rel.movie)
|
||||||
|
|
||||||
|
return
|
||||||
Reference in new issue
Block a user