Browse Source

Code cleanup

pull/2133/head
Ruud 12 years ago
parent
commit
7fd14e0283
  1. 3
      couchpotato/__init__.py
  2. 2
      couchpotato/api.py
  3. 2
      couchpotato/core/_base/clientscript/main.py
  4. 5
      couchpotato/core/auth.py
  5. 8
      couchpotato/core/downloaders/base.py
  6. 2
      couchpotato/core/downloaders/blackhole/main.py
  7. 4
      couchpotato/core/downloaders/deluge/main.py
  8. 6
      couchpotato/core/downloaders/nzbget/main.py
  9. 4
      couchpotato/core/downloaders/nzbvortex/main.py
  10. 5
      couchpotato/core/downloaders/sabnzbd/main.py
  11. 10
      couchpotato/core/downloaders/synology/main.py
  12. 9
      couchpotato/core/downloaders/transmission/main.py
  13. 4
      couchpotato/core/downloaders/utorrent/main.py
  14. 4
      couchpotato/core/event.py
  15. 2
      couchpotato/core/helpers/encoding.py
  16. 2
      couchpotato/core/helpers/request.py
  17. 6
      couchpotato/core/helpers/rss.py
  18. 10
      couchpotato/core/helpers/variable.py
  19. 4
      couchpotato/core/loader.py
  20. 1
      couchpotato/core/media/__init__.py
  21. 1
      couchpotato/core/media/_base/searcher/__init__.py
  22. 20
      couchpotato/core/media/_base/searcher/base.py
  23. 5
      couchpotato/core/media/_base/searcher/main.py
  24. 22
      couchpotato/core/media/movie/_base/main.py
  25. 3
      couchpotato/core/media/movie/library/movie/main.py
  26. 1
      couchpotato/core/notifications/base.py
  27. 17
      couchpotato/core/notifications/nmj/main.py
  28. 5
      couchpotato/core/notifications/notifymyandroid/main.py
  29. 2
      couchpotato/core/notifications/plex/main.py
  30. 3
      couchpotato/core/notifications/synoindex/main.py
  31. 3
      couchpotato/core/notifications/twitter/main.py
  32. 18
      couchpotato/core/notifications/xbmc/main.py
  33. 4
      couchpotato/core/plugins/base.py
  34. 2
      couchpotato/core/plugins/browser/main.py
  35. 2
      couchpotato/core/plugins/dashboard/main.py
  36. 1
      couchpotato/core/plugins/log/main.py
  37. 4
      couchpotato/core/plugins/manage/main.py
  38. 2
      couchpotato/core/plugins/profile/main.py
  39. 2
      couchpotato/core/plugins/quality/main.py
  40. 5
      couchpotato/core/plugins/release/main.py
  41. 29
      couchpotato/core/plugins/renamer/main.py
  42. 23
      couchpotato/core/plugins/scanner/main.py
  43. 2
      couchpotato/core/plugins/score/main.py
  44. 8
      couchpotato/core/plugins/score/scores.py
  45. 2
      couchpotato/core/plugins/status/main.py
  46. 2
      couchpotato/core/plugins/subtitle/main.py
  47. 1
      couchpotato/core/plugins/suggestion/main.py
  48. 2
      couchpotato/core/providers/automation/imdb/main.py
  49. 2
      couchpotato/core/providers/info/omdbapi/main.py
  50. 12
      couchpotato/core/providers/info/themoviedb/main.py
  51. 7
      couchpotato/core/providers/metadata/base.py
  52. 6
      couchpotato/core/providers/nzb/binsearch/main.py
  53. 2
      couchpotato/core/providers/nzb/newznab/main.py
  54. 2
      couchpotato/core/providers/torrent/scenehd/main.py
  55. 8
      couchpotato/core/providers/torrent/thepiratebay/main.py
  56. 3
      couchpotato/core/providers/userscript/allocine/main.py
  57. 7
      couchpotato/core/settings/__init__.py
  58. 4
      couchpotato/environment.py
  59. 4
      couchpotato/runner.py

3
couchpotato/__init__.py

@ -4,9 +4,6 @@ from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.variable import md5 from couchpotato.core.helpers.variable import md5
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.environment import Env from couchpotato.environment import Env
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm.session import sessionmaker
from tornado import template from tornado import template
from tornado.web import RequestHandler from tornado.web import RequestHandler
import os import os

2
couchpotato/api.py

@ -104,7 +104,7 @@ class ApiHandler(RequestHandler):
if jsonp_callback: if jsonp_callback:
self.write(str(jsonp_callback) + '(' + json.dumps(result) + ')') self.write(str(jsonp_callback) + '(' + json.dumps(result) + ')')
elif isinstance(result, (tuple)) and result[0] == 'redirect': elif isinstance(result, tuple) and result[0] == 'redirect':
self.redirect(result[1]) self.redirect(result[1])
else: else:
self.write(result) self.write(result)

2
couchpotato/core/_base/clientscript/main.py

@ -111,7 +111,7 @@ class ClientScript(Plugin):
data = jsmin(f) data = jsmin(f)
else: else:
data = self.prefix(f) data = self.prefix(f)
data = cssmin(f) data = cssmin(data)
data = data.replace('../images/', '../static/images/') data = data.replace('../images/', '../static/images/')
data = data.replace('../fonts/', '../static/fonts/') data = data.replace('../fonts/', '../static/fonts/')
data = data.replace('../../static/', '../static/') # Replace inside plugins data = data.replace('../../static/', '../static/') # Replace inside plugins

5
couchpotato/core/auth.py

@ -10,10 +10,15 @@ def requires_auth(handler_class):
def wrap_execute(handler_execute): def wrap_execute(handler_execute):
def require_basic_auth(handler, kwargs): def require_basic_auth(handler, kwargs):
if Env.setting('username') and Env.setting('password'): if Env.setting('username') and Env.setting('password'):
auth_header = handler.request.headers.get('Authorization') auth_header = handler.request.headers.get('Authorization')
auth_decoded = base64.decodestring(auth_header[6:]) if auth_header else None auth_decoded = base64.decodestring(auth_header[6:]) if auth_header else None
username = ''
password = ''
if auth_decoded: if auth_decoded:
username, password = auth_decoded.split(':', 2) username, password = auth_decoded.split(':', 2)

8
couchpotato/core/downloaders/base.py

@ -119,7 +119,7 @@ class Downloader(Provider):
except: except:
log.debug('Torrent hash "%s" wasn\'t found on: %s', (torrent_hash, source)) log.debug('Torrent hash "%s" wasn\'t found on: %s', (torrent_hash, source))
log.error('Failed converting magnet url to torrent: %s', (torrent_hash)) log.error('Failed converting magnet url to torrent: %s', torrent_hash)
return False return False
def downloadReturnId(self, download_id): def downloadReturnId(self, download_id):
@ -128,7 +128,7 @@ class Downloader(Provider):
'id': download_id 'id': download_id
} }
def isDisabled(self, manual, data): def isDisabled(self, manual = False, data = {}):
return not self.isEnabled(manual, data) return not self.isEnabled(manual, data)
def _isEnabled(self, manual, data = {}): def _isEnabled(self, manual, data = {}):
@ -136,10 +136,10 @@ class Downloader(Provider):
return return
return True return True
def isEnabled(self, manual, data = {}): def isEnabled(self, manual = False, data = {}):
d_manual = self.conf('manual', default = False) d_manual = self.conf('manual', default = False)
return super(Downloader, self).isEnabled() and \ return super(Downloader, self).isEnabled() and \
((d_manual and manual) or (d_manual is False)) and \ (d_manual and manual or d_manual is False) and \
(not data or self.isCorrectProtocol(data.get('protocol'))) (not data or self.isCorrectProtocol(data.get('protocol')))
def _pause(self, item, pause = True): def _pause(self, item, pause = True):

