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:
@@ -7,17 +7,20 @@ import os
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Downloader(Plugin):
|
||||
|
||||
type = []
|
||||
|
||||
def __init__(self):
|
||||
addEvent('download', self.download)
|
||||
addEvent('getdownloadfailed', self.getdownloadfailed)
|
||||
|
||||
def download(self, data = {}):
|
||||
pass
|
||||
|
||||
def getdownloadfailed(self, data = {}):
|
||||
pass
|
||||
|
||||
def createNzbName(self, data, 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.logger import CPLog
|
||||
import traceback
|
||||
import urllib2
|
||||
import json
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
@@ -61,3 +63,44 @@ class Sabnzbd(Downloader):
|
||||
else:
|
||||
log.error("Unknown error: " + result[:40])
|
||||
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.logger import CPLog
|
||||
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
|
||||
import os
|
||||
import re
|
||||
@@ -48,6 +48,8 @@ class Renamer(Plugin):
|
||||
log.info('Renamer is disabled to avoid infinite looping of the same error.')
|
||||
return
|
||||
|
||||
self.checkSnatchedStatusses()
|
||||
|
||||
# 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')):
|
||||
log.debug('"To" and "From" have to exist.')
|
||||
@@ -471,3 +473,45 @@ class Renamer(Plugin):
|
||||
os.rmdir(folder)
|
||||
except:
|
||||
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