Browse Source

Code cleanup

pull/2742/merge
Ruud 11 years ago
parent
commit
799299c7cc
  1. 8
      CouchPotato.py
  2. 26
      couchpotato/__init__.py
  3. 10
      couchpotato/api.py
  4. 1
      couchpotato/core/_base/_core/__init__.py
  5. 1
      couchpotato/core/_base/clientscript/__init__.py
  6. 6
      couchpotato/core/_base/clientscript/main.py
  7. 1
      couchpotato/core/_base/desktop/__init__.py
  8. 1
      couchpotato/core/_base/scheduler/__init__.py
  9. 1
      couchpotato/core/_base/updater/__init__.py
  10. 16
      couchpotato/core/_base/updater/main.py
  11. 1
      couchpotato/core/downloaders/blackhole/__init__.py
  12. 1
      couchpotato/core/downloaders/deluge/__init__.py
  13. 1
      couchpotato/core/downloaders/deluge/main.py
  14. 1
      couchpotato/core/downloaders/nzbget/__init__.py
  15. 6
      couchpotato/core/downloaders/nzbget/main.py
  16. 1
      couchpotato/core/downloaders/nzbvortex/__init__.py
  17. 8
      couchpotato/core/downloaders/nzbvortex/main.py
  18. 1
      couchpotato/core/downloaders/pneumatic/__init__.py
  19. 12
      couchpotato/core/downloaders/pneumatic/main.py
  20. 1
      couchpotato/core/downloaders/rtorrent/__init__.py
  21. 1
      couchpotato/core/downloaders/rtorrent/main.py
  22. 1
      couchpotato/core/downloaders/sabnzbd/__init__.py
  23. 1
      couchpotato/core/downloaders/synology/__init__.py
  24. 1
      couchpotato/core/downloaders/synology/main.py
  25. 1
      couchpotato/core/downloaders/transmission/__init__.py
  26. 1
      couchpotato/core/downloaders/utorrent/__init__.py
  27. 18
      couchpotato/core/event.py
  28. 14
      couchpotato/core/helpers/encoding.py
  29. 1
      couchpotato/core/helpers/request.py
  30. 3
      couchpotato/core/helpers/rss.py
  31. 42
      couchpotato/core/helpers/variable.py
  32. 3
      couchpotato/core/logger.py
  33. 4
      couchpotato/core/media/__init__.py
  34. 1
      couchpotato/core/media/_base/media/__init__.py
  35. 3
      couchpotato/core/media/_base/media/main.py
  36. 1
      couchpotato/core/media/_base/search/__init__.py
  37. 1
      couchpotato/core/media/_base/searcher/__init__.py
  38. 2
      couchpotato/core/media/_base/searcher/base.py
  39. 1
      couchpotato/core/media/movie/_base/__init__.py
  40. 1
      couchpotato/core/media/movie/_base/main.py
  41. 1
      couchpotato/core/media/movie/library/movie/__init__.py
  42. 2
      couchpotato/core/media/movie/library/movie/main.py
  43. 1
      couchpotato/core/media/movie/searcher/__init__.py
  44. 4
      couchpotato/core/media/movie/searcher/main.py
  45. 1
      couchpotato/core/media/movie/suggestion/__init__.py
  46. 1
      couchpotato/core/migration/versions/002_Movie_category.py
  47. 1
      couchpotato/core/notifications/boxcar/__init__.py
  48. 1
      couchpotato/core/notifications/core/__init__.py
  49. 1
      couchpotato/core/notifications/core/main.py
  50. 1
      couchpotato/core/notifications/email/__init__.py
  51. 2
      couchpotato/core/notifications/email/main.py
  52. 1
      couchpotato/core/notifications/growl/__init__.py
  53. 2
      couchpotato/core/notifications/growl/main.py
  54. 1
      couchpotato/core/notifications/nmj/__init__.py
  55. 7
      couchpotato/core/notifications/nmj/main.py
  56. 1
      couchpotato/core/notifications/notifymyandroid/__init__.py
  57. 1
      couchpotato/core/notifications/notifymywp/__init__.py
  58. 3
      couchpotato/core/notifications/notifymywp/main.py
  59. 1
      couchpotato/core/notifications/plex/__init__.py
  60. 7
      couchpotato/core/notifications/plex/main.py
  61. 1
      couchpotato/core/notifications/prowl/__init__.py
  62. 1
      couchpotato/core/notifications/pushalot/__init__.py
  63. 1
      couchpotato/core/notifications/pushalot/main.py
  64. 1
      couchpotato/core/notifications/pushbullet/__init__.py
  65. 1
      couchpotato/core/notifications/pushover/__init__.py
  66. 1
      couchpotato/core/notifications/synoindex/__init__.py
  67. 2
      couchpotato/core/notifications/synoindex/main.py
  68. 1
      couchpotato/core/notifications/toasty/__init__.py
  69. 1
      couchpotato/core/notifications/toasty/main.py
  70. 1
      couchpotato/core/notifications/trakt/__init__.py
  71. 1
      couchpotato/core/notifications/trakt/main.py
  72. 1
      couchpotato/core/notifications/twitter/__init__.py
  73. 2
      couchpotato/core/notifications/twitter/main.py
  74. 1
      couchpotato/core/notifications/xbmc/__init__.py
  75. 3
      couchpotato/core/notifications/xbmc/main.py
  76. 1
      couchpotato/core/notifications/xmpp/__init__.py
  77. 1
      couchpotato/core/plugins/automation/__init__.py
  78. 9
      couchpotato/core/plugins/base.py
  79. 1
      couchpotato/core/plugins/browser/__init__.py
  80. 1
      couchpotato/core/plugins/category/__init__.py
  81. 2
      couchpotato/core/plugins/category/main.py
  82. 1
      couchpotato/core/plugins/custom/__init__.py
  83. 1
      couchpotato/core/plugins/dashboard/__init__.py
  84. 2
      couchpotato/core/plugins/dashboard/main.py
  85. 1
      couchpotato/core/plugins/file/__init__.py
  86. 1
      couchpotato/core/plugins/file/main.py
  87. 1
      couchpotato/core/plugins/log/__init__.py
  88. 2
      couchpotato/core/plugins/log/main.py
  89. 1
      couchpotato/core/plugins/manage/__init__.py
  90. 1
      couchpotato/core/plugins/manage/main.py
  91. 1
      couchpotato/core/plugins/profile/__init__.py
  92. 2
      couchpotato/core/plugins/profile/main.py
  93. 1
      couchpotato/core/plugins/quality/__init__.py
  94. 1
      couchpotato/core/plugins/release/__init__.py
  95. 15
      couchpotato/core/plugins/release/main.py
  96. 4
      couchpotato/core/plugins/renamer/__init__.py
  97. 13
      couchpotato/core/plugins/renamer/main.py
  98. 1
      couchpotato/core/plugins/scanner/__init__.py
  99. 6
      couchpotato/core/plugins/scanner/main.py
  100. 1
      couchpotato/core/plugins/score/__init__.py

8
CouchPotato.py

@ -132,14 +132,14 @@ if __name__ == '__main__':
pass pass
except SystemExit: except SystemExit:
raise raise
except socket.error as (nr, msg): except socket.error as e:
# log when socket receives SIGINT, but continue. # log when socket receives SIGINT, but continue.
# previous code would have skipped over other types of IO errors too. # previous code would have skipped over other types of IO errors too.
if nr != 4: if nr != 4:
try: try:
l.log.critical(traceback.format_exc()) l.log.critical(traceback.format_exc())
except: except:
print traceback.format_exc() print(traceback.format_exc())
raise raise
except: except:
try: try:
@ -148,7 +148,7 @@ if __name__ == '__main__':
if l: if l:
l.log.critical(traceback.format_exc()) l.log.critical(traceback.format_exc())
else: else:
print traceback.format_exc() print(traceback.format_exc())
except: except:
print traceback.format_exc() print(traceback.format_exc())
raise raise

26
couchpotato/__init__.py