2
couchpotato/core/downloaders/blackhole/main.py

@ -62,7 +62,7 @@ class Blackhole(Downloader):
else: else:
return ['nzb'] return ['nzb']
def isEnabled(self, manual, data = {}): def isEnabled(self, manual = False, data = {}):
for_protocol = ['both'] for_protocol = ['both']
if data and 'torrent' in data.get('protocol'): if data and 'torrent' in data.get('protocol'):
for_protocol.append('torrent') for_protocol.append('torrent')

4
couchpotato/core/downloaders/deluge/main.py

@ -54,7 +54,7 @@ class Deluge(Downloader):
if self.conf('completed_directory'): if self.conf('completed_directory'):
if os.path.isdir(self.conf('completed_directory')): if os.path.isdir(self.conf('completed_directory')):
options['move_completed'] = 1 options['move_completed'] = 1
options['move_completed_path'] = self.conf('completed_directory') options['move_completed_path'] = self.conf('completed_directory')
else: else:
log.error('Download directory from Deluge settings: %s doesn\'t exist', self.conf('directory')) log.error('Download directory from Deluge settings: %s doesn\'t exist', self.conf('directory'))
@ -96,7 +96,7 @@ class Deluge(Downloader):
queue = self.drpc.get_alltorrents() queue = self.drpc.get_alltorrents()
if not (queue): if not queue:
log.debug('Nothing in queue or error') log.debug('Nothing in queue or error')
return False return False

6
couchpotato/core/downloaders/nzbget/main.py

@ -172,11 +172,15 @@ class NZBGet(Downloader):
try: try:
history = rpc.history() history = rpc.history()
nzb_id = None
path = None
for hist in history: for hist in history:
if hist['Parameters'] and hist['Parameters']['couchpotato'] and hist['Parameters']['couchpotato'] == item['id']: if hist['Parameters'] and hist['Parameters']['couchpotato'] and hist['Parameters']['couchpotato'] == item['id']:
nzb_id = hist['ID'] nzb_id = hist['ID']
path = hist['DestDir'] path = hist['DestDir']
if rpc.editqueue('HistoryDelete', 0, "", [tryInt(nzb_id)]):
if nzb_id and path and rpc.editqueue('HistoryDelete', 0, "", [tryInt(nzb_id)]):
shutil.rmtree(path, True) shutil.rmtree(path, True)
except: except:
log.error('Failed deleting: %s', traceback.format_exc(0)) log.error('Failed deleting: %s', traceback.format_exc(0))

4
couchpotato/core/downloaders/nzbvortex/main.py

@ -122,7 +122,7 @@ class NZBVortex(Downloader):
# Try login and do again # Try login and do again
if not repeat: if not repeat:
self.login() self.login()
return self.call(call, parameters = parameters, repeat = True, *args, **kwargs) return self.call(call, parameters = parameters, repeat = True, **kwargs)
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc())) log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc()))
except: except:
@ -148,7 +148,7 @@ class NZBVortex(Downloader):
return self.api_level return self.api_level
def isEnabled(self, manual, data): def isEnabled(self, manual = False, data = {}):
return super(NZBVortex, self).isEnabled(manual, data) and self.getApiLevel() return super(NZBVortex, self).isEnabled(manual, data) and self.getApiLevel()

5
couchpotato/core/downloaders/sabnzbd/main.py

@ -26,9 +26,10 @@ class Sabnzbd(Downloader):
'priority': self.conf('priority'), 'priority': self.conf('priority'),
} }
nzb_filename = None
if filedata: if filedata:
if len(filedata) < 50: if len(filedata) < 50:
log.error('No proper nzb available: %s', (filedata)) log.error('No proper nzb available: %s', filedata)
return False return False
# If it's a .rar, it adds the .rar extension, otherwise it stays .nzb # If it's a .rar, it adds the .rar extension, otherwise it stays .nzb
@ -38,7 +39,7 @@ class Sabnzbd(Downloader):
req_params['name'] = data.get('url') req_params['name'] = data.get('url')
try: try:
if req_params.get('mode') is 'addfile': if nzb_filename and req_params.get('mode') is 'addfile':
sab_data = self.call(req_params, params = {'nzbfile': (ss(nzb_filename), filedata)}, multipart = True) sab_data = self.call(req_params, params = {'nzbfile': (ss(nzb_filename), filedata)}, multipart = True)
else: else:
sab_data = self.call(req_params) sab_data = self.call(req_params)

10
couchpotato/core/downloaders/synology/main.py