@ -9,13 +9,12 @@ import os
import time import time
import traceback import traceback
log = CPLog(__name__)
log = CPLog(__name__)
views = {} views = {}
template_loader = template.Loader(os.path.join(os.path.dirname(__file__), 'templates')) template_loader = template.Loader(os.path.join(os.path.dirname(__file__), 'templates'))
class BaseHandler(RequestHandler): class BaseHandler(RequestHandler):
def get_current_user(self): def get_current_user(self):
@ -27,6 +26,7 @@ class BaseHandler(RequestHandler):
else: # Login when no username or password are set else: # Login when no username or password are set
return True return True
# Main web handler # Main web handler
class WebHandler(BaseHandler): class WebHandler(BaseHandler):
@ -43,9 +43,11 @@ class WebHandler(BaseHandler):
log.error("Failed doing web request '%s': %s", (route, traceback.format_exc())) log.error("Failed doing web request '%s': %s", (route, traceback.format_exc()))
self.write({'success': False, 'error': 'Failed returning results'}) self.write({'success': False, 'error': 'Failed returning results'})
def addView(route, func, static = False): def addView(route, func, static = False):
views[route] = func views[route] = func
def get_session(engine = None): def get_session(engine = None):
return Env.getSession(engine) return Env.getSession(engine)
@ -55,6 +57,7 @@ def index():
return template_loader.load('index.html').generate(sep = os.sep, fireEvent = fireEvent, Env = Env) return template_loader.load('index.html').generate(sep = os.sep, fireEvent = fireEvent, Env = Env)
addView('', index) addView('', index)
# API docs # API docs
def apiDocs(): def apiDocs():
routes = [] routes = []
@ -70,21 +73,22 @@ def apiDocs():
addView('docs', apiDocs) addView('docs', apiDocs)
# Make non basic auth option to get api key # Make non basic auth option to get api key
class KeyHandler(RequestHandler): class KeyHandler(RequestHandler):
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
api = None api_key = None
try: try:
username = Env.setting('username') username = Env.setting('username')
password = Env.setting('password') password = Env.setting('password')
if (self.get_argument('u') == md5(username) or not username) and (self.get_argument('p') == password or not password): if (self.get_argument('u') == md5(username) or not username) and (self.get_argument('p') == password or not password):
api = Env.setting('api_key') api_key = Env.setting('api_key')
self.write({ self.write({
'success': api is not None, 'success': api_key is not None,
'api_key': api 'api_key': api_key
}) })
except: except:
log.error('Failed doing key request: %s', (traceback.format_exc())) log.error('Failed doing key request: %s', (traceback.format_exc()))
@ -102,20 +106,21 @@ class LoginHandler(BaseHandler):
def post(self, *args, **kwargs): def post(self, *args, **kwargs):
api = None api_key = None
username = Env.setting('username') username = Env.setting('username')
password = Env.setting('password') password = Env.setting('password')
if (self.get_argument('username') == username or not username) and (md5(self.get_argument('password')) == password or not password): if (self.get_argument('username') == username or not username) and (md5(self.get_argument('password')) == password or not password):
api = Env.setting('api_key') api_key = Env.setting('api_key')
if api: if api_key:
remember_me = tryInt(self.get_argument('remember_me', default = 0)) remember_me = tryInt(self.get_argument('remember_me', default = 0))
self.set_secure_cookie('user', api, expires_days = 30 if remember_me > 0 else None) self.set_secure_cookie('user', api_key, expires_days = 30 if remember_me > 0 else None)
self.redirect(Env.get('web_base')) self.redirect(Env.get('web_base'))
class LogoutHandler(BaseHandler): class LogoutHandler(BaseHandler):
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
@ -136,4 +141,3 @@ def page_not_found(rh):
rh.set_status(404) rh.set_status(404)
rh.write('Wrong API key used') rh.write('Wrong API key used')

10
couchpotato/api.py

@ -20,6 +20,7 @@ api_nonblock = {}
api_docs = {} api_docs = {}
api_docs_missing = [] api_docs_missing = []
def run_async(func): def run_async(func):
@wraps(func) @wraps(func)
def async_func(*args, **kwargs): def async_func(*args, **kwargs):
@ -29,6 +30,7 @@ def run_async(func):
return async_func return async_func
# NonBlock API handler # NonBlock API handler
class NonBlockHandler(RequestHandler): class NonBlockHandler(RequestHandler):
@ -61,6 +63,7 @@ class NonBlockHandler(RequestHandler):
self.stopper = None self.stopper = None
def addNonBlockApiView(route, func_tuple, docs = None, **kwargs): def addNonBlockApiView(route, func_tuple, docs = None, **kwargs):
api_nonblock[route] = func_tuple api_nonblock[route] = func_tuple
@ -69,6 +72,7 @@ def addNonBlockApiView(route, func_tuple, docs = None, **kwargs):
else: else:
api_docs_missing.append(route) api_docs_missing.append(route)
# Blocking API handler # Blocking API handler
class ApiHandler(RequestHandler): class ApiHandler(RequestHandler):
@ -98,11 +102,12 @@ class ApiHandler(RequestHandler):
@run_async @run_async
def run_handler(callback): def run_handler(callback):
try: try:
result = api[route](**kwargs) res = api[route](**kwargs)
callback(result) callback(res)
except: except:
log.error('Failed doing api request "%s": %s', (route, traceback.format_exc())) log.error('Failed doing api request "%s": %s', (route, traceback.format_exc()))
callback({'success': False, 'error': 'Failed returning results'}) callback({'success': False, 'error': 'Failed returning results'})
result = yield tornado.gen.Task(run_handler) result = yield tornado.gen.Task(run_handler)
# Check JSONP callback # Check JSONP callback
@ -122,6 +127,7 @@ class ApiHandler(RequestHandler):
api_locks[route].release() api_locks[route].release()
def addApiView(route, func, static = False, docs = None, **kwargs): def addApiView(route, func, static = False, docs = None, **kwargs):
if static: func(route) if static: func(route)

1
couchpotato/core/_base/_core/__init__.py

@ -1,6 +1,7 @@
from .main import Core from .main import Core
from uuid import uuid4 from uuid import uuid4
def start(): def start():
return Core() return Core()

1
couchpotato/core/_base/clientscript/__init__.py

@ -1,5 +1,6 @@
from .main import ClientScript from .main import ClientScript
def start(): def start():
return ClientScript() return ClientScript()

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

@ -53,9 +53,9 @@ class ClientScript(Plugin):
} }
urls = {'style': {}, 'script': {}, } urls = {'style': {}, 'script': {}}
minified = {'style': {}, 'script': {}, } minified = {'style': {}, 'script': {}}
paths = {'style': {}, 'script': {}, } paths = {'style': {}, 'script': {}}
comment = { comment = {
'style': '/*** %s:%d ***/\n', 'style': '/*** %s:%d ***/\n',
'script': '// %s:%d\n' 'script': '// %s:%d\n'

1
couchpotato/core/_base/desktop/__init__.py

@ -1,5 +1,6 @@
from .main import Desktop from .main import Desktop
def start(): def start():
return Desktop() return Desktop()

1
couchpotato/core/_base/scheduler/__init__.py

@ -1,5 +1,6 @@
from .main import Scheduler from .main import Scheduler
def start(): def start():
return Scheduler() return Scheduler()

1
couchpotato/core/_base/updater/__init__.py

@ -2,6 +2,7 @@ from .main import Updater
from couchpotato.environment import Env from couchpotato.environment import Env
import os import os
def start(): def start():
return Updater() return Updater()

16
couchpotato/core/_base/updater/main.py

@ -151,6 +151,9 @@ class BaseUpdater(Plugin):
'branch': self.branch, 'branch': self.branch,
} }
def getVersion(self):
pass
def check(self): def check(self):
pass pass
@ -179,7 +182,6 @@ class BaseUpdater(Plugin):
log.error('Couldn\'t remove empty directory %s: %s', (full_path, traceback.format_exc())) log.error('Couldn\'t remove empty directory %s: %s', (full_path, traceback.format_exc()))
class GitUpdater(BaseUpdater): class GitUpdater(BaseUpdater):
def __init__(self, git_command): def __init__(self, git_command):
@ -214,7 +216,7 @@ class GitUpdater(BaseUpdater):
'date': output.getDate(), 'date': output.getDate(),
'type': 'git', 'type': 'git',
} }
except Exception, e: except Exception as e:
log.error('Failed using GIT updater, running from source, you need to have GIT installed. %s', e) log.error('Failed using GIT updater, running from source, you need to have GIT installed. %s', e)
return 'No GIT' return 'No GIT'
@ -250,7 +252,6 @@ class GitUpdater(BaseUpdater):
return False return False
class SourceUpdater(BaseUpdater): class SourceUpdater(BaseUpdater):
def __init__(self): def __init__(self):
@ -276,9 +277,9 @@ class SourceUpdater(BaseUpdater):
# Extract # Extract
if download_data.get('type') == 'zip': if download_data.get('type') == 'zip':
zip = zipfile.ZipFile(destination) zip_file = zipfile.ZipFile(destination)
zip.extractall(extracted_path) zip_file.extractall(extracted_path)
zip.close() zip_file.close()
else: else:
tar = tarfile.open(destination) tar = tarfile.open(destination)
tar.extractall(path = extracted_path) tar.extractall(path = extracted_path)
@ -345,7 +346,6 @@ class SourceUpdater(BaseUpdater):
return True return True
def removeDir(self, path): def removeDir(self, path):
try: try:
if os.path.isdir(path): if os.path.isdir(path):
@ -366,7 +366,7 @@ class SourceUpdater(BaseUpdater):
self.version = output self.version = output
self.version['type'] = 'source' self.version['type'] = 'source'
self.version['repr'] = 'source:(%s:%s % s) %s (%s)' % (self.repo_user, self.repo_name, self.branch, output.get('hash', '')[:8], datetime.fromtimestamp(output.get('date', 0))) self.version['repr'] = 'source:(%s:%s % s) %s (%s)' % (self.repo_user, self.repo_name, self.branch, output.get('hash', '')[:8], datetime.fromtimestamp(output.get('date', 0)))
except Exception, e: except Exception as e:
log.error('Failed using source updater. %s', e) log.error('Failed using source updater. %s', e)
return {} return {}

1
couchpotato/core/downloaders/blackhole/__init__.py

@ -1,6 +1,7 @@
from .main import Blackhole from .main import Blackhole
from couchpotato.core.helpers.variable import getDownloadDir from couchpotato.core.helpers.variable import getDownloadDir
def start(): def start():
return Blackhole() return Blackhole()

1
couchpotato/core/downloaders/deluge/__init__.py

@ -1,5 +1,6 @@
from .main import Deluge from .main import Deluge
def start(): def start():
return Deluge() return Deluge()

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

@ -157,6 +157,7 @@ class Deluge(Downloader):
log.debug('Requesting Deluge to remove the torrent %s%s.', (release_download['name'], ' and cleanup the downloaded files' if delete_files else '')) log.debug('Requesting Deluge to remove the torrent %s%s.', (release_download['name'], ' and cleanup the downloaded files' if delete_files else ''))
return self.drpc.remove_torrent(release_download['id'], remove_local_data = delete_files) return self.drpc.remove_torrent(release_download['id'], remove_local_data = delete_files)
class DelugeRPC(object): class DelugeRPC(object):
host = 'localhost' host = 'localhost'

1
couchpotato/core/downloaders/nzbget/__init__.py

@ -1,5 +1,6 @@
from .main import NZBGet from .main import NZBGet
def start(): def start():
return NZBGet() return NZBGet()

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

@ -42,7 +42,7 @@ class NZBGet(Downloader):
except socket.error: except socket.error:
log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.') log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.')
return False return False
except xmlrpclib.ProtocolError, e: except xmlrpclib.ProtocolError as e:
if e.errcode == 401: if e.errcode == 401:
log.error('Password is incorrect.') log.error('Password is incorrect.')
else: else:
@ -83,7 +83,7 @@ class NZBGet(Downloader):
except socket.error: except socket.error:
log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.') log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.')
return [] return []
except xmlrpclib.ProtocolError, e: except xmlrpclib.ProtocolError as e:
if e.errcode == 401: if e.errcode == 401:
log.error('Password is incorrect.') log.error('Password is incorrect.')
else: else:
@ -169,7 +169,7 @@ class NZBGet(Downloader):
except socket.error: except socket.error:
log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.') log.error('NZBGet is not responding. Please ensure that NZBGet is running and host setting is correct.')
return False return False
except xmlrpclib.ProtocolError, e: except xmlrpclib.ProtocolError as e:
if e.errcode == 401: if e.errcode == 401:
log.error('Password is incorrect.') log.error('Password is incorrect.')
else: else:

1
couchpotato/core/downloaders/nzbvortex/__init__.py

@ -1,5 +1,6 @@
from .main import NZBVortex from .main import NZBVortex
def start(): def start():
return NZBVortex() return NZBVortex()

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

@ -62,7 +62,7 @@ class NZBVortex(Downloader):
'name': nzb['uiTitle'], 'name': nzb['uiTitle'],
'status': status, 'status': status,
'original_status': nzb['state'], 'original_status': nzb['state'],
'timeleft':-1, 'timeleft': -1,
'folder': sp(nzb['destinationPath']), 'folder': sp(nzb['destinationPath']),
}) })
@ -102,7 +102,6 @@ class NZBVortex(Downloader):
log.error('Login failed, please check you api-key') log.error('Login failed, please check you api-key')
return False return False
def call(self, call, parameters = None, repeat = False, auth = True, *args, **kwargs): def call(self, call, parameters = None, repeat = False, auth = True, *args, **kwargs):
# Login first # Login first
@ -123,7 +122,7 @@ class NZBVortex(Downloader):
if data: if data:
return json.loads(data) return json.loads(data)
except URLError, e: except URLError as e:
if hasattr(e, 'code') and e.code == 403: if hasattr(e, 'code') and e.code == 403:
# Try login and do again # Try login and do again
if not repeat: if not repeat:
@ -145,7 +144,7 @@ class NZBVortex(Downloader):
try: try:
data = self.urlopen(url, show_error = False) data = self.urlopen(url, show_error = False)
self.api_level = float(json.loads(data).get('apilevel')) self.api_level = float(json.loads(data).get('apilevel'))
except URLError, e: except URLError as e:
if hasattr(e, 'code') and e.code == 403: if hasattr(e, 'code') and e.code == 403:
log.error('This version of NZBVortex isn\'t supported. Please update to 2.8.6 or higher') log.error('This version of NZBVortex isn\'t supported. Please update to 2.8.6 or higher')
else: else:
@ -175,6 +174,7 @@ class HTTPSConnection(httplib.HTTPSConnection):
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version = ssl.PROTOCOL_TLSv1) self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version = ssl.PROTOCOL_TLSv1)
class HTTPSHandler(urllib2.HTTPSHandler): class HTTPSHandler(urllib2.HTTPSHandler):
def https_open(self, req): def https_open(self, req):
return self.do_open(HTTPSConnection, req) return self.do_open(HTTPSConnection, req)

1
couchpotato/core/downloaders/pneumatic/__init__.py

@ -1,5 +1,6 @@
from .main import Pneumatic from .main import Pneumatic
def start(): def start():
return Pneumatic() return Pneumatic()

12
couchpotato/core/downloaders/pneumatic/main.py

@ -26,26 +26,26 @@ class Pneumatic(Downloader):
log.error('No nzb available!') log.error('No nzb available!')
return False return False
fullPath = os.path.join(directory, self.createFileName(data, filedata, media)) full_path = os.path.join(directory, self.createFileName(data, filedata, media))
try: try:
if not os.path.isfile(fullPath): if not os.path.isfile(full_path):
log.info('Downloading %s to %s.', (data.get('protocol'), fullPath)) log.info('Downloading %s to %s.', (data.get('protocol'), full_path))
with open(fullPath, 'wb') as f: with open(full_path, 'wb') as f:
f.write(filedata) f.write(filedata)
nzb_name = self.createNzbName(data, media) nzb_name = self.createNzbName(data, media)
strm_path = os.path.join(directory, nzb_name) strm_path = os.path.join(directory, nzb_name)
strm_file = open(strm_path + '.strm', 'wb') strm_file = open(strm_path + '.strm', 'wb')
strmContent = self.strm_syntax % (fullPath, nzb_name) strmContent = self.strm_syntax % (full_path, nzb_name)
strm_file.write(strmContent) strm_file.write(strmContent)
strm_file.close() strm_file.close()
return self.downloadReturnId('') return self.downloadReturnId('')
else: else:
log.info('File %s already exists.', fullPath) log.info('File %s already exists.', full_path)
return self.downloadReturnId('') return self.downloadReturnId('')
except: except:

1
couchpotato/core/downloaders/rtorrent/__init__.py

@ -1,5 +1,6 @@
from .main import rTorrent from .main import rTorrent
def start(): def start():
return rTorrent() return rTorrent()

1
couchpotato/core/downloaders/rtorrent/main.py

@ -111,7 +111,6 @@ class rTorrent(Downloader):
if self.conf('label'): if self.conf('label'):
torrent_params['label'] = self.conf('label') torrent_params['label'] = self.conf('label')
if not filedata and data.get('protocol') == 'torrent': if not filedata and data.get('protocol') == 'torrent':
log.error('Failed sending torrent, no data') log.error('Failed sending torrent, no data')
return False return False

1
couchpotato/core/downloaders/sabnzbd/__init__.py

@ -1,5 +1,6 @@
from .main import Sabnzbd from .main import Sabnzbd
def start(): def start():
return Sabnzbd() return Sabnzbd()

1
couchpotato/core/downloaders/synology/__init__.py

@ -1,5 +1,6 @@
from .main import Synology from .main import Synology
def start(): def start():
return Synology() return Synology()

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

@ -65,6 +65,7 @@ class Synology(Downloader):
return super(Synology, self).isEnabled(manual, data) and\ return super(Synology, self).isEnabled(manual, data) and\
((self.conf('use_for') in for_protocol)) ((self.conf('use_for') in for_protocol))
class SynologyRPC(object): class SynologyRPC(object):
"""SynologyRPC lite library""" """SynologyRPC lite library"""

1
couchpotato/core/downloaders/transmission/__init__.py

@ -1,5 +1,6 @@
from .main import Transmission from .main import Transmission
def start(): def start():
return Transmission() return Transmission()

1
couchpotato/core/downloaders/utorrent/__init__.py

@ -1,5 +1,6 @@
from .main import uTorrent from .main import uTorrent
def start(): def start():
return uTorrent() return uTorrent()

18
couchpotato/core/event.py