@ -49,7 +49,7 @@ class Synology(Downloader):
else: else:
return ['nzb'] return ['nzb']
def isEnabled(self, manual, data = {}): def isEnabled(self, manual = False, data = {}):
for_protocol = ['both'] for_protocol = ['both']
if data and 'torrent' in data.get('protocol'): if data and 'torrent' in data.get('protocol'):
for_protocol.append('torrent') for_protocol.append('torrent')
@ -61,7 +61,7 @@ class Synology(Downloader):
class SynologyRPC(object): class SynologyRPC(object):
'''SynologyRPC lite library''' """SynologyRPC lite library"""
def __init__(self, host = 'localhost', port = 5000, username = None, password = None): def __init__(self, host = 'localhost', port = 5000, username = None, password = None):
@ -98,7 +98,7 @@ class SynologyRPC(object):
req = requests.post(url, data = args, files = files) req = requests.post(url, data = args, files = files)
req.raise_for_status() req.raise_for_status()
response = json.loads(req.text) response = json.loads(req.text)
if response['success'] == True: if response['success']:
log.info('Synology action successfull') log.info('Synology action successfull')
return response return response
except requests.ConnectionError, err: except requests.ConnectionError, err:
@ -111,11 +111,11 @@ class SynologyRPC(object):
return response return response
def create_task(self, url = None, filename = None, filedata = None): def create_task(self, url = None, filename = None, filedata = None):
''' Creates new download task in Synology DownloadStation. Either specify """ Creates new download task in Synology DownloadStation. Either specify
url or pair (filename, filedata). url or pair (filename, filedata).
Returns True if task was created, False otherwise Returns True if task was created, False otherwise
''' """
result = False result = False
# login # login
if self._login(): if self._login():

9
couchpotato/core/downloaders/transmission/main.py

@ -44,8 +44,9 @@ class Transmission(Downloader):
return False return False
# Set parameters for adding torrent # Set parameters for adding torrent
params = {} params = {
params['paused'] = self.conf('paused', default = False) 'paused': self.conf('paused', default = False)
}
if self.conf('directory'): if self.conf('directory'):
if os.path.isdir(self.conf('directory')): if os.path.isdir(self.conf('directory')):
@ -135,11 +136,11 @@ class Transmission(Downloader):
def removeFailed(self, item): def removeFailed(self, item):
log.info('%s failed downloading, deleting...', item['name']) log.info('%s failed downloading, deleting...', item['name'])
return self.trpc.remove_torrent(self, item['hashString'], True) return self.trpc.remove_torrent(item['hashString'], True)
def processComplete(self, item, delete_files = False): def processComplete(self, item, delete_files = False):
log.debug('Requesting Transmission to remove the torrent %s%s.', (item['name'], ' and cleanup the downloaded files' if delete_files else '')) log.debug('Requesting Transmission to remove the torrent %s%s.', (item['name'], ' and cleanup the downloaded files' if delete_files else ''))
return self.trpc.remove_torrent(self, item['hashString'], delete_files) return self.trpc.remove_torrent(item['hashString'], delete_files)
class TransmissionRPC(object): class TransmissionRPC(object):

4
couchpotato/core/downloaders/utorrent/main.py

@ -1,5 +1,5 @@
from base64 import b16encode, b32decode from base64 import b16encode, b32decode
from bencode import bencode, bdecode from bencode import bencode as benc, bdecode
from couchpotato.core.downloaders.base import Downloader, StatusList from couchpotato.core.downloaders.base import Downloader, StatusList
from couchpotato.core.helpers.encoding import isInt, ss from couchpotato.core.helpers.encoding import isInt, ss
from couchpotato.core.helpers.variable import tryInt, tryFloat from couchpotato.core.helpers.variable import tryInt, tryFloat
@ -74,7 +74,7 @@ class uTorrent(Downloader):
torrent_params['trackers'] = '%0D%0A%0D%0A'.join(self.torrent_trackers) torrent_params['trackers'] = '%0D%0A%0D%0A'.join(self.torrent_trackers)
else: else:
info = bdecode(filedata)["info"] info = bdecode(filedata)["info"]
torrent_hash = sha1(bencode(info)).hexdigest().upper() torrent_hash = sha1(benc(info)).hexdigest().upper()
torrent_filename = self.createFileName(data, filedata, movie) torrent_filename = self.createFileName(data, filedata, movie)
if data.get('seed_ratio'): if data.get('seed_ratio'):

4
couchpotato/core/event.py

@ -21,9 +21,11 @@ def addEvent(name, handler, priority = 100):
def createHandle(*args, **kwargs): def createHandle(*args, **kwargs):
h = None
try: try:
# Open handler # Open handler
has_parent = hasattr(handler, 'im_self') has_parent = hasattr(handler, 'im_self')
parent = None
if has_parent: if has_parent:
parent = handler.im_self parent = handler.im_self
bc = hasattr(parent, 'beforeCall') bc = hasattr(parent, 'beforeCall')
@ -33,7 +35,7 @@ def addEvent(name, handler, priority = 100):
h = runHandler(name, handler, *args, **kwargs) h = runHandler(name, handler, *args, **kwargs)
# Close handler # Close handler
if has_parent: if parent and has_parent:
ac = hasattr(parent, 'afterCall') ac = hasattr(parent, 'afterCall')
if ac: parent.afterCall(handler) if ac: parent.afterCall(handler)
except: except:

2
couchpotato/core/helpers/encoding.py

@ -63,7 +63,7 @@ def stripAccents(s):
def tryUrlencode(s): def tryUrlencode(s):
new = u'' new = u''
if isinstance(s, (dict)): if isinstance(s, dict):
for key, value in s.iteritems(): for key, value in s.iteritems():
new += u'&%s=%s' % (key, tryUrlencode(value)) new += u'&%s=%s' % (key, tryUrlencode(value))

2
couchpotato/core/helpers/request.py

@ -8,7 +8,7 @@ def getParams(params):
reg = re.compile('^[a-z0-9_\.]+$') reg = re.compile('^[a-z0-9_\.]+$')
current = temp = {} temp = {}
for param, value in sorted(params.iteritems()): for param, value in sorted(params.iteritems()):
nest = re.split("([\[\]]+)", param) nest = re.split("([\[\]]+)", param)

6
couchpotato/core/helpers/rss.py

@ -6,7 +6,7 @@ log = CPLog(__name__)
class RSS(object): class RSS(object):
def getTextElements(self, xml, path): def getTextElements(self, xml, path):
''' Find elements and return tree''' """ Find elements and return tree"""
textelements = [] textelements = []
try: try:
@ -28,7 +28,7 @@ class RSS(object):
return elements return elements
def getElement(self, xml, path): def getElement(self, xml, path):
''' Find element and return text''' """ Find element and return text"""
try: try:
return xml.find(path) return xml.find(path)
@ -36,7 +36,7 @@ class RSS(object):
return return
def getTextElement(self, xml, path): def getTextElement(self, xml, path):
''' Find element and return text''' """ Find element and return text"""
try: try:
return xml.find(path).text return xml.find(path).text

10
couchpotato/core/helpers/variable.py

@ -179,11 +179,11 @@ def getTitle(library_dict):
def possibleTitles(raw_title): def possibleTitles(raw_title):
titles = [] titles = [
toSafeString(raw_title).lower(),
titles.append(toSafeString(raw_title).lower()) raw_title.lower(),
titles.append(raw_title.lower()) simplifyString(raw_title)
titles.append(simplifyString(raw_title)) ]
# replace some chars # replace some chars
new_title = raw_title.replace('&', 'and') new_title = raw_title.replace('&', 'and')

4
couchpotato/core/loader.py

@ -66,7 +66,7 @@ class Loader(object):
self.loadPlugins(m, plugin.get('name')) self.loadPlugins(m, plugin.get('name'))
except ImportError as e: except ImportError as e:
# todo:: subclass ImportError for missing requirements. # todo:: subclass ImportError for missing requirements.
if (e.message.lower().startswith("missing")): if e.message.lower().startswith("missing"):
log.error(e.message) log.error(e.message)
pass pass
# todo:: this needs to be more descriptive. # todo:: this needs to be more descriptive.
@ -122,7 +122,7 @@ class Loader(object):
try: try:
module.start() module.start()
return True return True
except Exception, e: except:
log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc())) log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc()))
return False return False

1
couchpotato/core/media/__init__.py

@ -1,5 +1,4 @@
from couchpotato.core.event import addEvent from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin

1
couchpotato/core/media/_base/searcher/__init__.py

@ -1,5 +1,4 @@
from .main import Searcher from .main import Searcher
import random
def start(): def start():
return Searcher() return Searcher()

20
couchpotato/core/media/_base/searcher/base.py

@ -1,4 +1,3 @@
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.event import addEvent, fireEvent
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
@ -19,12 +18,10 @@ class SearcherBase(Plugin):
self.initCron() self.initCron()
""" Set the searcher cronjob
Make sure to reset cronjob after setting has changed
"""
def initCron(self): def initCron(self):
""" Set the searcher cronjob
Make sure to reset cronjob after setting has changed
"""
_type = self.getType() _type = self.getType()
@ -38,14 +35,11 @@ class SearcherBase(Plugin):
addEvent('setting.save.%s_searcher.cron_hour.after' % _type, setCrons) addEvent('setting.save.%s_searcher.cron_hour.after' % _type, setCrons)
addEvent('setting.save.%s_searcher.cron_minute.after' % _type, setCrons) addEvent('setting.save.%s_searcher.cron_minute.after' % _type, setCrons)
""" Return progress of current searcher
"""
def getProgress(self, **kwargs): def getProgress(self, **kwargs):
""" Return progress of current searcher"""
progress = {} progress = {
progress[self.getType()] = self.in_progress self.getType(): self.in_progress
}
return progress return progress

5
couchpotato/core/media/_base/searcher/main.py

@ -173,10 +173,10 @@ class Searcher(SearcherBase):
year_name = fireEvent('scanner.name_year', name, single = True) year_name = fireEvent('scanner.name_year', name, single = True)
if len(found) == 0 and movie_year < datetime.datetime.now().year - 3 and not year_name.get('year', None): if len(found) == 0 and movie_year < datetime.datetime.now().year - 3 and not year_name.get('year', None):
if size > 3000: # Assume dvdr if size > 3000: # Assume dvdr
log.info('Quality was missing in name, assuming it\'s a DVD-R based on the size: %s', (size)) log.info('Quality was missing in name, assuming it\'s a DVD-R based on the size: %s', size)
found['dvdr'] = True found['dvdr'] = True
else: # Assume dvdrip else: # Assume dvdrip
log.info('Quality was missing in name, assuming it\'s a DVD-Rip based on the size: %s', (size)) log.info('Quality was missing in name, assuming it\'s a DVD-Rip based on the size: %s', size)
found['dvdrip'] = True found['dvdrip'] = True
# Allow other qualities # Allow other qualities
@ -191,6 +191,7 @@ class Searcher(SearcherBase):
if not isinstance(haystack, (list, tuple, set)): if not isinstance(haystack, (list, tuple, set)):
haystack = [haystack] haystack = [haystack]
year_name = {}
for string in haystack: for string in haystack:
year_name = fireEvent('scanner.name_year', string, single = True) year_name = fireEvent('scanner.name_year', string, single = True)

22
couchpotato/core/media/movie/_base/main.py

@ -145,7 +145,7 @@ class MovieBase(MovieTypeBase):
imdb_id = getImdb(str(movie_id)) imdb_id = getImdb(str(movie_id))
if(imdb_id): if imdb_id:
m = db.query(Movie).filter(Movie.library.has(identifier = imdb_id)).first() m = db.query(Movie).filter(Movie.library.has(identifier = imdb_id)).first()
else: else:
m = db.query(Movie).filter_by(id = movie_id).first() m = db.query(Movie).filter_by(id = movie_id).first()
@ -231,7 +231,7 @@ class MovieBase(MovieTypeBase):
})) }))
db.expire_all() db.expire_all()
return (total_count, movies) return total_count, movies
def availableChars(self, status = None, release_status = None): def availableChars(self, status = None, release_status = None):
@ -270,12 +270,12 @@ class MovieBase(MovieTypeBase):
def listView(self, **kwargs): def listView(self, **kwargs):
status = splitString(kwargs.get('status', None)) status = splitString(kwargs.get('status'))
release_status = splitString(kwargs.get('release_status', None)) release_status = splitString(kwargs.get('release_status'))
limit_offset = kwargs.get('limit_offset', None) limit_offset = kwargs.get('limit_offset')
starts_with = kwargs.get('starts_with', None) starts_with = kwargs.get('starts_with')
search = kwargs.get('search', None) search = kwargs.get('search')
order = kwargs.get('order', None) order = kwargs.get('order')
total_movies, movies = self.list( total_movies, movies = self.list(
status = status, status = status,
@ -372,7 +372,7 @@ class MovieBase(MovieTypeBase):
fireEvent('status.get', ['active', 'snatched', 'ignored', 'done', 'downloaded'], single = True) fireEvent('status.get', ['active', 'snatched', 'ignored', 'done', 'downloaded'], single = True)
default_profile = fireEvent('profile.default', single = True) default_profile = fireEvent('profile.default', single = True)
cat_id = params.get('category_id', None) cat_id = params.get('category_id')
db = get_session() db = get_session()
m = db.query(Movie).filter_by(library_id = library.get('id')).first() m = db.query(Movie).filter_by(library_id = library.get('id')).first()
@ -463,7 +463,7 @@ class MovieBase(MovieTypeBase):
m.profile_id = kwargs.get('profile_id') m.profile_id = kwargs.get('profile_id')
cat_id = kwargs.get('category_id', None) cat_id = kwargs.get('category_id')
if cat_id is not None: if cat_id is not None:
m.category_id = tryInt(cat_id) if tryInt(cat_id) > 0 else None m.category_id = tryInt(cat_id) if tryInt(cat_id) > 0 else None
@ -559,7 +559,7 @@ class MovieBase(MovieTypeBase):
log.debug('Can\'t restatus movie, doesn\'t seem to exist.') log.debug('Can\'t restatus movie, doesn\'t seem to exist.')
return False return False
log.debug('Changing status for %s', (m.library.titles[0].title)) log.debug('Changing status for %s', m.library.titles[0].title)
if not m.profile: if not m.profile:
m.status_id = done_status.get('id') m.status_id = done_status.get('id')
else: else:

3
couchpotato/core/media/movie/library/movie/main.py

@ -2,8 +2,8 @@ from couchpotato import get_session
from couchpotato.core.event import addEvent, fireEventAsync, fireEvent from couchpotato.core.event import addEvent, fireEventAsync, fireEvent
from couchpotato.core.helpers.encoding import toUnicode, simplifyString from couchpotato.core.helpers.encoding import toUnicode, simplifyString
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.settings.model import Library, LibraryTitle, File
from couchpotato.core.media._base.library import LibraryBase from couchpotato.core.media._base.library import LibraryBase
from couchpotato.core.settings.model import Library, LibraryTitle, File
from string import ascii_letters from string import ascii_letters
import time import time
import traceback import traceback
@ -66,6 +66,7 @@ class MovieLibraryPlugin(LibraryBase):
library = db.query(Library).filter_by(identifier = identifier).first() library = db.query(Library).filter_by(identifier = identifier).first()
done_status = fireEvent('status.get', 'done', single = True) done_status = fireEvent('status.get', 'done', single = True)
library_dict = None
if library: if library:
library_dict = library.to_dict(self.default_dict) library_dict = library.to_dict(self.default_dict)

1
couchpotato/core/notifications/base.py

@ -45,6 +45,7 @@ class Notification(Provider):
def _notify(self, *args, **kwargs): def _notify(self, *args, **kwargs):
if self.isEnabled(): if self.isEnabled():
return self.notify(*args, **kwargs) return self.notify(*args, **kwargs)
return False
def notify(self, message = '', data = {}, listener = None): def notify(self, message = '', data = {}, listener = None):
pass pass

17
couchpotato/core/notifications/nmj/main.py

@ -23,16 +23,15 @@ class NMJ(Notification):
def autoConfig(self, host = 'localhost', **kwargs): def autoConfig(self, host = 'localhost', **kwargs):
database = ''
mount = '' mount = ''
try: try:
terminal = telnetlib.Telnet(host) terminal = telnetlib.Telnet(host)
except Exception: except Exception:
log.error('Warning: unable to get a telnet session to %s', (host)) log.error('Warning: unable to get a telnet session to %s', host)
return self.failed() return self.failed()
log.debug('Connected to %s via telnet', (host)) log.debug('Connected to %s via telnet', host)
terminal.read_until('sh-3.00# ') terminal.read_until('sh-3.00# ')
terminal.write('cat /tmp/source\n') terminal.write('cat /tmp/source\n')
terminal.write('cat /tmp/netshare\n') terminal.write('cat /tmp/netshare\n')
@ -46,7 +45,7 @@ class NMJ(Notification):
device = match.group(2) device = match.group(2)
log.info('Found NMJ database %s on device %s', (database, device)) log.info('Found NMJ database %s on device %s', (database, device))
else: else:
log.error('Could not get current NMJ database on %s, NMJ is probably not running!', (host)) log.error('Could not get current NMJ database on %s, NMJ is probably not running!', host)
return self.failed() return self.failed()
if device.startswith('NETWORK_SHARE/'): if device.startswith('NETWORK_SHARE/'):
@ -54,7 +53,7 @@ class NMJ(Notification):
if match: if match:
mount = match.group().replace('127.0.0.1', host) mount = match.group().replace('127.0.0.1', host)
log.info('Found mounting url on the Popcorn Hour in configuration: %s', (mount)) log.info('Found mounting url on the Popcorn Hour in configuration: %s', mount)
else: else:
log.error('Detected a network share on the Popcorn Hour, but could not get the mounting url') log.error('Detected a network share on the Popcorn Hour, but could not get the mounting url')
return self.failed() return self.failed()
@ -73,9 +72,9 @@ class NMJ(Notification):
database = self.conf('database') database = self.conf('database')
if mount: if mount:
log.debug('Try to mount network drive via url: %s', (mount)) log.debug('Try to mount network drive via url: %s', mount)
try: try:
data = self.urlopen(mount) self.urlopen(mount)
except: except:
return False return False
@ -98,11 +97,11 @@ class NMJ(Notification):
et = etree.fromstring(response) et = etree.fromstring(response)
result = et.findtext('returnValue') result = et.findtext('returnValue')
except SyntaxError, e: except SyntaxError, e:
log.error('Unable to parse XML returned from the Popcorn Hour: %s', (e)) log.error('Unable to parse XML returned from the Popcorn Hour: %s', e)
return False return False
if int(result) > 0: if int(result) > 0:
log.error('Popcorn Hour returned an errorcode: %s', (result)) log.error('Popcorn Hour returned an errorcode: %s', result)
return False return False
else: else:
log.info('NMJ started background scan') log.info('NMJ started background scan')

5
couchpotato/core/notifications/notifymyandroid/main.py

@ -15,12 +15,9 @@ class NotifyMyAndroid(Notification):
nma.addkey(keys) nma.addkey(keys)
nma.developerkey(self.conf('dev_key')) nma.developerkey(self.conf('dev_key'))
# hacky fix for the event type
# as it seems to be part of the message now
self.event = message.split(' ')[0]
response = nma.push( response = nma.push(
application = self.default_title, application = self.default_title,
event = self.event, event = message.split(' ')[0],
description = message, description = message,
priority = self.conf('priority'), priority = self.conf('priority'),
batch_mode = len(keys) > 1 batch_mode = len(keys) > 1

2
couchpotato/core/notifications/plex/main.py

@ -37,7 +37,7 @@ class Plex(Notification):
for s in sections: for s in sections:
if s.getAttribute('type') in source_type: if s.getAttribute('type') in source_type:
url = refresh_url % s.getAttribute('key') url = refresh_url % s.getAttribute('key')
x = self.urlopen(url) self.urlopen(url)
except: except:
log.error('Plex library update failed for %s, Media Server not running: %s', (host, traceback.format_exc(1))) log.error('Plex library update failed for %s, Media Server not running: %s', (host, traceback.format_exc(1)))

3
couchpotato/core/notifications/synoindex/main.py

@ -27,9 +27,8 @@ class Synoindex(Notification):
return True return True
except OSError, e: except OSError, e:
log.error('Unable to run synoindex: %s', e) log.error('Unable to run synoindex: %s', e)
return False
return True return False
def test(self, **kwargs): def test(self, **kwargs):
return { return {

3
couchpotato/core/notifications/twitter/main.py

@ -4,7 +4,8 @@ from couchpotato.core.helpers.variable import cleanHost
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification from couchpotato.core.notifications.base import Notification
from couchpotato.environment import Env from couchpotato.environment import Env
from pytwitter import Api, parse_qsl from pytwitter import Api
from urlparse import parse_qsl
import oauth2 import oauth2
log = CPLog(__name__) log = CPLog(__name__)

18
couchpotato/core/notifications/xbmc/main.py

@ -53,9 +53,9 @@ class XBMC(Notification):
try: try:
for result in response: for result in response:
if (result.get('result') and result['result'] == 'OK'): if result.get('result') and result['result'] == 'OK':
successful += 1 successful += 1
elif (result.get('error')): elif result.get('error'):
log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code'])) log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code']))
except: except:
@ -72,7 +72,7 @@ class XBMC(Notification):
('JSONRPC.Version', {}) ('JSONRPC.Version', {})
]) ])
for result in response: for result in response:
if (result.get('result') and type(result['result']['version']).__name__ == 'int'): if result.get('result') and type(result['result']['version']).__name__ == 'int':
# only v2 and v4 return an int object # only v2 and v4 return an int object
# v6 (as of XBMC v12(Frodo)) is required to send notifications # v6 (as of XBMC v12(Frodo)) is required to send notifications
xbmc_rpc_version = str(result['result']['version']) xbmc_rpc_version = str(result['result']['version'])
@ -85,15 +85,15 @@ class XBMC(Notification):
# send the text message # send the text message
resp = self.notifyXBMCnoJSON(host, {'title':self.default_title, 'message':message}) resp = self.notifyXBMCnoJSON(host, {'title':self.default_title, 'message':message})
for result in resp: for result in resp:
if (result.get('result') and result['result'] == 'OK'): if result.get('result') and result['result'] == 'OK':
log.debug('Message delivered successfully!') log.debug('Message delivered successfully!')
success = True success = True
break break
elif (result.get('error')): elif result.get('error'):
log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code'])) log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code']))
break break
elif (result.get('result') and type(result['result']['version']).__name__ == 'dict'): elif result.get('result') and type(result['result']['version']).__name__ == 'dict':
# XBMC JSON-RPC v6 returns an array object containing # XBMC JSON-RPC v6 returns an array object containing
# major, minor and patch number # major, minor and patch number
xbmc_rpc_version = str(result['result']['version']['major']) xbmc_rpc_version = str(result['result']['version']['major'])
@ -108,16 +108,16 @@ class XBMC(Notification):
# send the text message # send the text message
resp = self.request(host, [('GUI.ShowNotification', {'title':self.default_title, 'message':message, 'image': self.getNotificationImage('small')})]) resp = self.request(host, [('GUI.ShowNotification', {'title':self.default_title, 'message':message, 'image': self.getNotificationImage('small')})])
for result in resp: for result in resp:
if (result.get('result') and result['result'] == 'OK'): if result.get('result') and result['result'] == 'OK':
log.debug('Message delivered successfully!') log.debug('Message delivered successfully!')
success = True success = True
break break
elif (result.get('error')): elif result.get('error'):
log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code'])) log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code']))
break break
# error getting version info (we do have contact with XBMC though) # error getting version info (we do have contact with XBMC though)
elif (result.get('error')): elif result.get('error'):
log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code'])) log.error('XBMC error; %s: %s (%s)', (result['id'], result['error']['message'], result['error']['code']))
log.debug('Use JSON notifications: %s ', self.use_json_notifications) log.debug('Use JSON notifications: %s ', self.use_json_notifications)

4
couchpotato/core/plugins/base.py

@ -26,11 +26,13 @@ log = CPLog(__name__)
class Plugin(object): class Plugin(object):
_class_name = None _class_name = None
plugin_path = None
enabled_option = 'enabled' enabled_option = 'enabled'
auto_register_static = True auto_register_static = True
_needs_shutdown = False _needs_shutdown = False
_running = None
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20130519 Firefox/24.0' user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20130519 Firefox/24.0'
http_last_use = {} http_last_use = {}
@ -306,4 +308,4 @@ class Plugin(object):
return not self.isEnabled() return not self.isEnabled()
def isEnabled(self): def isEnabled(self):
return self.conf(self.enabled_option) or self.conf(self.enabled_option) == None return self.conf(self.enabled_option) or self.conf(self.enabled_option) is None

2
couchpotato/core/plugins/browser/main.py

@ -12,7 +12,7 @@ if os.name == 'nt':
except: except:
# todo:: subclass ImportError for missing dependencies, vs. broken plugins? # todo:: subclass ImportError for missing dependencies, vs. broken plugins?
raise ImportError("Missing the win32file module, which is a part of the prerequisite \ raise ImportError("Missing the win32file module, which is a part of the prerequisite \
pywin32 package. You can get it from http://sourceforge.net/projects/pywin32/files/pywin32/"); pywin32 package. You can get it from http://sourceforge.net/projects/pywin32/files/pywin32/")
else: else:
import win32file #@UnresolvedImport import win32file #@UnresolvedImport

2
couchpotato/core/plugins/dashboard/main.py

@ -93,7 +93,7 @@ class Dashboard(Plugin):
}) })
# Don't list older movies # Don't list older movies
if ((not late and ((not eta.get('dvd') and not eta.get('theater')) or (eta.get('dvd') and eta.get('dvd') > (now - 2419200)))) or \ if ((not late and (not eta.get('dvd') and not eta.get('theater') or eta.get('dvd') and eta.get('dvd') > (now - 2419200))) or
(late and (eta.get('dvd', 0) > 0 or eta.get('theater')) and eta.get('dvd') < (now - 2419200))): (late and (eta.get('dvd', 0) > 0 or eta.get('theater')) and eta.get('dvd') < (now - 2419200))):
movies.append(temp) movies.append(temp)

1
couchpotato/core/plugins/log/main.py

@ -90,7 +90,6 @@ class Logging(Plugin):
if not os.path.isfile(path): if not os.path.isfile(path):
break break
reversed_lines = []
f = open(path, 'r') f = open(path, 'r')
reversed_lines = toUnicode(f.read()).split('[0m\n') reversed_lines = toUnicode(f.read()).split('[0m\n')
reversed_lines.reverse() reversed_lines.reverse()

4
couchpotato/core/plugins/manage/main.py

@ -184,7 +184,7 @@ class Manage(Plugin):
fireEvent('release.add', group = group) fireEvent('release.add', group = group)
fireEventAsync('library.update.movie', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier)) fireEventAsync('library.update.movie', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier))
else: else:
self.in_progress[folder]['to_go'] = self.in_progress[folder]['to_go'] - 1 self.in_progress[folder]['to_go'] -= 1
return addToLibrary return addToLibrary
@ -195,7 +195,7 @@ class Manage(Plugin):
if not self.in_progress or self.shuttingDown(): if not self.in_progress or self.shuttingDown():
return return
self.in_progress[folder]['to_go'] = self.in_progress[folder]['to_go'] - 1 self.in_progress[folder]['to_go'] -= 1
total = self.in_progress[folder]['total'] total = self.in_progress[folder]['total']
movie_dict = fireEvent('movie.get', identifier, single = True) movie_dict = fireEvent('movie.get', identifier, single = True)

2
couchpotato/core/plugins/profile/main.py

@ -155,7 +155,7 @@ class ProfilePlugin(Plugin):
def fill(self): def fill(self):
db = get_session(); db = get_session()
profiles = [{ profiles = [{
'label': 'Best', 'label': 'Best',

2
couchpotato/core/plugins/quality/main.py

@ -102,7 +102,7 @@ class QualityPlugin(Plugin):
def fill(self): def fill(self):
db = get_session(); db = get_session()
order = 0 order = 0
for q in self.qualities: for q in self.qualities:

5
couchpotato/core/plugins/release/main.py

@ -8,6 +8,7 @@ from couchpotato.core.plugins.scanner.main import Scanner
from couchpotato.core.settings.model import File, Release as Relea, Movie from couchpotato.core.settings.model import File, Release as Relea, Movie
from sqlalchemy.sql.expression import and_, or_ from sqlalchemy.sql.expression import and_, or_
import os import os
import traceback
log = CPLog(__name__) log = CPLog(__name__)
@ -88,8 +89,8 @@ class Release(Plugin):
added_files = db.query(File).filter(or_(*[File.id == x for x in added_files])).all() added_files = db.query(File).filter(or_(*[File.id == x for x in added_files])).all()
rel.files.extend(added_files) rel.files.extend(added_files)
db.commit() db.commit()
except Exception, e: except:
log.debug('Failed to attach "%s" to release: %s', (cur_file, e)) log.debug('Failed to attach "%s" to release: %s', (added_files, traceback.format_exc()))
fireEvent('movie.restatus', movie.id) fireEvent('movie.restatus', movie.id)

29
couchpotato/core/plugins/renamer/main.py

@ -9,8 +9,7 @@ from couchpotato.core.plugins.base import Plugin
from couchpotato.core.settings.model import Library, File, Profile, Release, \ from couchpotato.core.settings.model import Library, File, Profile, Release, \
ReleaseInfo ReleaseInfo
from couchpotato.environment import Env from couchpotato.environment import Env
from unrar2 import RarFile, RarInfo from unrar2 import RarFile
from unrar2.rar_exceptions import *
import errno import errno
import fnmatch import fnmatch
import os import os
@ -62,10 +61,10 @@ class Renamer(Plugin):
def scanView(self, **kwargs): def scanView(self, **kwargs):
async = tryInt(kwargs.get('async', None)) async = tryInt(kwargs.get('async', 0))
movie_folder = kwargs.get('movie_folder', None) movie_folder = kwargs.get('movie_folder')
downloader = kwargs.get('downloader', None) downloader = kwargs.get('downloader')
download_id = kwargs.get('download_id', None) download_id = kwargs.get('download_id')
download_info = {'folder': movie_folder} if movie_folder else None download_info = {'folder': movie_folder} if movie_folder else None
if download_info: if download_info:
@ -98,7 +97,7 @@ class Renamer(Plugin):
elif self.conf('from') in self.conf('to'): elif self.conf('from') in self.conf('to'):
log.error('The "to" can\'t be inside of the "from" folder. You\'ll get an infinite loop.') log.error('The "to" can\'t be inside of the "from" folder. You\'ll get an infinite loop.')
return return
elif (movie_folder and movie_folder in [self.conf('to'), self.conf('from')]): elif movie_folder and movie_folder in [self.conf('to'), self.conf('from')]:
log.error('The "to" and "from" folders can\'t be inside of or the same as the provided movie folder.') log.error('The "to" and "from" folders can\'t be inside of or the same as the provided movie folder.')
return return
@ -131,8 +130,8 @@ class Renamer(Plugin):
# Unpack any archives # Unpack any archives
extr_files = None extr_files = None
if self.conf('unrar'): if self.conf('unrar'):
folder, movie_folder, files, extr_files = self.extractFiles(folder = folder, movie_folder = movie_folder, files = files, \ folder, movie_folder, files, extr_files = self.extractFiles(folder = folder, movie_folder = movie_folder, files = files,
cleanup = self.conf('cleanup') and not self.downloadIsTorrent(download_info)) cleanup = self.conf('cleanup') and not self.downloadIsTorrent(download_info))
groups = fireEvent('scanner.scan', folder = folder if folder else self.conf('from'), groups = fireEvent('scanner.scan', folder = folder if folder else self.conf('from'),
files = files, download_info = download_info, return_ignored = False, single = True) files = files, download_info = download_info, return_ignored = False, single = True)
@ -347,7 +346,7 @@ class Renamer(Plugin):
profile = db.query(Profile).filter_by(core = True, label = group['meta_data']['quality']['label']).first() profile = db.query(Profile).filter_by(core = True, label = group['meta_data']['quality']['label']).first()
fireEvent('movie.add', params = {'identifier': group['library']['identifier'], 'profile_id': profile.id}, search_after = False) fireEvent('movie.add', params = {'identifier': group['library']['identifier'], 'profile_id': profile.id}, search_after = False)
db.expire_all() db.expire_all()
library = db.query(Library).filter_by(identifier = group['library']['identifier']).first() library_ent = db.query(Library).filter_by(identifier = group['library']['identifier']).first()
for movie in library_ent.movies: for movie in library_ent.movies:
@ -517,7 +516,7 @@ class Renamer(Plugin):
def tagDir(self, group, tag): def tagDir(self, group, tag):
ignore_file = None ignore_file = None
if isinstance(group, (dict)): if isinstance(group, dict):
for movie_file in sorted(list(group['files']['movie'])): for movie_file in sorted(list(group['files']['movie'])):
ignore_file = '%s.%s.ignore' % (os.path.splitext(movie_file)[0], tag) ignore_file = '%s.%s.ignore' % (os.path.splitext(movie_file)[0], tag)
break break
@ -603,9 +602,9 @@ Remove it if you want it to be renamed (again, or at least let it try again)
return True return True
def doReplace(self, string, replacements, remove_multiple = False): def doReplace(self, string, replacements, remove_multiple = False):
''' """
replace confignames with the real thing replace confignames with the real thing
''' """
replacements = replacements.copy() replacements = replacements.copy()
if remove_multiple: if remove_multiple:
@ -873,7 +872,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
#Extract all found archives #Extract all found archives
for archive in archives: for archive in archives:
# Check if it has already been processed by CPS # Check if it has already been processed by CPS
if (self.hastagDir(os.path.dirname(archive['file']))): if self.hastagDir(os.path.dirname(archive['file'])):
continue continue
# Find all related archive files # Find all related archive files
@ -970,4 +969,4 @@ Remove it if you want it to be renamed (again, or at least let it try again)
files = [] files = []
folder = None folder = None
return (folder, movie_folder, files, extr_files) return folder, movie_folder, files, extr_files

23
couchpotato/core/plugins/scanner/main.py

@ -429,7 +429,7 @@ class Scanner(Plugin):
if len(processed_movies) > 0: if len(processed_movies) > 0:
log.info('Found %s movies in the folder %s', (len(processed_movies), folder)) log.info('Found %s movies in the folder %s', (len(processed_movies), folder))
else: else:
log.debug('Found no movies in the folder %s', (folder)) log.debug('Found no movies in the folder %s', folder)
return processed_movies return processed_movies
@ -508,6 +508,7 @@ class Scanner(Plugin):
detected_languages = {} detected_languages = {}
# Subliminal scanner # Subliminal scanner
paths = None
try: try:
paths = group['files']['movie'] paths = group['files']['movie']
scan_result = [] scan_result = []
@ -560,12 +561,14 @@ class Scanner(Plugin):
break break
# Check and see if nfo contains the imdb-id # Check and see if nfo contains the imdb-id
nfo_file = None
if not imdb_id: if not imdb_id:
try: try:
for nfo_file in files['nfo']: for nf in files['nfo']:
imdb_id = getImdb(nfo_file) imdb_id = getImdb(nfo_file)
if imdb_id: if imdb_id:
log.debug('Found movie via nfo file: %s', nfo_file) log.debug('Found movie via nfo file: %s', nf)
nfo_file = nf
break break
except: except:
pass pass
@ -585,11 +588,12 @@ class Scanner(Plugin):
# Check if path is already in db # Check if path is already in db
if not imdb_id: if not imdb_id:
db = get_session() db = get_session()
for cur_file in files['movie']: for cf in files['movie']:
f = db.query(File).filter_by(path = toUnicode(cur_file)).first() f = db.query(File).filter_by(path = toUnicode(cf)).first()
try: try:
imdb_id = f.library[0].identifier imdb_id = f.library[0].identifier
log.debug('Found movie via database: %s', cur_file) log.debug('Found movie via database: %s', cf)
cur_file = cf
break break
except: except:
pass pass
@ -680,10 +684,9 @@ class Scanner(Plugin):
return getExt(s.lower()) in ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tbn'] return getExt(s.lower()) in ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tbn']
files = set(filter(test, files)) files = set(filter(test, files))
images = {} images = {
'backdrop': set(filter(lambda s: re.search('(^|[\W_])fanart|backdrop\d*[\W_]', s.lower()) and self.filesizeBetween(s, 0, 5), files))
# Fanart }
images['backdrop'] = set(filter(lambda s: re.search('(^|[\W_])fanart|backdrop\d*[\W_]', s.lower()) and self.filesizeBetween(s, 0, 5), files))
# Rest # Rest
images['rest'] = files - images['backdrop'] images['rest'] = files - images['backdrop']

2
couchpotato/core/plugins/score/main.py

@ -17,7 +17,7 @@ class Score(Plugin):
addEvent('score.calculate', self.calculate) addEvent('score.calculate', self.calculate)
def calculate(self, nzb, movie): def calculate(self, nzb, movie):
''' Calculate the score of a NZB, used for sorting later ''' """ Calculate the score of a NZB, used for sorting later """
# Merge global and category # Merge global and category
preferred_words = splitString(Env.setting('preferred_words', section = 'searcher').lower()) preferred_words = splitString(Env.setting('preferred_words', section = 'searcher').lower())

8
couchpotato/core/plugins/score/scores.py

@ -1,6 +1,6 @@
from couchpotato.core.event import fireEvent from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import simplifyString from couchpotato.core.helpers.encoding import simplifyString
from couchpotato.core.helpers.variable import tryInt, splitString from couchpotato.core.helpers.variable import tryInt
from couchpotato.environment import Env from couchpotato.environment import Env
import re import re
@ -24,7 +24,7 @@ name_scores = [
def nameScore(name, year, preferred_words): def nameScore(name, year, preferred_words):
''' Calculate score for words in the NZB name ''' """ Calculate score for words in the NZB name """
score = 0 score = 0
name = name.lower() name = name.lower()
@ -34,11 +34,11 @@ def nameScore(name, year, preferred_words):
v = value.split(':') v = value.split(':')
add = int(v.pop()) add = int(v.pop())
if v.pop() in name: if v.pop() in name:
score = score + add score += add
# points if the year is correct # points if the year is correct
if str(year) in name: if str(year) in name:
score = score + 5 score += 5
# Contains preferred word # Contains preferred word
nzb_words = re.split('\W+', simplifyString(name)) nzb_words = re.split('\W+', simplifyString(name))

2
couchpotato/core/plugins/status/main.py

@ -75,7 +75,7 @@ class StatusPlugin(Plugin):
def get(self, identifiers): def get(self, identifiers):
if not isinstance(identifiers, (list)): if not isinstance(identifiers, list):
identifiers = [identifiers] identifiers = [identifiers]
db = get_session() db = get_session()

2
couchpotato/core/plugins/subtitle/main.py

@ -36,7 +36,7 @@ class Subtitle(Plugin):
files = [] files = []
for file in release.files.filter(FileType.status.has(identifier = 'movie')).all(): for file in release.files.filter(FileType.status.has(identifier = 'movie')).all():
files.append(file.path); files.append(file.path)
# get subtitles for those files # get subtitles for those files
subliminal.list_subtitles(files, cache_dir = Env.get('cache_dir'), multi = True, languages = self.getLanguages(), services = self.services) subliminal.list_subtitles(files, cache_dir = Env.get('cache_dir'), multi = True, languages = self.getLanguages(), services = self.services)

1
couchpotato/core/plugins/suggestion/main.py

@ -47,6 +47,7 @@ class Suggestion(Plugin):
ignored = splitString(Env.prop('suggest_ignore', default = '')) ignored = splitString(Env.prop('suggest_ignore', default = ''))
new_suggestions = []
if imdb: if imdb:
if not remove_only: if not remove_only:
ignored.append(imdb) ignored.append(imdb)

2
couchpotato/core/providers/automation/imdb/main.py

@ -58,7 +58,7 @@ class IMDBWatchlist(IMDBBase):
break break
except: except:
log.error('Failed loading IMDB watchlist: %s %s', (url, traceback.format_exc())) log.error('Failed loading IMDB watchlist: %s %s', (watchlist_url, traceback.format_exc()))
return movies return movies

2
couchpotato/core/providers/info/omdbapi/main.py

@ -98,7 +98,7 @@ class OMDBAPI(MovieProvider):
'mpaa': str(movie.get('Rated', '')), 'mpaa': str(movie.get('Rated', '')),
'runtime': self.runtimeToMinutes(movie.get('Runtime', '')), 'runtime': self.runtimeToMinutes(movie.get('Runtime', '')),
'released': movie.get('Released'), 'released': movie.get('Released'),
'year': year if isinstance(year, (int)) else None, 'year': year if isinstance(year, int) else None,
'plot': movie.get('Plot'), 'plot': movie.get('Plot'),
'genres': splitString(movie.get('Genre', '')), 'genres': splitString(movie.get('Genre', '')),
'directors': splitString(movie.get('Director', '')), 'directors': splitString(movie.get('Director', '')),

12
couchpotato/core/providers/info/themoviedb/main.py

@ -23,7 +23,7 @@ class TheMovieDb(MovieProvider):
tmdb3.set_cache(engine='file', filename=os.path.join(Env.get('cache_dir'), 'python', 'tmdb.cache')) tmdb3.set_cache(engine='file', filename=os.path.join(Env.get('cache_dir'), 'python', 'tmdb.cache'))
def search(self, q, limit = 12): def search(self, q, limit = 12):
''' Find movie by name ''' """ Find movie by name """
if self.isDisabled(): if self.isDisabled():
return False return False
@ -72,9 +72,6 @@ class TheMovieDb(MovieProvider):
result = self.getCache(cache_key) result = self.getCache(cache_key)
if not result: if not result:
result = {}
movie = None
try: try:
log.debug('Getting info: %s', cache_key) log.debug('Getting info: %s', cache_key)
movie = tmdb3.Movie(identifier) movie = tmdb3.Movie(identifier)
@ -129,7 +126,7 @@ class TheMovieDb(MovieProvider):
movie_data['titles'].append(movie.originaltitle) movie_data['titles'].append(movie.originaltitle)
for alt in movie.alternate_titles: for alt in movie.alternate_titles:
alt_name = alt.title alt_name = alt.title
if alt_name and not alt_name in movie_data['titles'] and alt_name.lower() != 'none' and alt_name != None: if alt_name and not alt_name in movie_data['titles'] and alt_name.lower() != 'none' and alt_name is not None:
movie_data['titles'].append(alt_name) movie_data['titles'].append(alt_name)
movie_data['titles'] = list(set(movie_data['titles'])) movie_data['titles'] = list(set(movie_data['titles']))
@ -149,6 +146,5 @@ class TheMovieDb(MovieProvider):
def isDisabled(self): def isDisabled(self):
if self.conf('api_key') == '': if self.conf('api_key') == '':
log.error('No API key provided.') log.error('No API key provided.')
True return True
else: return False
False

7
couchpotato/core/providers/metadata/base.py

@ -82,8 +82,11 @@ class MetaDataBase(Plugin):
def getThumbnail(self, movie_info = {}, data = {}, wanted_file_type = 'poster_original'): def getThumbnail(self, movie_info = {}, data = {}, wanted_file_type = 'poster_original'):
file_types = fireEvent('file.types', single = True) file_types = fireEvent('file.types', single = True)
for file_type in file_types: file_type = {}
if file_type.get('identifier') == wanted_file_type:
for ft in file_types:
if ft.get('identifier') == wanted_file_type:
file_type = ft
break break
# See if it is in current files # See if it is in current files

6
couchpotato/core/providers/nzb/binsearch/main.py

@ -86,8 +86,10 @@ class BinSearch(NZBProvider):
def download(self, url = '', nzb_id = ''): def download(self, url = '', nzb_id = ''):
params = {'action': 'nzb'} params = {
params[nzb_id] = 'on' 'action': 'nzb',
nzb_id: 'on'
}
try: try:
return self.urlopen(url, params = params, show_error = False) return self.urlopen(url, params = params, show_error = False)

2
couchpotato/core/providers/nzb/newznab/main.py

@ -118,7 +118,7 @@ class Newznab(NZBProvider, RSS):
return list return list
def belongsTo(self, url, provider = None): def belongsTo(self, url, provider = None, host = None):
hosts = self.getHosts() hosts = self.getHosts()

2
couchpotato/core/providers/torrent/scenehd/main.py

@ -65,7 +65,7 @@ class SceneHD(TorrentProvider):
log.error('Failed getting results from %s: %s', (self.getName(), traceback.format_exc())) log.error('Failed getting results from %s: %s', (self.getName(), traceback.format_exc()))
def getLoginParams(self, params): def getLoginParams(self):
return tryUrlencode({ return tryUrlencode({
'username': self.conf('username'), 'username': self.conf('username'),
'password': self.conf('password'), 'password': self.conf('password'),

8
couchpotato/core/providers/torrent/thepiratebay/main.py

@ -86,10 +86,10 @@ class ThePirateBay(TorrentMagnetProvider):
if link and download: if link and download:
def extra_score(item): def extra_score(item):
trusted = (0, 10)[result.find('img', alt = re.compile('Trusted')) != None] trusted = (0, 10)[result.find('img', alt = re.compile('Trusted')) is not None]
vip = (0, 20)[result.find('img', alt = re.compile('VIP')) != None] vip = (0, 20)[result.find('img', alt = re.compile('VIP')) is not None]
confirmed = (0, 30)[result.find('img', alt = re.compile('Helpers')) != None] confirmed = (0, 30)[result.find('img', alt = re.compile('Helpers')) is not None]
moderated = (0, 50)[result.find('img', alt = re.compile('Moderator')) != None] moderated = (0, 50)[result.find('img', alt = re.compile('Moderator')) is not None]
return confirmed + trusted + vip + moderated return confirmed + trusted + vip + moderated

3
couchpotato/core/providers/userscript/allocine/main.py

@ -19,9 +19,6 @@ class AlloCine(UserscriptBase):
except: except:
return return
name = None
year = None
try: try:
start = data.find('<title>') start = data.find('<title>')
end = data.find('</title>', start) end = data.find('</title>', start)

7
couchpotato/core/settings/__init__.py

@ -1,13 +1,10 @@
from __future__ import with_statement from __future__ import with_statement
from couchpotato.api import addApiView from couchpotato.api import addApiView
from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.event import addEvent, fireEvent
from couchpotato.core.helpers.encoding import isInt, toUnicode from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import mergeDicts, tryInt, tryFloat from couchpotato.core.helpers.variable import mergeDicts, tryInt, tryFloat
from couchpotato.core.settings.model import Properties from couchpotato.core.settings.model import Properties
import ConfigParser import ConfigParser
import os.path
import time
import traceback
class Settings(object): class Settings(object):
@ -92,7 +89,7 @@ class Settings(object):
self.setType(section_name, option_name, option.get('type')) self.setType(section_name, option_name, option.get('type'))
if save: if save:
self.save(self) self.save()
def set(self, section, option, value): def set(self, section, option, value):
return self.p.set(section, option, value) return self.p.set(section, option, value)

4
couchpotato/environment.py

@ -74,7 +74,7 @@ class Env(object):
s = Env.get('settings') s = Env.get('settings')
# Return setting # Return setting
if value == None: if value is None:
return s.get(attr, default = default, section = section, type = type) return s.get(attr, default = default, section = section, type = type)
# Set setting # Set setting
@ -86,7 +86,7 @@ class Env(object):
@staticmethod @staticmethod
def prop(identifier, value = None, default = None): def prop(identifier, value = None, default = None):
s = Env.get('settings') s = Env.get('settings')
if value == None: if value is None:
v = s.getProperty(identifier) v = s.getProperty(identifier)
return v if v else default return v if v else default

4
couchpotato/runner.py

@ -112,7 +112,7 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
try: try:
if os.path.isfile(file_path): if os.path.isfile(file_path):
os.remove(file_path) os.remove(file_path)
except Exception, e: except:
raise raise
os.rmdir(backup) os.rmdir(backup)
@ -257,7 +257,7 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
application.add_handlers(".*$", [ application.add_handlers(".*$", [
('%s%s/(.*)' % (static_path, dir_name), StaticFileHandler, {'path': toUnicode(os.path.join(base_path, 'couchpotato', 'static', dir_name))}) ('%s%s/(.*)' % (static_path, dir_name), StaticFileHandler, {'path': toUnicode(os.path.join(base_path, 'couchpotato', 'static', dir_name))})
]) ])
Env.set('static_path', static_path); Env.set('static_path', static_path)
# Load configs & plugins # Load configs & plugins

Loading…
Cancel
Save