@ -7,6 +7,7 @@ import traceback
log = CPLog(__name__) log = CPLog(__name__)
events = {} events = {}
def runHandler(name, handler, *args, **kwargs): def runHandler(name, handler, *args, **kwargs):
try: try:
return handler(*args, **kwargs) return handler(*args, **kwargs)
@ -14,6 +15,7 @@ def runHandler(name, handler, *args, **kwargs):
from couchpotato.environment import Env from couchpotato.environment import Env
log.error('Error in event "%s", that wasn\'t caught: %s%s', (name, traceback.format_exc(), Env.all() if not Env.get('dev') else '')) log.error('Error in event "%s", that wasn\'t caught: %s%s', (name, traceback.format_exc(), Env.all() if not Env.get('dev') else ''))
def addEvent(name, handler, priority = 100): def addEvent(name, handler, priority = 100):
if not events.get(name): if not events.get(name):
@ -48,12 +50,14 @@ def addEvent(name, handler, priority = 100):
'priority': priority, 'priority': priority,
}) })
def removeEvent(name, handler): def removeEvent(name, handler):
e = events[name] e = events[name]
e -= handler e -= handler
def fireEvent(name, *args, **kwargs): def fireEvent(name, *args, **kwargs):
if not events.has_key(name): return if name not in events: return
#log.debug('Firing event %s', name) #log.debug('Firing event %s', name)
try: try:
@ -101,11 +105,14 @@ def fireEvent(name, *args, **kwargs):
# Fire # Fire
result = e(*args, **kwargs) result = e(*args, **kwargs)
result_keys = result.keys()
result_keys.sort(natcmp)
if options['single'] and not options['merge']: if options['single'] and not options['merge']:
results = None results = None
# Loop over results, stop when first not None result is found. # Loop over results, stop when first not None result is found.
for r_key in sorted(result.iterkeys(), cmp = natcmp): for r_key in result_keys:
r = result[r_key] r = result[r_key]
if r[0] is True and r[1] is not None: if r[0] is True and r[1] is not None:
results = r[1] results = r[1]
@ -117,7 +124,7 @@ def fireEvent(name, *args, **kwargs):
else: else:
results = [] results = []
for r_key in sorted(result.iterkeys(), cmp = natcmp): for r_key in result_keys:
r = result[r_key] r = result[r_key]
if r[0] == True and r[1]: if r[0] == True and r[1]:
results.append(r[1]) results.append(r[1])
@ -160,18 +167,21 @@ def fireEvent(name, *args, **kwargs):
except Exception: except Exception:
log.error('%s: %s', (name, traceback.format_exc())) log.error('%s: %s', (name, traceback.format_exc()))
def fireEventAsync(*args, **kwargs): def fireEventAsync(*args, **kwargs):
try: try:
t = threading.Thread(target = fireEvent, args = args, kwargs = kwargs) t = threading.Thread(target = fireEvent, args = args, kwargs = kwargs)
t.setDaemon(True) t.setDaemon(True)
t.start() t.start()
return True return True
except Exception, e: except Exception as e:
log.error('%s: %s', (args[0], e)) log.error('%s: %s', (args[0], e))
def errorHandler(error): def errorHandler(error):
etype, value, tb = error etype, value, tb = error
log.error(''.join(traceback.format_exception(etype, value, tb))) log.error(''.join(traceback.format_exception(etype, value, tb)))
def getEvent(name): def getEvent(name):
return events[name] return events[name]

14
couchpotato/core/helpers/encoding.py

@ -11,16 +11,18 @@ log = CPLog(__name__)
def toSafeString(original): def toSafeString(original):
valid_chars = "-_.() %s%s" % (ascii_letters, digits) valid_chars = "-_.() %s%s" % (ascii_letters, digits)
cleanedFilename = unicodedata.normalize('NFKD', toUnicode(original)).encode('ASCII', 'ignore') cleaned_filename = unicodedata.normalize('NFKD', toUnicode(original)).encode('ASCII', 'ignore')
valid_string = ''.join(c for c in cleanedFilename if c in valid_chars) valid_string = ''.join(c for c in cleaned_filename if c in valid_chars)
return ' '.join(valid_string.split()) return ' '.join(valid_string.split())
def simplifyString(original): def simplifyString(original):
string = stripAccents(original.lower()) string = stripAccents(original.lower())
string = toSafeString(' '.join(re.split('\W+', string))) string = toSafeString(' '.join(re.split('\W+', string)))
split = re.split('\W+|_', string.lower()) split = re.split('\W+|_', string.lower())
return toUnicode(' '.join(split)) return toUnicode(' '.join(split))
def toUnicode(original, *args): def toUnicode(original, *args):
try: try:
if isinstance(original, unicode): if isinstance(original, unicode):
@ -38,16 +40,18 @@ def toUnicode(original, *args):
ascii_text = str(original).encode('string_escape') ascii_text = str(original).encode('string_escape')
return toUnicode(ascii_text) return toUnicode(ascii_text)
def ss(original, *args): def ss(original, *args):
u_original = toUnicode(original, *args) u_original = toUnicode(original, *args)
try: try:
from couchpotato.environment import Env from couchpotato.environment import Env
return u_original.encode(Env.get('encoding')) return u_original.encode(Env.get('encoding'))
except Exception, e: except Exception as e:
log.debug('Failed ss encoding char, force UTF8: %s', e) log.debug('Failed ss encoding char, force UTF8: %s', e)
return u_original.encode('UTF-8') return u_original.encode('UTF-8')
def sp(path, *args): def sp(path, *args):
# Standardise encoding, normalise case, path and strip trailing '/' or '\' # Standardise encoding, normalise case, path and strip trailing '/' or '\'
@ -73,6 +77,7 @@ def sp(path, *args):
return path return path
def ek(original, *args): def ek(original, *args):
if isinstance(original, (str, unicode)): if isinstance(original, (str, unicode)):
try: try:
@ -83,6 +88,7 @@ def ek(original, *args):
return original return original
def isInt(value): def isInt(value):
try: try:
int(value) int(value)
@ -90,9 +96,11 @@ def isInt(value):
except ValueError: except ValueError:
return False return False
def stripAccents(s): def stripAccents(s):
return ''.join((c for c in unicodedata.normalize('NFD', toUnicode(s)) if unicodedata.category(c) != 'Mn')) return ''.join((c for c in unicodedata.normalize('NFD', toUnicode(s)) if unicodedata.category(c) != 'Mn'))
def tryUrlencode(s): def tryUrlencode(s):
new = u'' new = u''
if isinstance(s, dict): if isinstance(s, dict):

1
couchpotato/core/helpers/request.py

@ -37,6 +37,7 @@ def getParams(params):
return dictToList(temp) return dictToList(temp)
def dictToList(params): def dictToList(params):
if type(params) is dict: if type(params) is dict:

3
couchpotato/core/helpers/rss.py

@ -3,6 +3,7 @@ import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
class RSS(object): class RSS(object):
def getTextElements(self, xml, path): def getTextElements(self, xml, path):
@ -46,6 +47,6 @@ class RSS(object):
def getItems(self, data, path = 'channel/item'): def getItems(self, data, path = 'channel/item'):
try: try:
return XMLTree.parse(data).findall(path) return XMLTree.parse(data).findall(path)
except Exception, e: except Exception as e:
log.error('Error parsing RSS. %s', e) log.error('Error parsing RSS. %s', e)
return [] return []

42
couchpotato/core/helpers/variable.py

@ -11,8 +11,10 @@ import sys
log = CPLog(__name__) log = CPLog(__name__)
def fnEscape(pattern): def fnEscape(pattern):
return pattern.replace('[','[[').replace(']','[]]').replace('[[','[[]') return pattern.replace('[', '[[').replace(']', '[]]').replace('[[', '[[]')
def link(src, dst): def link(src, dst):
if os.name == 'nt': if os.name == 'nt':
@ -21,6 +23,7 @@ def link(src, dst):
else: else:
os.link(src, dst) os.link(src, dst)
def symlink(src, dst): def symlink(src, dst):
if os.name == 'nt': if os.name == 'nt':
import ctypes import ctypes
@ -28,6 +31,7 @@ def symlink(src, dst):
else: else:
os.symlink(src, dst) os.symlink(src, dst)
def getUserDir(): def getUserDir():
try: try:
import pwd import pwd
@ -37,6 +41,7 @@ def getUserDir():
return os.path.expanduser('~') return os.path.expanduser('~')
def getDownloadDir(): def getDownloadDir():
user_dir = getUserDir() user_dir = getUserDir()
@ -49,6 +54,7 @@ def getDownloadDir():
return user_dir return user_dir
def getDataDir(): def getDataDir():
# Windows # Windows
@ -68,8 +74,10 @@ def getDataDir():
# Linux # Linux
return os.path.join(user_dir, '.couchpotato') return os.path.join(user_dir, '.couchpotato')
def isDict(object):
return isinstance(object, dict) def isDict(obj):
return isinstance(obj, dict)
def mergeDicts(a, b, prepend_list = False): def mergeDicts(a, b, prepend_list = False):
assert isDict(a), isDict(b) assert isDict(a), isDict(b)
@ -91,6 +99,7 @@ def mergeDicts(a, b, prepend_list = False):
current_dst[key] = current_src[key] current_dst[key] = current_src[key]
return dst return dst
def removeListDuplicates(seq): def removeListDuplicates(seq):
checked = [] checked = []
for e in seq: for e in seq:
@ -98,26 +107,32 @@ def removeListDuplicates(seq):
checked.append(e) checked.append(e)
return checked return checked
def flattenList(l): def flattenList(l):
if isinstance(l, list): if isinstance(l, list):
return sum(map(flattenList, l)) return sum(map(flattenList, l))
else: else:
return l return l
def md5(text): def md5(text):
return hashlib.md5(ss(text)).hexdigest() return hashlib.md5(ss(text)).hexdigest()
def sha1(text): def sha1(text):
return hashlib.sha1(text).hexdigest() return hashlib.sha1(text).hexdigest()
def isLocalIP(ip): def isLocalIP(ip):
ip = ip.lstrip('htps:/') ip = ip.lstrip('htps:/')
regex = '/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1)$/' regex = '/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1)$/'
return re.search(regex, ip) is not None or 'localhost' in ip or ip[:4] == '127.' return re.search(regex, ip) is not None or 'localhost' in ip or ip[:4] == '127.'
def getExt(filename): def getExt(filename):
return os.path.splitext(filename)[1][1:] return os.path.splitext(filename)[1][1:]
def cleanHost(host, protocol = True, ssl = False, username = None, password = None): def cleanHost(host, protocol = True, ssl = False, username = None, password = None):
if not '://' in host and protocol: if not '://' in host and protocol:
@ -137,6 +152,7 @@ def cleanHost(host, protocol = True, ssl = False, username = None, password = No
return host return host
def getImdb(txt, check_inside = False, multiple = False): def getImdb(txt, check_inside = False, multiple = False):
if not check_inside: if not check_inside:
@ -161,10 +177,12 @@ def getImdb(txt, check_inside = False, multiple = False):
return False return False
def tryInt(s, default = 0): def tryInt(s, default = 0):
try: return int(s) try: return int(s)
except: return default except: return default
def tryFloat(s): def tryFloat(s):
try: try:
if isinstance(s, str): if isinstance(s, str):
@ -173,17 +191,24 @@ def tryFloat(s):
return float(s) return float(s)
except: return 0 except: return 0
def natsortKey(s): def natsortKey(s):
return map(tryInt, re.findall(r'(\d+|\D+)', s)) return map(tryInt, re.findall(r'(\d+|\D+)', s))
def natcmp(a, b): def natcmp(a, b):
return cmp(natsortKey(a), natsortKey(b)) a2 = natsortKey(a)
b2 = natsortKey(b)
return (a2 > b2) - (a2 < b2)
def toIterable(value): def toIterable(value):
if isinstance(value, collections.Iterable): if isinstance(value, collections.Iterable):
return value return value
return [value] return [value]
def getTitle(library_dict): def getTitle(library_dict):
try: try:
try: try:
@ -206,6 +231,7 @@ def getTitle(library_dict):
log.error('Could not get title for library item: %s', library_dict) log.error('Could not get title for library item: %s', library_dict)
return None return None
def possibleTitles(raw_title): def possibleTitles(raw_title):
titles = [ titles = [
@ -220,16 +246,20 @@ def possibleTitles(raw_title):
return list(set(titles)) return list(set(titles))
def randomString(size = 8, chars = string.ascii_uppercase + string.digits): def randomString(size = 8, chars = string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for x in range(size)) return ''.join(random.choice(chars) for x in range(size))
def splitString(str, split_on = ',', clean = True): def splitString(str, split_on = ',', clean = True):
list = [x.strip() for x in str.split(split_on)] if str else [] l = [x.strip() for x in str.split(split_on)] if str else []
return filter(None, list) if clean else list return filter(None, l) if clean else l
def dictIsSubset(a, b): def dictIsSubset(a, b):
return all([k in b and b[k] == v for k, v in a.items()]) return all([k in b and b[k] == v for k, v in a.items()])
def isSubFolder(sub_folder, base_folder): def isSubFolder(sub_folder, base_folder):
# Returns True if sub_folder is the same as or inside base_folder # Returns True if sub_folder is the same as or inside base_folder
return base_folder and sub_folder and os.path.normpath(base_folder).rstrip(os.path.sep) + os.path.sep in os.path.normpath(sub_folder).rstrip(os.path.sep) + os.path.sep return base_folder and sub_folder and os.path.normpath(base_folder).rstrip(os.path.sep) + os.path.sep in os.path.normpath(sub_folder).rstrip(os.path.sep) + os.path.sep

3
couchpotato/core/logger.py

@ -1,6 +1,7 @@
import logging import logging
import re import re
class CPLog(object): class CPLog(object):
context = '' context = ''
@ -49,7 +50,7 @@ class CPLog(object):
msg = msg % tuple([ss(x) for x in list(replace_tuple)]) msg = msg % tuple([ss(x) for x in list(replace_tuple)])
else: else:
msg = msg % ss(replace_tuple) msg = msg % ss(replace_tuple)
except Exception, e: except Exception as e:
self.logger.error(u'Failed encoding stuff to log "%s": %s' % (msg, e)) self.logger.error(u'Failed encoding stuff to log "%s": %s' % (msg, e))
if not Env.get('dev'): if not Env.get('dev'):

4
couchpotato/core/media/__init__.py

@ -10,8 +10,8 @@ class MediaBase(Plugin):
default_dict = { default_dict = {
'profile': {'types': {'quality': {}}}, 'profile': {'types': {'quality': {}}},
'releases': {'status': {}, 'quality': {}, 'files':{}, 'info': {}}, 'releases': {'status': {}, 'quality': {}, 'files': {}, 'info': {}},
'library': {'titles': {}, 'files':{}}, 'library': {'titles': {}, 'files': {}},
'files': {}, 'files': {},
'status': {}, 'status': {},
'category': {}, 'category': {},

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

@ -1,5 +1,6 @@
from .main import MediaPlugin from .main import MediaPlugin
def start(): def start():
return MediaPlugin() return MediaPlugin()

3
couchpotato/core/media/_base/media/main.py

@ -102,7 +102,6 @@ class MediaPlugin(MediaBase):
def handler(): def handler():
fireEvent('library.update.%s' % media.type, identifier = identifier, default_title = default_title, force = True, on_complete = self.createOnComplete(id)) fireEvent('library.update.%s' % media.type, identifier = identifier, default_title = default_title, force = True, on_complete = self.createOnComplete(id))
return handler return handler
def addSingleRefreshView(self): def addSingleRefreshView(self):
@ -254,7 +253,7 @@ class MediaPlugin(MediaBase):
# Merge releases with movie dict # Merge releases with movie dict
movies.append(mergeDicts(movie_dict[media_id].to_dict({ movies.append(mergeDicts(movie_dict[media_id].to_dict({
'library': {'titles': {}, 'files':{}}, 'library': {'titles': {}, 'files': {}},
'files': {}, 'files': {},
}), { }), {
'releases': releases, 'releases': releases,

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

@ -1,5 +1,6 @@
from .main import Search from .main import Search
def start(): def start():
return Search() return Search()

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

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

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

@ -12,7 +12,6 @@ class SearcherBase(Plugin):
def __init__(self): def __init__(self):
super(SearcherBase, self).__init__() super(SearcherBase, self).__init__()
addEvent('searcher.progress', self.getProgress) addEvent('searcher.progress', self.getProgress)
addEvent('%s.searcher.progress' % self.getType(), self.getProgress) addEvent('%s.searcher.progress' % self.getType(), self.getProgress)
@ -26,7 +25,6 @@ class SearcherBase(Plugin):
_type = self.getType() _type = self.getType()
def setCrons(): def setCrons():
fireEvent('schedule.cron', '%s.searcher.all' % _type, self.searchAll, fireEvent('schedule.cron', '%s.searcher.all' % _type, self.searchAll,
day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute')) day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))

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

@ -1,5 +1,6 @@
from .main import MovieBase from .main import MovieBase
def start(): def start():
return MovieBase() return MovieBase()

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

@ -61,7 +61,6 @@ class MovieBase(MovieTypeBase):
except: except:
pass pass
library = fireEvent('library.add.movie', single = True, attrs = params, update_after = update_library) library = fireEvent('library.add.movie', single = True, attrs = params, update_after = update_library)
# Status # Status

1
couchpotato/core/media/movie/library/movie/__init__.py

@ -1,5 +1,6 @@
from .main import MovieLibraryPlugin from .main import MovieLibraryPlugin
def start(): def start():
return MovieLibraryPlugin() return MovieLibraryPlugin()

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

@ -13,7 +13,7 @@ log = CPLog(__name__)
class MovieLibraryPlugin(LibraryBase): class MovieLibraryPlugin(LibraryBase):
default_dict = {'titles': {}, 'files':{}} default_dict = {'titles': {}, 'files': {}}
def __init__(self): def __init__(self):
addEvent('library.add.movie', self.add) addEvent('library.add.movie', self.add)

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

@ -1,6 +1,7 @@
from .main import MovieSearcher from .main import MovieSearcher
import random import random
def start(): def start():
return MovieSearcher() return MovieSearcher()

4
couchpotato/core/media/movie/searcher/main.py

@ -91,7 +91,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
'category': {}, 'category': {},
'profile': {'types': {'quality': {}}}, 'profile': {'types': {'quality': {}}},
'releases': {'status': {}, 'quality': {}}, 'releases': {'status': {}, 'quality': {}},
'library': {'titles': {}, 'files':{}}, 'library': {'titles': {}, 'files': {}},
'files': {}, 'files': {},
}) })
@ -117,7 +117,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
def single(self, movie, search_protocols = None, manual = False): def single(self, movie, search_protocols = None, manual = False):
# movies don't contain 'type' yet, so just set to default here # movies don't contain 'type' yet, so just set to default here
if not movie.has_key('type'): if 'type' not in movie:
movie['type'] = 'movie' movie['type'] = 'movie'
# Find out search type # Find out search type

1
couchpotato/core/media/movie/suggestion/__init__.py

@ -1,5 +1,6 @@
from .main import Suggestion from .main import Suggestion
def start(): def start():
return Suggestion() return Suggestion()

1
couchpotato/core/migration/versions/002_Movie_category.py

@ -13,5 +13,6 @@ def upgrade(migrate_engine):
create_column(category_column, movie) create_column(category_column, movie)
Index('ix_movie_category_id', movie.c.category_id).create() Index('ix_movie_category_id', movie.c.category_id).create()
def downgrade(migrate_engine): def downgrade(migrate_engine):
pass pass

1
couchpotato/core/notifications/boxcar/__init__.py

@ -1,5 +1,6 @@
from .main import Boxcar from .main import Boxcar
def start(): def start():
return Boxcar() return Boxcar()

1
couchpotato/core/notifications/core/__init__.py

@ -1,5 +1,6 @@
from .main import CoreNotifier from .main import CoreNotifier
def start(): def start():
return CoreNotifier() return CoreNotifier()

1
couchpotato/core/notifications/core/main.py

@ -71,7 +71,6 @@ class CoreNotifier(Notification):
db.query(Notif).filter(Notif.added <= (int(time.time()) - 2419200)).delete() db.query(Notif).filter(Notif.added <= (int(time.time()) - 2419200)).delete()
db.commit() db.commit()
def markAsRead(self, ids = None, **kwargs): def markAsRead(self, ids = None, **kwargs):
ids = splitString(ids) if ids else None ids = splitString(ids) if ids else None

1
couchpotato/core/notifications/email/__init__.py

@ -1,5 +1,6 @@
from .main import Email from .main import Email
def start(): def start():
return Email() return Email()

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

@ -40,7 +40,7 @@ class Email(Notification):
log.debug("SMTP over SSL %s", ("enabled" if ssl == 1 else "disabled")) log.debug("SMTP over SSL %s", ("enabled" if ssl == 1 else "disabled"))
mailserver = smtplib.SMTP_SSL(smtp_server) if ssl == 1 else smtplib.SMTP(smtp_server) mailserver = smtplib.SMTP_SSL(smtp_server) if ssl == 1 else smtplib.SMTP(smtp_server)
if (starttls): if starttls:
log.debug("Using StartTLS to initiate the connection with the SMTP server") log.debug("Using StartTLS to initiate the connection with the SMTP server")
mailserver.starttls() mailserver.starttls()

1
couchpotato/core/notifications/growl/__init__.py

@ -1,5 +1,6 @@
from .main import Growl from .main import Growl
def start(): def start():
return Growl() return Growl()

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

@ -37,7 +37,7 @@ class Growl(Notification):
) )
self.growl.register() self.growl.register()
self.registered = True self.registered = True
except Exception, e: except Exception as e:
if 'timed out' in str(e): if 'timed out' in str(e):
self.registered = True self.registered = True
else: else:

1
couchpotato/core/notifications/nmj/__init__.py

@ -1,5 +1,6 @@
from .main import NMJ from .main import NMJ
def start(): def start():
return NMJ() return NMJ()

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

@ -86,18 +86,17 @@ class NMJ(Notification):
'arg3': '', 'arg3': '',
} }
params = tryUrlencode(params) params = tryUrlencode(params)
UPDATE_URL = 'http://%(host)s:8008/metadata_database?%(params)s' update_url = 'http://%(host)s:8008/metadata_database?%(params)s' % {'host': host, 'params': params}
updateUrl = UPDATE_URL % {'host': host, 'params': params}
try: try:
response = self.urlopen(updateUrl) response = self.urlopen(update_url)
except: except:
return False return False
try: try:
et = etree.fromstring(response) et = etree.fromstring(response)
result = et.findtext('returnValue') result = et.findtext('returnValue')
except SyntaxError, e: except SyntaxError as 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

1
couchpotato/core/notifications/notifymyandroid/__init__.py

@ -1,5 +1,6 @@
from .main import NotifyMyAndroid from .main import NotifyMyAndroid
def start(): def start():
return NotifyMyAndroid() return NotifyMyAndroid()

1
couchpotato/core/notifications/notifymywp/__init__.py

@ -1,5 +1,6 @@
from .main import NotifyMyWP from .main import NotifyMyWP
def start(): def start():
return NotifyMyWP() return NotifyMyWP()

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

@ -8,7 +8,8 @@ log = CPLog(__name__)
class NotifyMyWP(Notification): class NotifyMyWP(Notification):
def notify(self, message = '', data = {}, listener = None): def notify(self, message = '', data = None, listener = None):
if not data: data = {}
keys = splitString(self.conf('api_key')) keys = splitString(self.conf('api_key'))
p = PyNMWP(keys, self.conf('dev_key')) p = PyNMWP(keys, self.conf('dev_key'))

1
couchpotato/core/notifications/plex/__init__.py

@ -1,5 +1,6 @@
from .main import Plex from .main import Plex
def start(): def start():
return Plex() return Plex()

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

@ -23,9 +23,9 @@ class Plex(Notification):
addEvent('renamer.after', self.addToLibrary) addEvent('renamer.after', self.addToLibrary)
def addToLibrary(self, message = None, group = None):
def addToLibrary(self, message = None, group = {}):
if self.isDisabled(): return if self.isDisabled(): return
if not group: group = {}
return self.server.refresh() return self.server.refresh()
@ -57,7 +57,8 @@ class Plex(Notification):
return success return success
def notify(self, message = '', data = {}, listener = None): def notify(self, message = '', data = None, listener = None):
if not data: data = {}
return self.notifyClients(message, self.getClientNames()) return self.notifyClients(message, self.getClientNames())
def test(self, **kwargs): def test(self, **kwargs):

1
couchpotato/core/notifications/prowl/__init__.py

@ -1,5 +1,6 @@
from .main import Prowl from .main import Prowl
def start(): def start():
return Prowl() return Prowl()

1
couchpotato/core/notifications/pushalot/__init__.py

@ -1,5 +1,6 @@
from .main import Pushalot from .main import Pushalot
def start(): def start():
return Pushalot() return Pushalot()

1
couchpotato/core/notifications/pushalot/main.py

@ -5,6 +5,7 @@ import traceback
log = CPLog(__name__) log = CPLog(__name__)
class Pushalot(Notification): class Pushalot(Notification):
urls = { urls = {

1
couchpotato/core/notifications/pushbullet/__init__.py

@ -1,5 +1,6 @@
from .main import Pushbullet from .main import Pushbullet
def start(): def start():
return Pushbullet() return Pushbullet()

1
couchpotato/core/notifications/pushover/__init__.py

@ -1,5 +1,6 @@
from .main import Pushover from .main import Pushover
def start(): def start():
return Pushover() return Pushover()

1
couchpotato/core/notifications/synoindex/__init__.py

@ -1,5 +1,6 @@
from .main import Synoindex from .main import Synoindex
def start(): def start():
return Synoindex() return Synoindex()

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

@ -26,7 +26,7 @@ class Synoindex(Notification):
out = p.communicate() out = p.communicate()
log.info('Result from synoindex: %s', str(out)) log.info('Result from synoindex: %s', str(out))
return True return True
except OSError, e: except OSError as e:
log.error('Unable to run synoindex: %s', e) log.error('Unable to run synoindex: %s', e)
return False return False

1
couchpotato/core/notifications/toasty/__init__.py

@ -1,5 +1,6 @@
from .main import Toasty from .main import Toasty
def start(): def start():
return Toasty() return Toasty()

1
couchpotato/core/notifications/toasty/main.py

@ -5,6 +5,7 @@ import traceback
log = CPLog(__name__) log = CPLog(__name__)
class Toasty(Notification): class Toasty(Notification):
urls = { urls = {

1
couchpotato/core/notifications/trakt/__init__.py

@ -1,5 +1,6 @@
from .main import Trakt from .main import Trakt
def start(): def start():
return Trakt() return Trakt()

1
couchpotato/core/notifications/trakt/main.py

@ -3,6 +3,7 @@ from couchpotato.core.notifications.base import Notification
log = CPLog(__name__) log = CPLog(__name__)
class Trakt(Notification): class Trakt(Notification):
urls = { urls = {

1
couchpotato/core/notifications/twitter/__init__.py

@ -1,5 +1,6 @@
from .main import Twitter from .main import Twitter
def start(): def start():
return Twitter() return Twitter()

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

@ -64,7 +64,7 @@ class Twitter(Notification):
api.PostUpdate(update_message[135:] + ' 2/2') api.PostUpdate(update_message[135:] + ' 2/2')
else: else:
api.PostUpdate(update_message) api.PostUpdate(update_message)
except Exception, e: except Exception as e:
log.error('Error sending tweet: %s', e) log.error('Error sending tweet: %s', e)
return False return False

1
couchpotato/core/notifications/xbmc/__init__.py

@ -1,5 +1,6 @@
from .main import XBMC from .main import XBMC
def start(): def start():
return XBMC() return XBMC()

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

@ -1,7 +1,6 @@
from couchpotato.core.helpers.variable import splitString from couchpotato.core.helpers.variable import splitString
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 urllib2 import URLError
import base64 import base64
import json import json
import socket import socket
@ -46,7 +45,7 @@ class XBMC(Notification):
max_successful += len(calls) max_successful += len(calls)
response = self.request(host, calls) response = self.request(host, calls)
else: else:
response = self.notifyXBMCnoJSON(host, {'title':self.default_title, 'message':message}) response = self.notifyXBMCnoJSON(host, {'title': self.default_title, 'message': message})
if data and data.get('destination_dir') and (not self.conf('only_first') or hosts.index(host) == 0): if data and data.get('destination_dir') and (not self.conf('only_first') or hosts.index(host) == 0):
response += self.request(host, [('VideoLibrary.Scan', {})]) response += self.request(host, [('VideoLibrary.Scan', {})])

1
couchpotato/core/notifications/xmpp/__init__.py

@ -1,5 +1,6 @@
from .main import Xmpp from .main import Xmpp
def start(): def start():
return Xmpp() return Xmpp()

1
couchpotato/core/plugins/automation/__init__.py

@ -1,5 +1,6 @@
from .main import Automation from .main import Automation
def start(): def start():
return Automation() return Automation()

9
couchpotato/core/plugins/base.py

@ -85,7 +85,7 @@ class Plugin(object):
class_name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() class_name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
# View path # View path
path = 'static/plugin/%s/' % (class_name) path = 'static/plugin/%s/' % class_name
# Add handler to Tornado # Add handler to Tornado
Env.get('app').add_handlers(".*$", [(Env.get('web_base') + path + '(.*)', StaticFileHandler, {'path': static_folder})]) Env.get('app').add_handlers(".*$", [(Env.get('web_base') + path + '(.*)', StaticFileHandler, {'path': static_folder})])
@ -110,7 +110,7 @@ class Plugin(object):
f.write(content) f.write(content)
f.close() f.close()
os.chmod(path, Env.getPermission('file')) os.chmod(path, Env.getPermission('file'))
except Exception, e: except Exception as e:
log.error('Unable writing to file "%s": %s', (path, traceback.format_exc())) log.error('Unable writing to file "%s": %s', (path, traceback.format_exc()))
if os.path.isfile(path): if os.path.isfile(path):
os.remove(path) os.remove(path)
@ -121,7 +121,7 @@ class Plugin(object):
if not os.path.isdir(path): if not os.path.isdir(path):
os.makedirs(path, Env.getPermission('folder')) os.makedirs(path, Env.getPermission('folder'))
return True return True
except Exception, e: except Exception as e:
log.error('Unable to create folder "%s": %s', (path, e)) log.error('Unable to create folder "%s": %s', (path, e))
return False return False
@ -243,7 +243,6 @@ class Plugin(object):
except: except:
log.error("Something went wrong when finishing the plugin function. Could not find the 'is_running' key") log.error("Something went wrong when finishing the plugin function. Could not find the 'is_running' key")
def getCache(self, cache_key, url = None, **kwargs): def getCache(self, cache_key, url = None, **kwargs):
cache_key_md5 = md5(cache_key) cache_key_md5 = md5(cache_key)
cache = Env.get('cache').get(cache_key_md5) cache = Env.get('cache').get(cache_key_md5)
@ -255,7 +254,7 @@ class Plugin(object):
try: try:
cache_timeout = 300 cache_timeout = 300
if kwargs.has_key('cache_timeout'): if 'cache_timeout' in kwargs:
cache_timeout = kwargs.get('cache_timeout') cache_timeout = kwargs.get('cache_timeout')
del kwargs['cache_timeout'] del kwargs['cache_timeout']

1
couchpotato/core/plugins/browser/__init__.py

@ -1,5 +1,6 @@
from .main import FileBrowser from .main import FileBrowser
def start(): def start():
return FileBrowser() return FileBrowser()

1
couchpotato/core/plugins/category/__init__.py

@ -1,5 +1,6 @@
from .main import CategoryPlugin from .main import CategoryPlugin
def start(): def start():
return CategoryPlugin() return CategoryPlugin()

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

@ -101,7 +101,7 @@ class CategoryPlugin(Plugin):
self.removeFromMovie(id) self.removeFromMovie(id)
success = True success = True
except Exception, e: except Exception as e:
message = log.error('Failed deleting category: %s', e) message = log.error('Failed deleting category: %s', e)
db.expire_all() db.expire_all()

1
couchpotato/core/plugins/custom/__init__.py

@ -1,5 +1,6 @@
from .main import Custom from .main import Custom
def start(): def start():
return Custom() return Custom()

1
couchpotato/core/plugins/dashboard/__init__.py

@ -1,5 +1,6 @@
from .main import Dashboard from .main import Dashboard
def start(): def start():
return Dashboard() return Dashboard()

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

@ -115,7 +115,7 @@ class Dashboard(Plugin):
for movie_id in movie_ids: for movie_id in movie_ids:
movies.append(movie_dict[movie_id].to_dict({ movies.append(movie_dict[movie_id].to_dict({
'library': {'titles': {}, 'files':{}}, 'library': {'titles': {}, 'files': {}},
'files': {}, 'files': {},
})) }))

1
couchpotato/core/plugins/file/__init__.py

@ -1,5 +1,6 @@
from .main import FileManager from .main import FileManager
def start(): def start():
return FileManager() return FileManager()

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

@ -82,7 +82,6 @@ class FileManager(Plugin):
def showCacheFile(self, route, **kwargs): def showCacheFile(self, route, **kwargs):
Env.get('app').add_handlers(".*$", [('%s%s' % (Env.get('api_base'), route), StaticFileHandler, {'path': Env.get('cache_dir')})]) Env.get('app').add_handlers(".*$", [('%s%s' % (Env.get('api_base'), route), StaticFileHandler, {'path': Env.get('cache_dir')})])
def download(self, url = '', dest = None, overwrite = False, urlopen_kwargs = None): def download(self, url = '', dest = None, overwrite = False, urlopen_kwargs = None):
if not urlopen_kwargs: urlopen_kwargs = {} if not urlopen_kwargs: urlopen_kwargs = {}

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

@ -1,5 +1,6 @@
from .main import Logging from .main import Logging
def start(): def start():
return Logging() return Logging()

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

@ -42,7 +42,7 @@ class Logging(Plugin):
'desc': 'Log errors', 'desc': 'Log errors',
'params': { 'params': {
'type': {'desc': 'Type of logging, default "error"'}, 'type': {'desc': 'Type of logging, default "error"'},
'**kwargs': {'type':'object', 'desc': 'All other params will be printed in the log string.'}, '**kwargs': {'type': 'object', 'desc': 'All other params will be printed in the log string.'},
} }
}) })

1
couchpotato/core/plugins/manage/__init__.py

@ -1,5 +1,6 @@
from .main import Manage from .main import Manage
def start(): def start():
return Manage() return Manage()

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

@ -14,6 +14,7 @@ import traceback
log = CPLog(__name__) log = CPLog(__name__)
class Manage(Plugin): class Manage(Plugin):
in_progress = False in_progress = False

1
couchpotato/core/plugins/profile/__init__.py

@ -1,5 +1,6 @@
from .main import ProfilePlugin from .main import ProfilePlugin
def start(): def start():
return ProfilePlugin() return ProfilePlugin()

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

@ -149,7 +149,7 @@ class ProfilePlugin(Plugin):
self.forceDefaults() self.forceDefaults()
success = True success = True
except Exception, e: except Exception as e:
message = log.error('Failed deleting Profile: %s', e) message = log.error('Failed deleting Profile: %s', e)
db.expire_all() db.expire_all()

1
couchpotato/core/plugins/quality/__init__.py

@ -1,5 +1,6 @@
from .main import QualityPlugin from .main import QualityPlugin
def start(): def start():
return QualityPlugin() return QualityPlugin()

1
couchpotato/core/plugins/release/__init__.py

@ -1,5 +1,6 @@
from .main import Release from .main import Release
def start(): def start():
return Release() return Release()

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

@ -96,7 +96,6 @@ class Release(Plugin):
identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier']) identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier'])
done_status, snatched_status = fireEvent('status.get', ['done', 'snatched'], single = True) done_status, snatched_status = fireEvent('status.get', ['done', 'snatched'], single = True)
# Add movie # Add movie
@ -237,15 +236,15 @@ class Release(Plugin):
success = self.download(data = item, media = rel.movie.to_dict({ success = self.download(data = item, media = rel.movie.to_dict({
'profile': {'types': {'quality': {}}}, 'profile': {'types': {'quality': {}}},
'releases': {'status': {}, 'quality': {}}, 'releases': {'status': {}, 'quality': {}},
'library': {'titles': {}, 'files':{}}, 'library': {'titles': {}, 'files': {}},
'files': {} 'files': {}
}), manual = True) }), manual = True)
if success == True:
db.expunge_all() db.expunge_all()
rel = db.query(Relea).filter_by(id = id).first() # Get release again @RuudBurger why do we need to get it again??
if success:
fireEvent('notify.frontend', type = 'release.manual_download', data = True, message = 'Successfully snatched "%s"' % item['name']) fireEvent('notify.frontend', type = 'release.manual_download', data = True, message = 'Successfully snatched "%s"' % item['name'])
return { return {
'success': success == True 'success': success == True
} }
@ -317,8 +316,8 @@ class Release(Plugin):
# If renamer isn't used, mark media done if finished or release downloaded # If renamer isn't used, mark media done if finished or release downloaded
else: else:
if media['status_id'] == active_status.get('id'): if media['status_id'] == active_status.get('id'):
finished = next((True for profile_type in media['profile']['types'] if \ finished = next((True for profile_type in media['profile']['types']
profile_type['quality_id'] == rls.quality.id and profile_type['finish']), False) if profile_type['quality_id'] == rls.quality.id and profile_type['finish']), False)
if finished: if finished:
log.info('Renamer disabled, marking media as finished: %s', log_movie) log.info('Renamer disabled, marking media as finished: %s', log_movie)
@ -423,7 +422,7 @@ class Release(Plugin):
.filter(Relea.movie_id == id) \ .filter(Relea.movie_id == id) \
.all() .all()
releases = [r.to_dict({'info':{}, 'files':{}}) for r in releases_raw] releases = [r.to_dict({'info': {}, 'files': {}}) for r in releases_raw]
releases = sorted(releases, key = lambda k: k['info'].get('score', 0), reverse = True) releases = sorted(releases, key = lambda k: k['info'].get('score', 0), reverse = True)
return releases return releases
@ -449,6 +448,7 @@ class Release(Plugin):
for info in rel.info: for info in rel.info:
item[info.identifier] = info.value item[info.identifier] = info.value
release_name = None
if rel.files: if rel.files:
for file_item in rel.files: for file_item in rel.files:
if file_item.type.identifier == 'movie': if file_item.type.identifier == 'movie':
@ -456,6 +456,7 @@ class Release(Plugin):
break break
else: else:
release_name = item['name'] release_name = item['name']
#update status in Db #update status in Db
log.debug('Marking release %s as %s', (release_name, status.get("label"))) log.debug('Marking release %s as %s', (release_name, status.get("label")))
rel.status_id = status.get('id') rel.status_id = status.get('id')

4
couchpotato/core/plugins/renamer/__init__.py

@ -1,6 +1,7 @@
from couchpotato.core.plugins.renamer.main import Renamer from couchpotato.core.plugins.renamer.main import Renamer
import os import os
def start(): def start():
return Renamer() return Renamer()
@ -136,7 +137,8 @@ config = [{
'default': 'link', 'default': 'link',
'type': 'dropdown', 'type': 'dropdown',
'values': [('Link', 'link'), ('Copy', 'copy'), ('Move', 'move')], 'values': [('Link', 'link'), ('Copy', 'copy'), ('Move', 'move')],
'description': ('<strong>Link</strong>, <strong>Copy</strong> or <strong>Move</strong> after download completed.', 'Link first tries <a href="http://en.wikipedia.org/wiki/Hard_link">hard link</a>, then <a href="http://en.wikipedia.org/wiki/Sym_link">sym link</a> and falls back to Copy. It is perfered to use link when downloading torrents as it will save you space, while still beeing able to seed.'), 'description': ('<strong>Link</strong>, <strong>Copy</strong> or <strong>Move</strong> after download completed.',
'Link first tries <a href="http://en.wikipedia.org/wiki/Hard_link">hard link</a>, then <a href="http://en.wikipedia.org/wiki/Sym_link">sym link</a> and falls back to Copy. It is perfered to use link when downloading torrents as it will save you space, while still beeing able to seed.'),
'advanced': True, 'advanced': True,
}, },
{ {

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

@ -20,6 +20,7 @@ import traceback
log = CPLog(__name__) log = CPLog(__name__)
class Renamer(Plugin): class Renamer(Plugin):
renaming_started = False renaming_started = False
@ -33,7 +34,7 @@ class Renamer(Plugin):
'media_folder': {'desc': 'Optional: The folder of the media to scan. Keep empty for default renamer folder.'}, 'media_folder': {'desc': 'Optional: The folder of the media to scan. Keep empty for default renamer folder.'},
'files': {'desc': 'Optional: Provide the release files if more releases are in the same media_folder, delimited with a \'|\'. Note that no dedicated release folder is expected for releases with one file.'}, 'files': {'desc': 'Optional: Provide the release files if more releases are in the same media_folder, delimited with a \'|\'. Note that no dedicated release folder is expected for releases with one file.'},
'base_folder': {'desc': 'Optional: The folder to find releases in. Leave empty for default folder.'}, 'base_folder': {'desc': 'Optional: The folder to find releases in. Leave empty for default folder.'},
'downloader' : {'desc': 'Optional: The downloader the release has been downloaded with. \'download_id\' is required with this option.'}, 'downloader': {'desc': 'Optional: The downloader the release has been downloaded with. \'download_id\' is required with this option.'},
'download_id': {'desc': 'Optional: The nzb/torrent ID of the release in media_folder. \'downloader\' is required with this option.'}, 'download_id': {'desc': 'Optional: The nzb/torrent ID of the release in media_folder. \'downloader\' is required with this option.'},
'status': {'desc': 'Optional: The status of the release: \'completed\' (default) or \'seeding\''}, 'status': {'desc': 'Optional: The status of the release: \'completed\' (default) or \'seeding\''},
}, },
@ -434,7 +435,7 @@ class Renamer(Plugin):
movie.status_id = done_status.get('id') movie.status_id = done_status.get('id')
movie.last_edit = int(time.time()) movie.last_edit = int(time.time())
db.commit() db.commit()
except Exception, e: except Exception as e:
log.error('Failed marking movie finished: %s %s', (e, traceback.format_exc())) log.error('Failed marking movie finished: %s %s', (e, traceback.format_exc()))
# Go over current movie releases # Go over current movie releases
@ -526,7 +527,7 @@ class Renamer(Plugin):
for delete_folder in delete_folders: for delete_folder in delete_folders:
try: try:
self.deleteEmptyFolder(delete_folder, show_error = False) self.deleteEmptyFolder(delete_folder, show_error = False)
except Exception, e: except Exception as e:
log.error('Failed to delete folder: %s %s', (e, traceback.format_exc())) log.error('Failed to delete folder: %s %s', (e, traceback.format_exc()))
# Rename all files marked # Rename all files marked
@ -1160,7 +1161,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
rar_handle.extract(condition = [packedinfo.index], path = extr_path, withSubpath = False, overwrite = False) rar_handle.extract(condition = [packedinfo.index], path = extr_path, withSubpath = False, overwrite = False)
extr_files.append(sp(os.path.join(extr_path, os.path.basename(packedinfo.filename)))) extr_files.append(sp(os.path.join(extr_path, os.path.basename(packedinfo.filename))))
del rar_handle del rar_handle
except Exception, e: except Exception as e:
log.error('Failed to extract %s: %s %s', (archive['file'], e, traceback.format_exc())) log.error('Failed to extract %s: %s %s', (archive['file'], e, traceback.format_exc()))
continue continue
@ -1169,7 +1170,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
if cleanup: if cleanup:
try: try:
os.remove(filename) os.remove(filename)
except Exception, e: except Exception as e:
log.error('Failed to remove %s: %s %s', (filename, e, traceback.format_exc())) log.error('Failed to remove %s: %s %s', (filename, e, traceback.format_exc()))
continue continue
files.remove(filename) files.remove(filename)
@ -1182,7 +1183,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
try: try:
self.makeDir(os.path.dirname(move_to)) self.makeDir(os.path.dirname(move_to))
self.moveFile(leftoverfile, move_to, cleanup) self.moveFile(leftoverfile, move_to, cleanup)
except Exception, e: except Exception as e:
log.error('Failed moving left over file %s to %s: %s %s', (leftoverfile, move_to, e, traceback.format_exc())) log.error('Failed moving left over file %s to %s: %s %s', (leftoverfile, move_to, e, traceback.format_exc()))
# As we probably tried to overwrite the nfo file, check if it exists and then remove the original # As we probably tried to overwrite the nfo file, check if it exists and then remove the original
if os.path.isfile(move_to): if os.path.isfile(move_to):

1
couchpotato/core/plugins/scanner/__init__.py

@ -1,5 +1,6 @@
from .main import Scanner from .main import Scanner
def start(): def start():
return Scanner() return Scanner()

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

@ -263,7 +263,7 @@ class Scanner(Plugin):
delete_identifiers.append(identifier) delete_identifiers.append(identifier)
# Remove the found files from the leftover stack # Remove the found files from the leftover stack
leftovers = leftovers - set([ff]) leftovers -= leftovers - set([ff])
# Break if CP wants to shut down # Break if CP wants to shut down
if self.shuttingDown(): if self.shuttingDown():
@ -727,7 +727,9 @@ class Scanner(Plugin):
if is_sample: log.debug('Is sample file: %s', filename) if is_sample: log.debug('Is sample file: %s', filename)
return is_sample return is_sample
def filesizeBetween(self, file, file_size = []): def filesizeBetween(self, file, file_size = None):
if not file_size: file_size = []
try: try:
return (file_size.get('min', 0) * 1048576) < os.path.getsize(file) < (file_size.get('max', 100000) * 1048576) return (file_size.get('min', 0) * 1048576) < os.path.getsize(file) < (file_size.get('max', 100000) * 1048576)
except: except:

1
couchpotato/core/plugins/score/__init__.py

@ -1,5 +1,6 @@
from .main import Score from .main import Score
def start(): def start():
return Score() return Score()

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save