Spring cleanup

This commit is contained in:
Ruud
2014-03-29 23:44:14 +01:00
parent 83c5d701b3
commit 99e77e409a
98 changed files with 469 additions and 489 deletions
+5 -4
View File
@@ -15,6 +15,7 @@ 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):
@@ -54,7 +55,7 @@ def get_db():
# Web view # Web view
def index(): def index():
return template_loader.load('index.html').generate(sep = os.sep, fireEvent = fireEvent, Env = Env) return template_loader.load('index.thtml').generate(sep = os.sep, fireEvent = fireEvent, Env = Env)
addView('', index) addView('', index)
@@ -66,14 +67,14 @@ def apiDocs():
del api_docs[''] del api_docs['']
del api_docs_missing[''] del api_docs_missing['']
return template_loader.load('api.html').generate(fireEvent = fireEvent, routes = sorted(routes), api_docs = api_docs, api_docs_missing = sorted(api_docs_missing), Env = Env) return template_loader.load('api.thtml').generate(fireEvent = fireEvent, routes = sorted(routes), api_docs = api_docs, api_docs_missing = sorted(api_docs_missing), Env = Env)
addView('docs', apiDocs) addView('docs', apiDocs)
# Database debug manager # Database debug manager
def databaseManage(): def databaseManage():
return template_loader.load('database.html').generate(fireEvent = fireEvent, Env = Env) return template_loader.load('database.thtml').generate(fireEvent = fireEvent, Env = Env)
addView('database', databaseManage) addView('database', databaseManage)
@@ -107,7 +108,7 @@ class LoginHandler(BaseHandler):
if self.get_current_user(): if self.get_current_user():
self.redirect(Env.get('web_base')) self.redirect(Env.get('web_base'))
else: else:
self.write(template_loader.load('login.html').generate(sep = os.sep, fireEvent = fireEvent, Env = Env)) self.write(template_loader.load('login.thtml').generate(sep = os.sep, fireEvent = fireEvent, Env = Env))
def post(self, *args, **kwargs): def post(self, *args, **kwargs):
+1 -1
View File
@@ -189,7 +189,7 @@ class Core(Plugin):
def signalHandler(self): def signalHandler(self):
if Env.get('daemonized'): return if Env.get('daemonized'): return
def signal_handler(signal, frame): def signal_handler(*args, **kwargs):
fireEvent('app.shutdown', single = True) fireEvent('app.shutdown', single = True)
signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGINT, signal_handler)
+4 -5
View File
@@ -57,13 +57,12 @@ 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'
} }
html = { html = {
@@ -95,7 +94,6 @@ class ClientScript(Plugin):
else: else:
self.registerStyle(core_url, file_path, position = 'front') self.registerStyle(core_url, file_path, position = 'front')
def minify(self): def minify(self):
# Create cache dir # Create cache dir
@@ -129,7 +127,7 @@ class ClientScript(Plugin):
data = cssmin(data) 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
raw.append({'file': file_path, 'date': int(os.path.getmtime(file_path)), 'data': data}) raw.append({'file': file_path, 'date': int(os.path.getmtime(file_path)), 'data': data})
@@ -192,6 +190,7 @@ class ClientScript(Plugin):
prefix_properties = ['border-radius', 'transform', 'transition', 'box-shadow'] prefix_properties = ['border-radius', 'transform', 'transition', 'box-shadow']
prefix_tags = ['ms', 'moz', 'webkit'] prefix_tags = ['ms', 'moz', 'webkit']
def prefix(self, data): def prefix(self, data):
trimmed_data = re.sub('(\t|\n|\r)+', '', data) trimmed_data = re.sub('(\t|\n|\r)+', '', data)
+3 -3
View File
@@ -164,14 +164,14 @@ class BaseUpdater(Plugin):
def info(self): def info(self):
version = self.getVersion() current_version = self.getVersion()
return { return {
'last_check': self.last_check, 'last_check': self.last_check,
'update_version': self.update_version, 'update_version': self.update_version,
'version': version, 'version': current_version,
'repo_name': '%s/%s' % (self.repo_user, self.repo_name), 'repo_name': '%s/%s' % (self.repo_user, self.repo_name),
'branch': version.get('branch', self.branch), 'branch': current_version.get('branch', self.branch),
} }
def getVersion(self): def getVersion(self):
@@ -5,7 +5,7 @@ var UpdaterBase = new Class({
initialize: function(){ initialize: function(){
var self = this; var self = this;
App.addEvent('load', self.info.bind(self, 2000)) App.addEvent('load', self.info.bind(self, 2000));
App.addEvent('unload', function(){ App.addEvent('unload', function(){
if(self.timer) if(self.timer)
clearTimeout(self.timer); clearTimeout(self.timer);
@@ -66,7 +66,7 @@ var UpdaterBase = new Class({
var changelog = 'https://github.com/'+data.repo_name+'/compare/'+data.version.hash+'...'+data.branch; var changelog = 'https://github.com/'+data.repo_name+'/compare/'+data.version.hash+'...'+data.branch;
if(data.update_version.changelog) if(data.update_version.changelog)
changelog = data.update_version.changelog + '#' + data.version.hash+'...'+data.update_version.hash changelog = data.update_version.changelog + '#' + data.version.hash+'...'+data.update_version.hash;
self.message = new Element('div.message.update').adopt( self.message = new Element('div.message.update').adopt(
new Element('span', { new Element('span', {
-2
View File
@@ -116,7 +116,6 @@ class Database(object):
results[key] = [] results[key] = []
results[key].append(document) results[key].append(document)
return results return results
def reindex(self, **kwargs): def reindex(self, **kwargs):
@@ -473,7 +472,6 @@ class Database(object):
log.info('Total migration took %s', time.time() - migrate_start) log.info('Total migration took %s', time.time() - migrate_start)
log.info('=' * 30) log.info('=' * 30)
# rename old database # rename old database
log.info('Renaming old database to %s ', old_db + '.old') log.info('Renaming old database to %s ', old_db + '.old')
os.rename(old_db, old_db + '.old') os.rename(old_db, old_db + '.old')
+1
View File
@@ -188,6 +188,7 @@ class Downloader(Provider):
def pause(self, release_download, pause): def pause(self, release_download, pause):
return return
class ReleaseDownloadList(list): class ReleaseDownloadList(list):
provider = None provider = None
+1 -1
View File
@@ -146,7 +146,7 @@ class NZBGet(Downloader):
'timeleft': timeleft, 'timeleft': timeleft,
}) })
for nzb in queue: # 'Parameters' is not passed in rpc.postqueue for nzb in queue: # 'Parameters' is not passed in rpc.postqueue
if nzb['NZBID'] in ids: if nzb['NZBID'] in ids:
log.debug('Found %s in NZBGet postprocessing queue', nzb['NZBFilename']) log.debug('Found %s in NZBGet postprocessing queue', nzb['NZBFilename'])
release_downloads.append({ release_downloads.append({
@@ -14,6 +14,7 @@ log = CPLog(__name__)
autoload = 'qBittorrent' autoload = 'qBittorrent'
class qBittorrent(Downloader): class qBittorrent(Downloader):
protocol = ['torrent', 'torrent_magnet'] protocol = ['torrent', 'torrent_magnet']
+3 -3
View File
@@ -78,10 +78,10 @@ class rTorrent(Downloader):
self.error_msg = '' self.error_msg = ''
try: try:
self.rt._verify_conn() self.rt._verify_conn()
except AssertionError as e: except AssertionError as e:
self.error_msg = e.message self.error_msg = e.message
self.rt = None self.rt = None
return self.rt return self.rt
@@ -160,6 +160,7 @@ class Transmission(Downloader):
log.debug('Requesting Transmission to remove the torrent %s%s.', (release_download['name'], ' and cleanup the downloaded files' if delete_files else '')) log.debug('Requesting Transmission to remove the torrent %s%s.', (release_download['name'], ' and cleanup the downloaded files' if delete_files else ''))
return self.trpc.remove_torrent(release_download['id'], delete_files) return self.trpc.remove_torrent(release_download['id'], delete_files)
class TransmissionRPC(object): class TransmissionRPC(object):
"""TransmissionRPC lite library""" """TransmissionRPC lite library"""
+8 -8
View File
@@ -29,14 +29,14 @@ class uTorrent(Downloader):
protocol = ['torrent', 'torrent_magnet'] protocol = ['torrent', 'torrent_magnet']
utorrent_api = None utorrent_api = None
status_flags = { status_flags = {
'STARTED' : 1, 'STARTED': 1,
'CHECKING' : 2, 'CHECKING': 2,
'CHECK-START' : 4, 'CHECK-START': 4,
'CHECKED' : 8, 'CHECKED': 8,
'ERROR' : 16, 'ERROR': 16,
'PAUSED' : 32, 'PAUSED': 32,
'QUEUED' : 64, 'QUEUED': 64,
'LOADED' : 128 'LOADED': 128
} }
def connect(self): def connect(self):
+2 -1
View File
@@ -2,7 +2,7 @@ from urllib import unquote
import re import re
from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import natsortKey, tryInt from couchpotato.core.helpers.variable import natsortKey
def getParams(params): def getParams(params):
@@ -44,6 +44,7 @@ def getParams(params):
return dictToList(temp) return dictToList(temp)
non_decimal = re.compile(r'[^\d.]+') non_decimal = re.compile(r'[^\d.]+')
def dictToList(params): def dictToList(params):
if type(params) is dict: if type(params) is dict:
+4 -3
View File
@@ -216,6 +216,7 @@ def tryFloat(s):
return float(s) return float(s)
except: return 0 except: return 0
def natsortKey(string_): def natsortKey(string_):
"""See http://www.codinghorror.com/blog/archives/001018.html""" """See http://www.codinghorror.com/blog/archives/001018.html"""
return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_)] return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_)]
@@ -247,9 +248,6 @@ def getTitle(media_dict):
except: except:
log.error('Could not get title for %s', getIdentifier(media_dict)) log.error('Could not get title for %s', getIdentifier(media_dict))
return None return None
log.error('Could not get title for %s', getIdentifier(media_dict))
return None
except: except:
log.error('Could not get title for library item: %s', media_dict) log.error('Could not get title for library item: %s', media_dict)
return None return None
@@ -296,8 +294,11 @@ 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 ss(os.path.normpath(base_folder).rstrip(os.path.sep) + os.path.sep) in ss(os.path.normpath(sub_folder).rstrip(os.path.sep) + os.path.sep) return base_folder and sub_folder and ss(os.path.normpath(base_folder).rstrip(os.path.sep) + os.path.sep) in ss(os.path.normpath(sub_folder).rstrip(os.path.sep) + os.path.sep)
# From SABNZBD # From SABNZBD
re_password = [re.compile(r'(.+){{([^{}]+)}}$'), re.compile(r'(.+)\s+password\s*=\s*(.+)$', re.I)] re_password = [re.compile(r'(.+){{([^{}]+)}}$'), re.compile(r'(.+)\s+password\s*=\s*(.+)$', re.I)]
def scanForPassword(name): def scanForPassword(name):
m = None m = None
for reg in re_password: for reg in re_password:
+8 -5
View File
@@ -12,19 +12,22 @@ log = CPLog(__name__)
class Loader(object): class Loader(object):
plugins = {}
providers = {} def __init__(self):
modules = {} self.plugins = {}
self.providers = {}
self.modules = {}
self.paths = {}
def preload(self, root = ''): def preload(self, root = ''):
core = os.path.join(root, 'couchpotato', 'core') core = os.path.join(root, 'couchpotato', 'core')
self.paths = { self.paths.update({
'core': (0, 'couchpotato.core._base', os.path.join(core, '_base')), 'core': (0, 'couchpotato.core._base', os.path.join(core, '_base')),
'plugin': (1, 'couchpotato.core.plugins', os.path.join(core, 'plugins')), 'plugin': (1, 'couchpotato.core.plugins', os.path.join(core, 'plugins')),
'notifications': (20, 'couchpotato.core.notifications', os.path.join(core, 'notifications')), 'notifications': (20, 'couchpotato.core.notifications', os.path.join(core, 'notifications')),
'downloaders': (20, 'couchpotato.core.downloaders', os.path.join(core, 'downloaders')), 'downloaders': (20, 'couchpotato.core.downloaders', os.path.join(core, 'downloaders')),
} })
# Add media to loader # Add media to loader
self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = True) self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = True)
+1
View File
@@ -5,6 +5,7 @@ from couchpotato import get_db, CPLog
from couchpotato.core.event import addEvent, fireEvent, fireEventAsync from couchpotato.core.event import addEvent, fireEvent, fireEventAsync
from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin
import six
log = CPLog(__name__) log = CPLog(__name__)
@@ -1,5 +1,6 @@
from .main import Library from .main import Library
def autoload(): def autoload():
return Library() return Library()
@@ -1,5 +1,6 @@
from .main import Matcher from .main import Matcher
def autoload(): def autoload():
return Matcher() return Matcher()
+3 -5
View File
@@ -222,7 +222,6 @@ class MediaPlugin(MediaBase):
del filter_by['media_status'] del filter_by['media_status']
del filter_by['release_status'] del filter_by['release_status']
# Filter by combining ids # Filter by combining ids
for x in filter_by: for x in filter_by:
media_ids = [n for n in media_ids if n in filter_by[x]] media_ids = [n for n in media_ids if n in filter_by[x]]
@@ -281,7 +280,7 @@ class MediaPlugin(MediaBase):
for media_type in fireEvent('media.types', merge = True): for media_type in fireEvent('media.types', merge = True):
def tempList(*args, **kwargs): def tempList(*args, **kwargs):
return self.listView(types = media_type, *args, **kwargs) return self.listView(types = media_type, **kwargs)
addApiView('%s.list' % media_type, tempList) addApiView('%s.list' % media_type, tempList)
def availableChars(self, types = None, status = None, release_status = None): def availableChars(self, types = None, status = None, release_status = None):
@@ -350,7 +349,7 @@ class MediaPlugin(MediaBase):
for media_type in fireEvent('media.types', merge = True): for media_type in fireEvent('media.types', merge = True):
def tempChar(*args, **kwargs): def tempChar(*args, **kwargs):
return self.charView(types = media_type, *args, **kwargs) return self.charView(types = media_type, **kwargs)
addApiView('%s.available_chars' % media_type, tempChar) addApiView('%s.available_chars' % media_type, tempChar)
def delete(self, media_id, delete_from = None): def delete(self, media_id, delete_from = None):
@@ -382,9 +381,8 @@ class MediaPlugin(MediaBase):
if release.get('status') == 'done': if release.get('status') == 'done':
db.delete(release) db.delete(release)
total_deleted += 1 total_deleted += 1
new_media_status = 'active'
if total_releases == total_deleted: if total_releases == total_deleted and media['status'] != 'active':
db.delete(media) db.delete(media)
deleted = True deleted = True
elif new_media_status: elif new_media_status:
@@ -18,7 +18,7 @@ class Base(NZBProvider):
'search': 'https://www.binsearch.info/index.php?%s', 'search': 'https://www.binsearch.info/index.php?%s',
} }
http_time_between_calls = 4 # Seconds http_time_between_calls = 4 # Seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -28,7 +28,7 @@ class Base(NZBProvider):
try: try:
html = BeautifulSoup(data) html = BeautifulSoup(data)
main_table = html.find('table', attrs = {'id':'r2'}) main_table = html.find('table', attrs = {'id': 'r2'})
if not main_table: if not main_table:
return return
@@ -36,11 +36,11 @@ class Base(NZBProvider):
items = main_table.find_all('tr') items = main_table.find_all('tr')
for row in items: for row in items:
title = row.find('span', attrs = {'class':'s'}) title = row.find('span', attrs = {'class': 's'})
if not title: continue if not title: continue
nzb_id = row.find('input', attrs = {'type':'checkbox'})['name'] nzb_id = row.find('input', attrs = {'type': 'checkbox'})['name']
info = row.find('span', attrs = {'class':'d'}) info = row.find('span', attrs = {'class':'d'})
size_match = re.search('size:.(?P<size>[0-9\.]+.[GMB]+)', info.text) size_match = re.search('size:.(?P<size>[0-9\.]+.[GMB]+)', info.text)
@@ -18,7 +18,7 @@ class Base(NZBProvider, RSS):
'search': 'https://www.nzbclub.com/nzbfeeds.aspx?%s', 'search': 'https://www.nzbclub.com/nzbfeeds.aspx?%s',
} }
http_time_between_calls = 4 #seconds http_time_between_calls = 4 # seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -55,7 +55,7 @@ class Base(NZBProvider, RSS):
def getMoreInfo(self, item): def getMoreInfo(self, item):
full_description = self.getCache('nzbclub.%s' % item['id'], item['detail_url'], cache_timeout = 25920000) full_description = self.getCache('nzbclub.%s' % item['id'], item['detail_url'], cache_timeout = 25920000)
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
nfo_pre = html.find('pre', attrs = {'class':'nfo'}) nfo_pre = html.find('pre', attrs = {'class': 'nfo'})
description = toUnicode(nfo_pre.text) if nfo_pre else '' description = toUnicode(nfo_pre.text) if nfo_pre else ''
item['description'] = description item['description'] = description
@@ -91,7 +91,7 @@ class Base(NZBProvider, RSS):
nfo_url = re.search('href=\"(?P<nfo>.+)\" ', item['description']).group('nfo') nfo_url = re.search('href=\"(?P<nfo>.+)\" ', item['description']).group('nfo')
full_description = self.getCache('nzbindex.%s' % item['id'], url = nfo_url, cache_timeout = 25920000) full_description = self.getCache('nzbindex.%s' % item['id'], url = nfo_url, cache_timeout = 25920000)
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
item['description'] = toUnicode(html.find('pre', attrs = {'id':'nfo0'}).text) item['description'] = toUnicode(html.find('pre', attrs = {'id': 'nfo0'}).text)
except: except:
pass pass
@@ -20,7 +20,7 @@ class Base(NZBProvider, RSS):
'detail_url': 'https://omgwtfnzbs.org/details.php?id=%s', 'detail_url': 'https://omgwtfnzbs.org/details.php?id=%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
cat_ids = [ cat_ids = [
([15], ['dvdrip']), ([15], ['dvdrip']),
@@ -21,7 +21,7 @@ class Base(TorrentProvider):
} }
# Searches for movies only - BiT-HDTV's subcategory and resolution search filters appear to be broken # Searches for movies only - BiT-HDTV's subcategory and resolution search filters appear to be broken
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -40,7 +40,7 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
result_table = html.find('table', attrs = {'width' : '750', 'class' : ''}) result_table = html.find('table', attrs = {'width': '750', 'class': ''})
if result_table is None: if result_table is None:
return return
@@ -74,7 +74,7 @@ class Base(TorrentProvider):
def getMoreInfo(self, item): def getMoreInfo(self, item):
full_description = self.getCache('bithdtv.%s' % item['id'], item['detail_url'], cache_timeout = 25920000) full_description = self.getCache('bithdtv.%s' % item['id'], item['detail_url'], cache_timeout = 25920000)
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
nfo_pre = html.find('table', attrs = {'class':'detail'}) nfo_pre = html.find('table', attrs = {'class': 'detail'})
description = toUnicode(nfo_pre.text) if nfo_pre else '' description = toUnicode(nfo_pre.text) if nfo_pre else ''
item['description'] = description item['description'] = description
@@ -20,7 +20,7 @@ class Base(TorrentProvider):
'baseurl': 'https://www.bitsoup.me/%s', 'baseurl': 'https://www.bitsoup.me/%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _searchOnTitle(self, title, movie, quality, results): def _searchOnTitle(self, title, movie, quality, results):
@@ -30,7 +30,7 @@ class Base(TorrentProvider):
}) })
url = "%s&%s" % (self.urls['search'], arguments) url = "%s&%s" % (self.urls['search'], arguments)
url = self.urls['search'] % self.buildUrl(media, quality) url = self.urls['search'] % self.buildUrl(movie, quality)
data = self.getHTMLData(url) data = self.getHTMLData(url)
if data: if data:
@@ -74,7 +74,6 @@ class Base(TorrentProvider):
except: except:
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): def getLoginParams(self):
return { return {
'username': self.conf('username'), 'username': self.conf('username'),
@@ -82,7 +81,6 @@ class Base(TorrentProvider):
'ssl': 'yes', 'ssl': 'yes',
} }
def loginSuccess(self, output): def loginSuccess(self, output):
return 'logout.php' in output.lower() return 'logout.php' in output.lower()
@@ -19,7 +19,7 @@ class Base(TorrentProvider):
'api': 'https://hdbits.org/api/torrents' 'api': 'https://hdbits.org/api/torrents'
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _post_query(self, **params): def _post_query(self, **params):
@@ -56,7 +56,7 @@ class Base(TorrentProvider):
'name': result['name'], 'name': result['name'],
'url': self.urls['download'] % (result['id'], self.conf('passkey')), 'url': self.urls['download'] % (result['id'], self.conf('passkey')),
'detail_url': self.urls['detail'] % result['id'], 'detail_url': self.urls['detail'] % result['id'],
'size': tryInt(result['size'])/1024/1024, 'size': tryInt(result['size']) / 1024 / 1024,
'seeders': tryInt(result['seeders']), 'seeders': tryInt(result['seeders']),
'leechers': tryInt(result['leechers']) 'leechers': tryInt(result['leechers'])
}) })
@@ -23,9 +23,9 @@ class Base(TorrentProvider):
} }
cat_ids = [ cat_ids = [
(['41'], ['720p', '1080p', 'brrip']), (['41'], ['720p', '1080p', 'brrip']),
(['19'], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']), (['19'], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']),
(['20'], ['dvdr']) (['20'], ['dvdr'])
] ]
cat_backup_id = 200 cat_backup_id = 200
@@ -79,7 +79,7 @@ class Base(TorrentProvider):
return confirmed + trusted + vip + moderated return confirmed + trusted + vip + moderated
id = re.search('id=(?P<id>\d+)&', link).group('id') id = re.search('id=(?P<id>\d+)&', link).group('id')
url = self.urls['download'] % (download) url = self.urls['download'] % download
fileSize = self.parseSize(result.select('td.rowhead')[5].text) fileSize = self.parseSize(result.select('td.rowhead')[5].text)
results.append({ results.append({
@@ -113,7 +113,7 @@ class Base(TorrentProvider):
try: try:
full_description = self.getHTMLData(item['detail_url']) full_description = self.getHTMLData(item['detail_url'])
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
nfo_pre = html.find('td', attrs = {'class':'main'}).findAll('table')[1] nfo_pre = html.find('td', attrs = {'class': 'main'}).findAll('table')[1]
description = toUnicode(nfo_pre.text) if nfo_pre else '' description = toUnicode(nfo_pre.text) if nfo_pre else ''
except: except:
log.error('Failed getting more info for %s', item['name']) log.error('Failed getting more info for %s', item['name'])
@@ -21,7 +21,7 @@ class Base(TorrentProvider):
'search': 'https://www.iptorrents.com/torrents/?l%d=1%s&q=%s&qf=ti&p=%d', 'search': 'https://www.iptorrents.com/torrents/?l%d=1%s&q=%s&qf=ti&p=%d',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
cat_backup_id = None cat_backup_id = None
def buildUrl(self, title, media, quality): def buildUrl(self, title, media, quality):
@@ -53,14 +53,14 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
page_nav = html.find('span', attrs = {'class' : 'page_nav'}) page_nav = html.find('span', attrs = {'class': 'page_nav'})
if page_nav: if page_nav:
next_link = page_nav.find("a", text = "Next") next_link = page_nav.find("a", text = "Next")
if next_link: if next_link:
final_page_link = next_link.previous_sibling.previous_sibling final_page_link = next_link.previous_sibling.previous_sibling
pages = int(final_page_link.string) pages = int(final_page_link.string)
result_table = html.find('table', attrs = {'class' : 'torrents'}) result_table = html.find('table', attrs = {'class': 'torrents'})
if not result_table or 'nothing found!' in data.lower(): if not result_table or 'nothing found!' in data.lower():
return return
@@ -80,8 +80,8 @@ class Base(TorrentProvider):
torrent_download_url = self.urls['base_url'] + (result.find_all('td')[3].find('a'))['href'].replace(' ', '.') torrent_download_url = self.urls['base_url'] + (result.find_all('td')[3].find('a'))['href'].replace(' ', '.')
torrent_details_url = self.urls['base_url'] + torrent['href'] torrent_details_url = self.urls['base_url'] + torrent['href']
torrent_size = self.parseSize(result.find_all('td')[5].string) torrent_size = self.parseSize(result.find_all('td')[5].string)
torrent_seeders = tryInt(result.find('td', attrs = {'class' : 'ac t_seeders'}).string) torrent_seeders = tryInt(result.find('td', attrs = {'class': 'ac t_seeders'}).string)
torrent_leechers = tryInt(result.find('td', attrs = {'class' : 'ac t_leechers'}).string) torrent_leechers = tryInt(result.find('td', attrs = {'class': 'ac t_leechers'}).string)
results.append({ results.append({
'id': torrent_id, 'id': torrent_id,
@@ -26,7 +26,7 @@ class Base(TorrentMagnetProvider):
(['dvd'], ['dvdr']), (['dvd'], ['dvdr']),
] ]
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
cat_backup_id = None cat_backup_id = None
proxy_list = [ proxy_list = [
@@ -18,12 +18,12 @@ log = CPLog(__name__)
class Base(TorrentProvider): class Base(TorrentProvider):
urls = { urls = {
'domain': 'https://tls.passthepopcorn.me', 'domain': 'https://tls.passthepopcorn.me',
'detail': 'https://tls.passthepopcorn.me/torrents.php?torrentid=%s', 'detail': 'https://tls.passthepopcorn.me/torrents.php?torrentid=%s',
'torrent': 'https://tls.passthepopcorn.me/torrents.php', 'torrent': 'https://tls.passthepopcorn.me/torrents.php',
'login': 'https://tls.passthepopcorn.me/ajax.php?action=login', 'login': 'https://tls.passthepopcorn.me/ajax.php?action=login',
'login_check': 'https://tls.passthepopcorn.me/ajax.php?action=login', 'login_check': 'https://tls.passthepopcorn.me/ajax.php?action=login',
'search': 'https://tls.passthepopcorn.me/search/%s/0/7/%d' 'search': 'https://tls.passthepopcorn.me/search/%s/0/7/%d'
} }
http_time_between_calls = 2 http_time_between_calls = 2
@@ -136,23 +136,23 @@ class Base(TorrentProvider):
def htmlToUnicode(self, text): def htmlToUnicode(self, text):
def fixup(m): def fixup(m):
text = m.group(0) txt = m.group(0)
if text[:2] == "&#": if txt[:2] == "&#":
# character reference # character reference
try: try:
if text[:3] == "&#x": if txt[:3] == "&#x":
return unichr(int(text[3:-1], 16)) return unichr(int(txt[3:-1], 16))
else: else:
return unichr(int(text[2:-1])) return unichr(int(txt[2:-1]))
except ValueError: except ValueError:
pass pass
else: else:
# named entity # named entity
try: try:
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]) txt = unichr(htmlentitydefs.name2codepoint[txt[1:-1]])
except KeyError: except KeyError:
pass pass
return text # leave as is return txt # leave as is
return re.sub("&#?\w+;", fixup, six.u('%s') % text) return re.sub("&#?\w+;", fixup, six.u('%s') % text)
def unicodeToASCII(self, text): def unicodeToASCII(self, text):
@@ -164,11 +164,11 @@ class Base(TorrentProvider):
def getLoginParams(self): def getLoginParams(self):
return { return {
'username': self.conf('username'), 'username': self.conf('username'),
'password': self.conf('password'), 'password': self.conf('password'),
'passkey': self.conf('passkey'), 'passkey': self.conf('passkey'),
'keeplogged': '1', 'keeplogged': '1',
'login': 'Login' 'login': 'Login'
} }
def loginSuccess(self, output): def loginSuccess(self, output):
@@ -34,7 +34,7 @@ class Base(TorrentMagnetProvider):
query = self.buildUrl(media) query = self.buildUrl(media)
params = tryUrlencode({ params = tryUrlencode({
'page':'torrents', 'page': 'torrents',
'search': query, 'search': query,
'active': 1, 'active': 1,
}) })
@@ -22,7 +22,7 @@ class Base(TorrentProvider):
'download': 'https://www.sceneaccess.eu/%s', 'download': 'https://www.sceneaccess.eu/%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -33,16 +33,16 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
resultsTable = html.find('table', attrs = {'id' : 'torrents-table'}) resultsTable = html.find('table', attrs = {'id': 'torrents-table'})
if resultsTable is None: if resultsTable is None:
return return
entries = resultsTable.find_all('tr', attrs = {'class' : 'tt_row'}) entries = resultsTable.find_all('tr', attrs = {'class': 'tt_row'})
for result in entries: for result in entries:
link = result.find('td', attrs = {'class' : 'ttr_name'}).find('a') link = result.find('td', attrs = {'class': 'ttr_name'}).find('a')
url = result.find('td', attrs = {'class' : 'td_dl'}).find('a') url = result.find('td', attrs = {'class': 'td_dl'}).find('a')
leechers = result.find('td', attrs = {'class' : 'ttr_leechers'}).find('a') leechers = result.find('td', attrs = {'class': 'ttr_leechers'}).find('a')
torrent_id = link['href'].replace('details?id=', '') torrent_id = link['href'].replace('details?id=', '')
results.append({ results.append({
@@ -50,8 +50,8 @@ class Base(TorrentProvider):
'name': link['title'], 'name': link['title'],
'url': self.urls['download'] % url['href'], 'url': self.urls['download'] % url['href'],
'detail_url': self.urls['detail'] % torrent_id, 'detail_url': self.urls['detail'] % torrent_id,
'size': self.parseSize(result.find('td', attrs = {'class' : 'ttr_size'}).contents[0]), 'size': self.parseSize(result.find('td', attrs = {'class': 'ttr_size'}).contents[0]),
'seeders': tryInt(result.find('td', attrs = {'class' : 'ttr_seeders'}).find('a').string), 'seeders': tryInt(result.find('td', attrs = {'class': 'ttr_seeders'}).find('a').string),
'leechers': tryInt(leechers.string) if leechers else 0, 'leechers': tryInt(leechers.string) if leechers else 0,
'get_more_info': self.getMoreInfo, 'get_more_info': self.getMoreInfo,
}) })
@@ -62,7 +62,7 @@ class Base(TorrentProvider):
def getMoreInfo(self, item): def getMoreInfo(self, item):
full_description = self.getCache('sceneaccess.%s' % item['id'], item['detail_url'], cache_timeout = 25920000) full_description = self.getCache('sceneaccess.%s' % item['id'], item['detail_url'], cache_timeout = 25920000)
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
nfo_pre = html.find('div', attrs = {'id':'details_table'}) nfo_pre = html.find('div', attrs = {'id': 'details_table'})
description = toUnicode(nfo_pre.text) if nfo_pre else '' description = toUnicode(nfo_pre.text) if nfo_pre else ''
item['description'] = description item['description'] = description
@@ -108,7 +108,7 @@ class Base(TorrentMagnetProvider):
def getMoreInfo(self, item): def getMoreInfo(self, item):
full_description = self.getCache('tpb.%s' % item['id'], item['detail_url'], cache_timeout = 25920000) full_description = self.getCache('tpb.%s' % item['id'], item['detail_url'], cache_timeout = 25920000)
html = BeautifulSoup(full_description) html = BeautifulSoup(full_description)
nfo_pre = html.find('div', attrs = {'class':'nfo'}) nfo_pre = html.find('div', attrs = {'class': 'nfo'})
description = toUnicode(nfo_pre.text) if nfo_pre else '' description = toUnicode(nfo_pre.text) if nfo_pre else ''
item['description'] = description item['description'] = description
@@ -31,7 +31,7 @@ class Base(TorrentProvider):
([20], ['dvdr']), ([20], ['dvdr']),
] ]
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
cat_backup_id = None cat_backup_id = None
def _searchOnTitle(self, title, movie, quality, results): def _searchOnTitle(self, title, movie, quality, results):
@@ -43,7 +43,7 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
result_table = html.find('table', attrs = {'border' : '1'}) result_table = html.find('table', attrs = {'border': '1'})
if not result_table: if not result_table:
return return
@@ -52,7 +52,7 @@ class Base(TorrentProvider):
for result in entries[1:]: for result in entries[1:]:
cells = result.find_all('td') cells = result.find_all('td')
link = cells[1].find('a', attrs = {'class' : 'index'}) link = cells[1].find('a', attrs = {'class': 'index'})
full_id = link['href'].replace('details.php?id=', '') full_id = link['href'].replace('details.php?id=', '')
torrent_id = full_id[:6] torrent_id = full_id[:6]
@@ -16,7 +16,7 @@ class Base(TorrentProvider):
'download': 'http://www.td.af/download.php/%s/%s', 'download': 'http://www.td.af/download.php/%s/%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -21,7 +21,7 @@ class Base(TorrentProvider):
'download': 'http://www.torrentleech.org%s', 'download': 'http://www.torrentleech.org%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
cat_backup_id = None cat_backup_id = None
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -34,7 +34,7 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
result_table = html.find('table', attrs = {'id' : 'torrenttable'}) result_table = html.find('table', attrs = {'id': 'torrenttable'})
if not result_table: if not result_table:
return return
@@ -42,9 +42,9 @@ class Base(TorrentProvider):
for result in entries[1:]: for result in entries[1:]:
link = result.find('td', attrs = {'class' : 'name'}).find('a') link = result.find('td', attrs = {'class': 'name'}).find('a')
url = result.find('td', attrs = {'class' : 'quickdownload'}).find('a') url = result.find('td', attrs = {'class': 'quickdownload'}).find('a')
details = result.find('td', attrs = {'class' : 'name'}).find('a') details = result.find('td', attrs = {'class': 'name'}).find('a')
results.append({ results.append({
'id': link['href'].replace('/torrent/', ''), 'id': link['href'].replace('/torrent/', ''),
@@ -52,8 +52,8 @@ class Base(TorrentProvider):
'url': self.urls['download'] % url['href'], 'url': self.urls['download'] % url['href'],
'detail_url': self.urls['download'] % details['href'], 'detail_url': self.urls['download'] % details['href'],
'size': self.parseSize(result.find_all('td')[4].string), 'size': self.parseSize(result.find_all('td')[4].string),
'seeders': tryInt(result.find('td', attrs = {'class' : 'seeders'}).string), 'seeders': tryInt(result.find('td', attrs = {'class': 'seeders'}).string),
'leechers': tryInt(result.find('td', attrs = {'class' : 'leechers'}).string), 'leechers': tryInt(result.find('td', attrs = {'class': 'leechers'}).string),
}) })
except: except:
@@ -21,7 +21,7 @@ class Base(TorrentProvider):
'download': 'https://torrentshack.net/%s', 'download': 'https://torrentshack.net/%s',
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # Seconds
def _search(self, media, quality, results): def _search(self, media, quality, results):
@@ -32,16 +32,16 @@ class Base(TorrentProvider):
html = BeautifulSoup(data) html = BeautifulSoup(data)
try: try:
result_table = html.find('table', attrs = {'id' : 'torrent_table'}) result_table = html.find('table', attrs = {'id': 'torrent_table'})
if not result_table: if not result_table:
return return
entries = result_table.find_all('tr', attrs = {'class' : 'torrent'}) entries = result_table.find_all('tr', attrs = {'class': 'torrent'})
for result in entries: for result in entries:
link = result.find('span', attrs = {'class' : 'torrent_name_link'}).parent link = result.find('span', attrs = {'class': 'torrent_name_link'}).parent
url = result.find('td', attrs = {'class' : 'torrent_td'}).find('a') url = result.find('td', attrs = {'class': 'torrent_td'}).find('a')
results.append({ results.append({
'id': link['href'].replace('torrents.php?torrentid=', ''), 'id': link['href'].replace('torrents.php?torrentid=', ''),
@@ -16,7 +16,7 @@ class Base(TorrentProvider):
'detail': '%s/api/movie.json?id=%s' 'detail': '%s/api/movie.json?id=%s'
} }
http_time_between_calls = 1 #seconds http_time_between_calls = 1 # seconds
proxy_list = [ proxy_list = [
'http://yify.unlocktorrent.com', 'http://yify.unlocktorrent.com',
@@ -6,12 +6,11 @@
top: 0; top: 0;
text-align: right; text-align: right;
height: 100%; height: 100%;
border-bottom: 4px solid transparent;
transition: all .4s cubic-bezier(0.9,0,0.1,1); transition: all .4s cubic-bezier(0.9,0,0.1,1);
position: absolute; position: absolute;
z-index: 20; z-index: 20;
border: 1px solid transparent; border: 0 solid transparent;
border-width: 0 0 4px; border-bottom-width: 4px;
} }
.search_form:hover { .search_form:hover {
border-color: #047792; border-color: #047792;
@@ -22,19 +21,19 @@
right: 44px; right: 44px;
} }
} }
.search_form.focused, .search_form.focused,
.search_form.shown { .search_form.shown {
border-color: #04bce6; border-color: #04bce6;
} }
.search_form .input { .search_form .input {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
width: 45px; width: 45px;
transition: all .4s cubic-bezier(0.9,0,0.1,1); transition: all .4s cubic-bezier(0.9,0,0.1,1);
} }
.search_form.focused .input, .search_form.focused .input,
.search_form.shown .input { .search_form.shown .input {
width: 380px; width: 380px;
@@ -49,7 +48,6 @@
color: #FFF; color: #FFF;
font-size: 25px; font-size: 25px;
height: 100%; height: 100%;
padding: 10px;
width: 100%; width: 100%;
opacity: 0; opacity: 0;
padding: 0 40px 0 10px; padding: 0 40px 0 10px;
@@ -59,23 +57,23 @@
.search_form.shown .input input { .search_form.shown .input input {
opacity: 1; opacity: 1;
} }
.search_form input::-ms-clear { .search_form input::-ms-clear {
width : 0; width : 0;
height: 0; height: 0;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.search_form .input input { .search_form .input input {
font-size: 15px; font-size: 15px;
} }
.search_form.focused .input, .search_form.focused .input,
.search_form.shown .input { .search_form.shown .input {
width: 277px; width: 277px;
} }
} }
.search_form .input a { .search_form .input a {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -89,7 +87,7 @@
font-size: 15px; font-size: 15px;
color: #FFF; color: #FFF;
} }
.search_form .input a:after { .search_form .input a:after {
content: "\e03e"; content: "\e03e";
} }
@@ -97,7 +95,7 @@
.search_form.shown.filled .input a:after { .search_form.shown.filled .input a:after {
content: "\e04e"; content: "\e04e";
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.search_form .input a { .search_form .input a {
line-height: 44px; line-height: 44px;
@@ -167,13 +165,13 @@
.media_result .options select[name=title] { width: 170px; } .media_result .options select[name=title] { width: 170px; }
.media_result .options select[name=profile] { width: 90px; } .media_result .options select[name=profile] { width: 90px; }
.media_result .options select[name=category] { width: 80px; } .media_result .options select[name=category] { width: 80px; }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.media_result .options select[name=title] { width: 90px; } .media_result .options select[name=title] { width: 90px; }
.media_result .options select[name=profile] { width: 50px; } .media_result .options select[name=profile] { width: 50px; }
.media_result .options select[name=category] { width: 50px; } .media_result .options select[name=category] { width: 50px; }
} }
.media_result .options .button { .media_result .options .button {
@@ -227,14 +225,14 @@
right: 7px; right: 7px;
vertical-align: middle; vertical-align: middle;
} }
.media_result .info h2 { .media_result .info h2 {
margin: 0; margin: 0;
font-weight: normal; font-weight: normal;
font-size: 20px; font-size: 20px;
padding: 0; padding: 0;
} }
.search_form .info h2 { .search_form .info h2 {
position: absolute; position: absolute;
width: 100%; width: 100%;
@@ -247,12 +245,12 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
} }
.search_form .info h2 .title { .search_form .info h2 .title {
position: absolute; position: absolute;
width: 88%; width: 88%;
} }
.media_result .info h2 .year { .media_result .info h2 .year {
padding: 0 5px; padding: 0 5px;
text-align: center; text-align: center;
@@ -260,14 +258,14 @@
width: 12%; width: 12%;
right: 0; right: 0;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.search_form .info h2 .year { .search_form .info h2 .year {
font-size: 12px; font-size: 12px;
margin-top: 7px; margin-top: 7px;
} }
} }
.search_form .mask, .search_form .mask,
@@ -277,4 +275,4 @@
width: 100%; width: 100%;
left: 0; left: 0;
top: 0; top: 0;
} }
@@ -16,7 +16,7 @@ Block.Search = new Class({
'keyup': self.keyup.bind(self), 'keyup': self.keyup.bind(self),
'focus': function(){ 'focus': function(){
if(focus_timer) clearTimeout(focus_timer); if(focus_timer) clearTimeout(focus_timer);
self.el.addClass('focused') self.el.addClass('focused');
if(this.get('value')) if(this.get('value'))
self.hideResults(false) self.hideResults(false)
}, },
@@ -57,17 +57,17 @@ Block.Search = new Class({
(e).preventDefault(); (e).preventDefault();
if(self.last_q === ''){ if(self.last_q === ''){
self.input.blur() self.input.blur();
self.last_q = null; self.last_q = null;
} }
else { else {
self.last_q = ''; self.last_q = '';
self.input.set('value', ''); self.input.set('value', '');
self.input.focus() self.input.focus();
self.media = {} self.media = {};
self.results.empty() self.results.empty();
self.el.removeClass('filled') self.el.removeClass('filled')
} }
@@ -92,16 +92,16 @@ Block.Search = new Class({
self.hidden = bool; self.hidden = bool;
}, },
keyup: function(e){ keyup: function(){
var self = this; var self = this;
self.el[self.q() ? 'addClass' : 'removeClass']('filled') self.el[self.q() ? 'addClass' : 'removeClass']('filled');
if(self.q() != self.last_q){ if(self.q() != self.last_q){
if(self.api_request && self.api_request.isRunning()) if(self.api_request && self.api_request.isRunning())
self.api_request.cancel(); self.api_request.cancel();
if(self.autocomplete_timer) clearTimeout(self.autocomplete_timer) if(self.autocomplete_timer) clearTimeout(self.autocomplete_timer);
self.autocomplete_timer = self.autocomplete.delay(300, self) self.autocomplete_timer = self.autocomplete.delay(300, self)
} }
@@ -111,7 +111,7 @@ Block.Search = new Class({
var self = this; var self = this;
if(!self.q()){ if(!self.q()){
self.hideResults(true) self.hideResults(true);
return return
} }
@@ -139,7 +139,7 @@ Block.Search = new Class({
}) })
} }
else else
self.fill(q, cache) self.fill(q, cache);
self.last_q = q; self.last_q = q;
@@ -148,31 +148,31 @@ Block.Search = new Class({
fill: function(q, json){ fill: function(q, json){
var self = this; var self = this;
self.cache[q] = json self.cache[q] = json;
self.media = {} self.media = {};
self.results.empty() self.results.empty();
Object.each(json, function(media, type){ Object.each(json, function(media){
if(typeOf(media) == 'array'){ if(typeOf(media) == 'array'){
Object.each(media, function(m){ Object.each(media, function(m){
var m = new Block.Search[m.type.capitalize() + 'Item'](m); var m = new Block.Search[m.type.capitalize() + 'Item'](m);
$(m).inject(self.results) $(m).inject(self.results);
self.media[m.imdb || 'r-'+Math.floor(Math.random()*10000)] = m self.media[m.imdb || 'r-'+Math.floor(Math.random()*10000)] = m;
if(q == m.imdb) if(q == m.imdb)
m.showOptions() m.showOptions()
}); });
} }
}) });
// Calculate result heights // Calculate result heights
var w = window.getSize(), var w = window.getSize(),
rc = self.result_container.getCoordinates(); rc = self.result_container.getCoordinates();
self.results.setStyle('max-height', (w.y - rc.top - 50) + 'px') self.results.setStyle('max-height', (w.y - rc.top - 50) + 'px');
self.mask.fade('out') self.mask.fade('out')
}, },
@@ -185,4 +185,4 @@ Block.Search = new Class({
return this.input.get('value').trim(); return this.input.get('value').trim();
} }
}); });
@@ -14,6 +14,7 @@ log = CPLog(__name__)
class Searcher(SearcherBase): class Searcher(SearcherBase):
# noinspection PyMissingConstructor
def __init__(self): def __init__(self):
addEvent('searcher.protocols', self.getSearchProtocols) addEvent('searcher.protocols', self.getSearchProtocols)
addEvent('searcher.contains_other_quality', self.containsOtherQuality) addEvent('searcher.contains_other_quality', self.containsOtherQuality)
@@ -195,7 +196,7 @@ class Searcher(SearcherBase):
req = splitString(req_set, '&') req = splitString(req_set, '&')
req_match += len(list(set(rel_words) & set(req))) == len(req) req_match += len(list(set(rel_words) & set(req))) == len(req)
if len(required_words) > 0 and req_match == 0: if len(required_words) > 0 and req_match == 0:
log.info2('Wrong: Required word missing: %s', rel_name) log.info2('Wrong: Required word missing: %s', rel_name)
return False return False
@@ -26,7 +26,7 @@ var MovieList = new Class({
self.filter = self.options.filter || { self.filter = self.options.filter || {
'starts_with': null, 'starts_with': null,
'search': null 'search': null
} };
self.el = new Element('div.movies').adopt( self.el = new Element('div.movies').adopt(
self.title = self.options.title ? new Element('h2', { self.title = self.options.title ? new Element('h2', {
@@ -52,7 +52,7 @@ var MovieList = new Class({
self.getMovies(); self.getMovies();
App.on('movie.added', self.movieAdded.bind(self)) App.on('movie.added', self.movieAdded.bind(self));
App.on('movie.deleted', self.movieDeleted.bind(self)) App.on('movie.deleted', self.movieDeleted.bind(self))
}, },
@@ -96,7 +96,7 @@ var MovieList = new Class({
if(self.options.load_more) if(self.options.load_more)
self.scrollspy = new ScrollSpy({ self.scrollspy = new ScrollSpy({
min: function(){ min: function(){
var c = self.load_more.getCoordinates() var c = self.load_more.getCoordinates();
return c.top - window.document.getSize().y - 300 return c.top - window.document.getSize().y - 300
}, },
onEnter: self.loadMore.bind(self) onEnter: self.loadMore.bind(self)
@@ -179,7 +179,7 @@ var MovieList = new Class({
m.fireEvent('injected'); m.fireEvent('injected');
self.movies.include(m) self.movies.include(m);
self.movies_added[movie._id] = true; self.movies_added[movie._id] = true;
}, },
@@ -187,7 +187,7 @@ var MovieList = new Class({
var self = this; var self = this;
var chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ';
self.el.addClass('with_navigation') self.el.addClass('with_navigation');
self.navigation = new Element('div.alph_nav').adopt( self.navigation = new Element('div.alph_nav').adopt(
self.mass_edit_form = new Element('div.mass_edit_form').adopt( self.mass_edit_form = new Element('div.mass_edit_form').adopt(
@@ -242,7 +242,7 @@ var MovieList = new Class({
this.addClass(a); this.addClass(a);
el.inject(el.getParent(), 'top'); el.inject(el.getParent(), 'top');
el.getSiblings().hide() el.getSiblings().hide();
setTimeout(function(){ setTimeout(function(){
el.getSiblings().setStyle('display', null); el.getSiblings().setStyle('display', null);
}, 100) }, 100)
@@ -286,7 +286,7 @@ var MovieList = new Class({
'status': self.options.status 'status': self.options.status
}, self.filter), }, self.filter),
'onSuccess': function(json){ 'onSuccess': function(json){
available_chars = json.chars available_chars = json.chars;
available_chars.each(function(c){ available_chars.each(function(c){
self.letters[c.capitalize()].addClass('available') self.letters[c.capitalize()].addClass('available')
@@ -300,7 +300,7 @@ var MovieList = new Class({
self.navigation_alpha = new Element('ul.numbers', { self.navigation_alpha = new Element('ul.numbers', {
'events': { 'events': {
'click:relay(li.available)': function(e, el){ 'click:relay(li.available)': function(e, el){
self.activateLetter(el.get('data-letter')) self.activateLetter(el.get('data-letter'));
self.getMovies(true) self.getMovies(true)
} }
} }
@@ -318,7 +318,7 @@ var MovieList = new Class({
// All // All
self.letters['all'] = new Element('li.letter_all.available.active', { self.letters['all'] = new Element('li.letter_all.available.active', {
'text': 'ALL', 'text': 'ALL'
}).inject(self.navigation_alpha); }).inject(self.navigation_alpha);
// Chars // Chars
@@ -334,7 +334,7 @@ var MovieList = new Class({
if (self.options.menu.length > 0) if (self.options.menu.length > 0)
self.options.menu.each(function(menu_item){ self.options.menu.each(function(menu_item){
self.navigation_menu.addLink(menu_item); self.navigation_menu.addLink(menu_item);
}) });
else else
self.navigation_menu.hide(); self.navigation_menu.hide();
@@ -347,15 +347,15 @@ var MovieList = new Class({
movies = self.movies.length; movies = self.movies.length;
self.movies.each(function(movie){ self.movies.each(function(movie){
selected += movie.isSelected() ? 1 : 0 selected += movie.isSelected() ? 1 : 0
}) });
var indeterminate = selected > 0 && selected < movies, var indeterminate = selected > 0 && selected < movies,
checked = selected == movies && selected > 0; checked = selected == movies && selected > 0;
self.mass_edit_select.set('indeterminate', indeterminate) self.mass_edit_select.set('indeterminate', indeterminate);
self.mass_edit_select_class[checked ? 'check' : 'uncheck']() self.mass_edit_select_class[checked ? 'check' : 'uncheck']();
self.mass_edit_select_class.element[indeterminate ? 'addClass' : 'removeClass']('indeterminate') self.mass_edit_select_class.element[indeterminate ? 'addClass' : 'removeClass']('indeterminate');
self.mass_edit_selected.set('text', selected); self.mass_edit_selected.set('text', selected);
}, },
@@ -371,7 +371,7 @@ var MovieList = new Class({
'events': { 'events': {
'click': function(e){ 'click': function(e){
(e).preventDefault(); (e).preventDefault();
this.set('text', 'Deleting..') this.set('text', 'Deleting..');
Api.request('media.delete', { Api.request('media.delete', {
'data': { 'data': {
'id': ids.join(','), 'id': ids.join(','),
@@ -383,7 +383,7 @@ var MovieList = new Class({
var erase_movies = []; var erase_movies = [];
self.movies.each(function(movie){ self.movies.each(function(movie){
if (movie.isSelected()){ if (movie.isSelected()){
$(movie).destroy() $(movie).destroy();
erase_movies.include(movie); erase_movies.include(movie);
} }
}); });
@@ -410,7 +410,7 @@ var MovieList = new Class({
changeQualitySelected: function(){ changeQualitySelected: function(){
var self = this; var self = this;
var ids = self.getSelectedMovies() var ids = self.getSelectedMovies();
Api.request('movie.edit', { Api.request('movie.edit', {
'data': { 'data': {
@@ -423,11 +423,11 @@ var MovieList = new Class({
refreshSelected: function(){ refreshSelected: function(){
var self = this; var self = this;
var ids = self.getSelectedMovies() var ids = self.getSelectedMovies();
Api.request('media.refresh', { Api.request('media.refresh', {
'data': { 'data': {
'id': ids.join(','), 'id': ids.join(',')
} }
}); });
}, },
@@ -435,7 +435,7 @@ var MovieList = new Class({
getSelectedMovies: function(){ getSelectedMovies: function(){
var self = this; var self = this;
var ids = [] var ids = [];
self.movies.each(function(movie){ self.movies.each(function(movie){
if (movie.isSelected()) if (movie.isSelected())
ids.include(movie.get('_id')) ids.include(movie.get('_id'))
@@ -459,11 +459,11 @@ var MovieList = new Class({
reset: function(){ reset: function(){
var self = this; var self = this;
self.movies = [] self.movies = [];
if(self.mass_edit_select) if(self.mass_edit_select)
self.calculateSelected() self.calculateSelected();
if(self.navigation_alpha) if(self.navigation_alpha)
self.navigation_alpha.getElements('.active').removeClass('active') self.navigation_alpha.getElements('.active').removeClass('active');
self.offset = 0; self.offset = 0;
if(self.scrollspy){ if(self.scrollspy){
@@ -475,7 +475,7 @@ var MovieList = new Class({
activateLetter: function(letter){ activateLetter: function(letter){
var self = this; var self = this;
self.reset() self.reset();
self.letters[letter || 'all'].addClass('active'); self.letters[letter || 'all'].addClass('active');
self.filter.starts_with = letter; self.filter.starts_with = letter;
@@ -487,7 +487,7 @@ var MovieList = new Class({
self.el self.el
.removeClass(self.current_view+'_list') .removeClass(self.current_view+'_list')
.addClass(new_view+'_list') .addClass(new_view+'_list');
self.current_view = new_view; self.current_view = new_view;
Cookie.write(self.options.identifier+'_view2', new_view, {duration: 1000}); Cookie.write(self.options.identifier+'_view2', new_view, {duration: 1000});
@@ -504,9 +504,9 @@ var MovieList = new Class({
if(self.search_timer) clearTimeout(self.search_timer); if(self.search_timer) clearTimeout(self.search_timer);
self.search_timer = (function(){ self.search_timer = (function(){
var search_value = self.navigation_search_input.get('value'); var search_value = self.navigation_search_input.get('value');
if (search_value == self.last_search_value) return if (search_value == self.last_search_value) return;
self.reset() self.reset();
self.activateLetter(); self.activateLetter();
self.filter.search = search_value; self.filter.search = search_value;
@@ -563,7 +563,7 @@ var MovieList = new Class({
if(self.loader_first){ if(self.loader_first){
var lf = self.loader_first; var lf = self.loader_first;
self.loader_first.addClass('hide') self.loader_first.addClass('hide');
self.loader_first = null; self.loader_first = null;
setTimeout(function(){ setTimeout(function(){
lf.destroy(); lf.destroy();
@@ -603,10 +603,10 @@ var MovieList = new Class({
var is_empty = self.movies.length == 0 && (self.total_movies == 0 || self.total_movies === undefined); var is_empty = self.movies.length == 0 && (self.total_movies == 0 || self.total_movies === undefined);
if(self.title) if(self.title)
self.title[is_empty ? 'hide' : 'show']() self.title[is_empty ? 'hide' : 'show']();
if(self.description) if(self.description)
self.description.setStyle('display', [is_empty ? 'none' : '']) self.description.setStyle('display', [is_empty ? 'none' : '']);
if(is_empty && self.options.on_empty_element){ if(is_empty && self.options.on_empty_element){
self.options.on_empty_element.inject(self.loader_first || self.title || self.movie_list, 'after'); self.options.on_empty_element.inject(self.loader_first || self.title || self.movie_list, 'after');
@@ -60,22 +60,6 @@ var MovieAction = new Class({
'z-index': '1' 'z-index': '1'
} }
}).inject(self.movie, 'top').fade('hide'); }).inject(self.movie, 'top').fade('hide');
//self.positionMask();
},
positionMask: function(){
var self = this,
movie = $(self.movie),
s = movie.getSize()
return;
return self.mask.setStyles({
'width': s.x,
'height': s.y
}).position({
'relativeTo': movie
})
}, },
toElement: function(){ toElement: function(){
@@ -122,7 +106,7 @@ MA.Release = new Class({
}); });
if(!self.movie.data.releases || self.movie.data.releases.length == 0) if(!self.movie.data.releases || self.movie.data.releases.length == 0)
self.el.hide() self.el.hide();
else else
self.showHelper(); self.showHelper();
@@ -164,7 +148,7 @@ MA.Release = new Class({
new Element('span.age', {'text': 'Age'}), new Element('span.age', {'text': 'Age'}),
new Element('span.score', {'text': 'Score'}), new Element('span.score', {'text': 'Score'}),
new Element('span.provider', {'text': 'Provider'}) new Element('span.provider', {'text': 'Provider'})
).inject(self.release_container) ).inject(self.release_container);
if(self.movie.data.releases) if(self.movie.data.releases)
self.movie.data.releases.each(function(release){ self.movie.data.releases.each(function(release){
@@ -186,7 +170,7 @@ MA.Release = new Class({
} }
// Create release // Create release
var item = new Element('div', { release['el'] = new Element('div', {
'class': 'item '+release.status, 'class': 'item '+release.status,
'id': 'release_'+release._id 'id': 'release_'+release._id
}).adopt( }).adopt(
@@ -219,7 +203,6 @@ MA.Release = new Class({
} }
}) })
).inject(self.release_container); ).inject(self.release_container);
release['el'] = item;
if(release.status == 'ignored' || release.status == 'failed' || release.status == 'snatched'){ if(release.status == 'ignored' || release.status == 'failed' || release.status == 'snatched'){
if(!self.last_release || (self.last_release && self.last_release.status != 'snatched' && release.status == 'snatched')) if(!self.last_release || (self.last_release && self.last_release.status != 'snatched' && release.status == 'snatched'))
@@ -242,13 +225,13 @@ MA.Release = new Class({
status_el.set('text', new_status); status_el.set('text', new_status);
if(!q && (new_status == 'snatched' || new_status == 'seeding' || new_status == 'done')) if(!q && (new_status == 'snatched' || new_status == 'seeding' || new_status == 'done'))
var q = self.addQuality(release.quality_id); q = self.addQuality(release.quality_id);
if(q && !q.hasClass(new_status)) { if(q && !q.hasClass(new_status)) {
q.removeClass(release.status).addClass(new_status); q.removeClass(release.status).addClass(new_status);
q.set('title', q.get('title').replace(release.status, new_status)); q.set('title', q.get('title').replace(release.status, new_status));
} }
} };
App.on('release.update_status', update_handle); App.on('release.update_status', update_handle);
@@ -391,12 +374,11 @@ MA.Release = new Class({
}, },
ignore: function(release){ ignore: function(release){
var self = this;
Api.request('release.ignore', { Api.request('release.ignore', {
'data': { 'data': {
'id': release._id 'id': release._id
}, }
}) })
}, },
@@ -456,7 +438,7 @@ MA.Trailer = new Class({
watch: function(offset){ watch: function(offset){
var self = this; var self = this;
var data_url = 'https://gdata.youtube.com/feeds/videos?vq="{title}" {year} trailer&max-results=1&alt=json-in-script&orderby=relevance&sortorder=descending&format=5&fmt=18' var data_url = 'https://gdata.youtube.com/feeds/videos?vq="{title}" {year} trailer&max-results=1&alt=json-in-script&orderby=relevance&sortorder=descending&format=5&fmt=18';
var url = data_url.substitute({ var url = data_url.substitute({
'title': encodeURI(self.getTitle()), 'title': encodeURI(self.getTitle()),
'year': self.get('year'), 'year': self.get('year'),
@@ -515,7 +497,7 @@ MA.Trailer = new Class({
} }
} }
} };
self.player.addEventListener('onStateChange', change_quality); self.player.addEventListener('onStateChange', change_quality);
} }
@@ -532,7 +514,7 @@ MA.Trailer = new Class({
$(self.movie).setStyle('height', null); $(self.movie).setStyle('height', null);
setTimeout(function(){ setTimeout(function(){
self.container.destroy() self.container.destroy();
self.close_button.destroy(); self.close_button.destroy();
}, 1800) }, 1800)
} }
@@ -661,7 +643,7 @@ MA.Edit = new Class({
self.movie.slide('out'); self.movie.slide('out');
} }
}) });
MA.Refresh = new Class({ MA.Refresh = new Class({
@@ -847,7 +829,7 @@ MA.Files = new Class({
new Element('div.item.head').adopt( new Element('div.item.head').adopt(
new Element('span.name', {'text': 'File'}), new Element('span.name', {'text': 'File'}),
new Element('span.type', {'text': 'Type'}) new Element('span.type', {'text': 'Type'})
).inject(self.files_container) ).inject(self.files_container);
if(self.movie.data.releases) if(self.movie.data.releases)
Array.each(self.movie.data.releases, function(release){ Array.each(self.movie.data.releases, function(release){
@@ -398,7 +398,6 @@
.movies .data .quality span { .movies .data .quality span {
padding: 2px 3px; padding: 2px 3px;
font-weight: bold;
opacity: 0.5; opacity: 0.5;
font-size: 10px; font-size: 10px;
height: 16px; height: 16px;
@@ -451,7 +450,6 @@
right: 20px; right: 20px;
line-height: 0; line-height: 0;
top: 0; top: 0;
display: block;
width: auto; width: auto;
opacity: 0; opacity: 0;
display: none; display: none;
@@ -833,7 +831,6 @@
} }
.movies .alph_nav .search input { .movies .alph_nav .search input {
padding: 6px 5px;
width: 100%; width: 100%;
height: 44px; height: 44px;
display: inline-block; display: inline-block;
@@ -841,7 +838,6 @@
background: none; background: none;
color: #444; color: #444;
font-size: 14px; font-size: 14px;
padding: 10px;
padding: 0 10px 0 30px; padding: 0 10px 0 30px;
border-bottom: 1px solid rgba(0,0,0,.08); border-bottom: 1px solid rgba(0,0,0,.08);
} }
@@ -1043,7 +1039,6 @@
} }
.movies .progress > div .percentage { .movies .progress > div .percentage {
font-weight: bold;
display: inline-block; display: inline-block;
text-transform: uppercase; text-transform: uppercase;
font-weight: normal; font-weight: normal;
@@ -23,7 +23,7 @@ var Movie = new Class({
addEvents: function(){ addEvents: function(){
var self = this; var self = this;
self.global_events = {} self.global_events = {};
// Do refresh with new data // Do refresh with new data
self.global_events['movie.update'] = function(notification){ self.global_events['movie.update'] = function(notification){
@@ -32,7 +32,7 @@ var Movie = new Class({
self.busy(false); self.busy(false);
self.removeView(); self.removeView();
self.update.delay(2000, self, notification); self.update.delay(2000, self, notification);
} };
App.on('movie.update', self.global_events['movie.update']); App.on('movie.update', self.global_events['movie.update']);
// Add spinner on load / search // Add spinner on load / search
@@ -40,20 +40,20 @@ var Movie = new Class({
self.global_events[listener] = function(notification){ self.global_events[listener] = function(notification){
if(notification.data && (self.data._id == notification.data._id || (typeOf(notification.data._id) == 'array' && notification.data._id.indexOf(self.data._id) > -1))) if(notification.data && (self.data._id == notification.data._id || (typeOf(notification.data._id) == 'array' && notification.data._id.indexOf(self.data._id) > -1)))
self.busy(true); self.busy(true);
} };
App.on(listener, self.global_events[listener]); App.on(listener, self.global_events[listener]);
}) });
// Remove spinner // Remove spinner
self.global_events['movie.searcher.ended'] = function(notification){ self.global_events['movie.searcher.ended'] = function(notification){
if(notification.data && self.data._id == notification.data._id) if(notification.data && self.data._id == notification.data._id)
self.busy(false) self.busy(false)
} };
App.on('movie.searcher.ended', self.global_events['movie.searcher.ended']); App.on('movie.searcher.ended', self.global_events['movie.searcher.ended']);
// Reload when releases have updated // Reload when releases have updated
self.global_events['release.update_status'] = function(notification){ self.global_events['release.update_status'] = function(notification){
var data = notification.data var data = notification.data;
if(data && self.data._id == data.movie_id){ if(data && self.data._id == data.movie_id){
if(!self.data.releases) if(!self.data.releases)
@@ -62,7 +62,7 @@ var Movie = new Class({
self.data.releases.push({'quality': data.quality, 'status': data.status}); self.data.releases.push({'quality': data.quality, 'status': data.status});
self.updateReleases(); self.updateReleases();
} }
} };
App.on('release.update_status', self.global_events['release.update_status']); App.on('release.update_status', self.global_events['release.update_status']);
@@ -73,7 +73,7 @@ var Movie = new Class({
self.el.destroy(); self.el.destroy();
delete self.list.movies_added[self.get('id')]; delete self.list.movies_added[self.get('id')];
self.list.movies.erase(self) self.list.movies.erase(self);
self.list.checkIfEmpty(); self.list.checkIfEmpty();
@@ -117,18 +117,6 @@ var Movie = new Class({
}).inject(self.el, 'top').fade('hide'); }).inject(self.el, 'top').fade('hide');
}, },
positionMask: function(){
var self = this,
s = self.el.getSize()
return self.mask.setStyles({
'width': s.x,
'height': s.y
}).position({
'relativeTo': self.el
})
},
update: function(notification){ update: function(notification){
var self = this; var self = this;
@@ -209,7 +197,7 @@ var Movie = new Class({
self.updateReleases(); self.updateReleases();
Object.each(self.options.actions, function(action, key){ Object.each(self.options.actions, function(action, key){
self.action[key.toLowerCase()] = action = new self.options.actions[key](self) self.action[key.toLowerCase()] = action = new self.options.actions[key](self);
if(action.el) if(action.el)
self.actions.adopt(action) self.actions.adopt(action)
}); });
@@ -226,7 +214,7 @@ var Movie = new Class({
status = release.status; status = release.status;
if(!q && (status == 'snatched' || status == 'seeding' || status == 'done')) if(!q && (status == 'snatched' || status == 'seeding' || status == 'done'))
var q = self.addQuality(release.quality, release.is_3d || false) q = self.addQuality(release.quality, release.is_3d || false);
if (q && !q.hasClass(status)){ if (q && !q.hasClass(status)){
q.addClass(status); q.addClass(status);
@@ -252,9 +240,9 @@ var Movie = new Class({
var self = this; var self = this;
if(self.data.title) if(self.data.title)
return self.getUnprefixedTitle(self.data.title) return self.getUnprefixedTitle(self.data.title);
else if(self.data.info.titles.length > 0) else if(self.data.info.titles.length > 0)
return self.getUnprefixedTitle(self.data.info.titles[0]) return self.getUnprefixedTitle(self.data.info.titles[0]);
return 'Unknown movie' return 'Unknown movie'
}, },
@@ -275,12 +263,12 @@ var Movie = new Class({
self.el.addEvent('outerClick', function(){ self.el.addEvent('outerClick', function(){
self.removeView(); self.removeView();
self.slide('out') self.slide('out')
}) });
el.show(); el.show();
self.data_container.addClass('hide_right'); self.data_container.addClass('hide_right');
} }
else { else {
self.el.removeEvents('outerClick') self.el.removeEvents('outerClick');
setTimeout(function(){ setTimeout(function(){
if(self.el) if(self.el)
@@ -297,7 +285,7 @@ var Movie = new Class({
if(self.el) if(self.el)
self.el self.el
.removeClass(self.view+'_view') .removeClass(self.view+'_view')
.addClass(new_view+'_view') .addClass(new_view+'_view');
self.view = new_view; self.view = new_view;
}, },
@@ -41,7 +41,7 @@ Block.Search.MovieItem = new Class({
) )
) )
) )
) );
if(info.titles) if(info.titles)
info.titles.each(function(title){ info.titles.each(function(title){
@@ -132,19 +132,19 @@ Block.Search.MovieItem = new Class({
if(!self.options_el.hasClass('set')){ if(!self.options_el.hasClass('set')){
if(self.info.in_library){ if(info.in_library){
var in_library = []; var in_library = [];
(self.info.in_library.releases || []).each(function(release){ (info.in_library.releases || []).each(function(release){
in_library.include(release.quality) in_library.include(release.quality)
}); });
} }
self.options_el.grab( self.options_el.grab(
new Element('div', { new Element('div', {
'class': self.info.in_wanted && self.info.in_wanted.profile_id || in_library ? 'in_library_wanted' : '' 'class': info.in_wanted && info.in_wanted.profile_id || in_library ? 'in_library_wanted' : ''
}).adopt( }).adopt(
self.info.in_wanted && self.info.in_wanted.profile_id ? new Element('span.in_wanted', { info.in_wanted && info.in_wanted.profile_id ? new Element('span.in_wanted', {
'text': 'Already in wanted list: ' + Quality.getProfile(self.info.in_wanted.profile_id).get('label') 'text': 'Already in wanted list: ' + Quality.getProfile(info.in_wanted.profile_id).get('label')
}) : (in_library ? new Element('span.in_library', { }) : (in_library ? new Element('span.in_library', {
'text': 'Already in library: ' + in_library.join(', ') 'text': 'Already in library: ' + in_library.join(', ')
}) : null), }) : null),
@@ -172,7 +172,7 @@ Block.Search.MovieItem = new Class({
new Element('option', { new Element('option', {
'text': alt.title 'text': alt.title
}).inject(self.title_select) }).inject(self.title_select)
}) });
// Fill categories // Fill categories
@@ -215,9 +215,9 @@ Block.Search.MovieItem = new Class({
loadingMask: function(){ loadingMask: function(){
var self = this; var self = this;
self.mask = new Element('div.mask').inject(self.el).fade('hide') self.mask = new Element('div.mask').inject(self.el).fade('hide');
createSpinner(self.mask) createSpinner(self.mask);
self.mask.fade('in') self.mask.fade('in')
}, },
@@ -62,7 +62,7 @@ class Bluray(Automation, RSS):
name = self.getTextElement(movie, 'title').lower().split('blu-ray')[0].strip('(').rstrip() name = self.getTextElement(movie, 'title').lower().split('blu-ray')[0].strip('(').rstrip()
year = self.getTextElement(movie, 'description').split('|')[1].strip('(').strip() year = self.getTextElement(movie, 'description').split('|')[1].strip('(').strip()
if not name.find('/') == -1: # make sure it is not a double movie release if not name.find('/') == -1: # make sure it is not a double movie release
continue continue
if tryInt(year) < self.getMinimal('year'): if tryInt(year) < self.getMinimal('year'):
@@ -46,7 +46,10 @@ class Goodfilms(Automation):
break break
for movie in this_watch_list: for movie in this_watch_list:
movies.append({ 'title': movie['data-film-title'], 'year': movie['data-film-year'] }) movies.append({
'title': movie['data-film-title'],
'year': movie['data-film-year']
})
if not 'next page' in data.lower(): if not 'next page' in data.lower():
break break
@@ -50,7 +50,10 @@ class Letterboxd(Automation):
for movie in soup.find_all('a', attrs = {'class': 'frame'}): for movie in soup.find_all('a', attrs = {'class': 'frame'}):
match = removeEmpty(self.pattern.split(movie['title'])) match = removeEmpty(self.pattern.split(movie['title']))
movies.append({'title': match[0], 'year': match[1] }) movies.append({
'title': match[0],
'year': match[1]
})
return movies return movies
@@ -74,6 +74,7 @@ class TheMovieDb(MovieProvider):
if not result: if not result:
try: try:
log.debug('Getting info: %s', cache_key) log.debug('Getting info: %s', cache_key)
# noinspection PyArgumentList
movie = tmdb3.Movie(identifier) movie = tmdb3.Movie(identifier)
try: exists = movie.title is not None try: exists = movie.title is not None
except: exists = False except: exists = False
@@ -14,6 +14,6 @@ class BiTHDTV(MovieProvider, Base):
def buildUrl(self, media): def buildUrl(self, media):
query = tryUrlencode({ query = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('library.query', media, single = True),
'cat': 7 # Movie cat 'cat': 7 # Movie cat
}) })
return query return query
@@ -10,29 +10,29 @@ autoload = 'PassThePopcorn'
class PassThePopcorn(MovieProvider, Base): class PassThePopcorn(MovieProvider, Base):
quality_search_params = { quality_search_params = {
'bd50': {'media': 'Blu-ray', 'format': 'BD50'}, 'bd50': {'media': 'Blu-ray', 'format': 'BD50'},
'1080p': {'resolution': '1080p'}, '1080p': {'resolution': '1080p'},
'720p': {'resolution': '720p'}, '720p': {'resolution': '720p'},
'brrip': {'media': 'Blu-ray'}, 'brrip': {'media': 'Blu-ray'},
'dvdr': {'resolution': 'anysd'}, 'dvdr': {'resolution': 'anysd'},
'dvdrip': {'media': 'DVD'}, 'dvdrip': {'media': 'DVD'},
'scr': {'media': 'DVD-Screener'}, 'scr': {'media': 'DVD-Screener'},
'r5': {'media': 'R5'}, 'r5': {'media': 'R5'},
'tc': {'media': 'TC'}, 'tc': {'media': 'TC'},
'ts': {'media': 'TS'}, 'ts': {'media': 'TS'},
'cam': {'media': 'CAM'} 'cam': {'media': 'CAM'}
} }
post_search_filters = { post_search_filters = {
'bd50': {'Codec': ['BD50']}, 'bd50': {'Codec': ['BD50']},
'1080p': {'Resolution': ['1080p']}, '1080p': {'Resolution': ['1080p']},
'720p': {'Resolution': ['720p']}, '720p': {'Resolution': ['720p']},
'brrip': {'Source': ['Blu-ray'], 'Quality': ['High Definition'], 'Container': ['!ISO']}, 'brrip': {'Source': ['Blu-ray'], 'Quality': ['High Definition'], 'Container': ['!ISO']},
'dvdr': {'Codec': ['DVD5', 'DVD9']}, 'dvdr': {'Codec': ['DVD5', 'DVD9']},
'dvdrip': {'Source': ['DVD'], 'Codec': ['!DVD5', '!DVD9']}, 'dvdrip': {'Source': ['DVD'], 'Codec': ['!DVD5', '!DVD9']},
'scr': {'Source': ['DVD-Screener']}, 'scr': {'Source': ['DVD-Screener']},
'r5': {'Source': ['R5']}, 'r5': {'Source': ['R5']},
'tc': {'Source': ['TC']}, 'tc': {'Source': ['TC']},
'ts': {'Source': ['TS']}, 'ts': {'Source': ['TS']},
'cam': {'Source': ['CAM']} 'cam': {'Source': ['CAM']}
} }
@@ -12,11 +12,11 @@ autoload = 'ThePirateBay'
class ThePirateBay(MovieProvider, Base): class ThePirateBay(MovieProvider, Base):
cat_ids = [ cat_ids = [
([209], ['3d']), ([209], ['3d']),
([207], ['720p', '1080p']), ([207], ['720p', '1080p']),
([201], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']), ([201], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']),
([201, 207], ['brrip']), ([201, 207], ['brrip']),
([202], ['dvdr']) ([202], ['dvdr'])
] ]
def buildUrl(self, media, page, cats): def buildUrl(self, media, page, cats):
@@ -16,5 +16,6 @@ class TorrentDay(MovieProvider, Base):
([3], ['dvdr']), ([3], ['dvdr']),
([5], ['bd50']), ([5], ['bd50']),
] ]
def buildUrl(self, media): def buildUrl(self, media):
return fireEvent('library.query', media, single = True) return fireEvent('library.query', media, single = True)
@@ -52,7 +52,7 @@ class HDTrailers(TrailerProvider):
return result_data return result_data
def findViaAlternative(self, group): def findViaAlternative(self, group):
results = {'480p':[], '720p':[], '1080p':[]} results = {'480p': [], '720p': [], '1080p': []}
movie_name = getTitle(group) movie_name = getTitle(group)
-1
View File
@@ -249,7 +249,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase):
log.info2('Wrong: "%s" is too large to be %s. %sMB instead of the maximum of %sMB.', (nzb['name'], preferred_quality['label'], nzb['size'], preferred_quality['size_max'])) log.info2('Wrong: "%s" is too large to be %s. %sMB instead of the maximum of %sMB.', (nzb['name'], preferred_quality['label'], nzb['size'], preferred_quality['size_max']))
return False return False
# Provider specific functions # Provider specific functions
get_more = nzb.get('get_more_info') get_more = nzb.get('get_more_info')
if get_more: if get_more:
@@ -91,7 +91,6 @@
padding: 0 3px 10px 0; padding: 0 3px 10px 0;
} }
.suggestions .media_result .data:before { .suggestions .media_result .data:before {
bottom: 0;
content: ''; content: '';
display: block; display: block;
height: 10px; height: 10px;
@@ -107,7 +106,7 @@
z-index: 3; z-index: 3;
pointer-events: none; pointer-events: none;
} }
.suggestions .media_result .data .info .plot.full { .suggestions .media_result .data .info .plot.full {
top: 0; top: 0;
overflow: auto; overflow: auto;
@@ -123,14 +122,14 @@
.suggestions .media_result .options select[name=title] { width: 100%; } .suggestions .media_result .options select[name=title] { width: 100%; }
.suggestions .media_result .options select[name=profile] { width: 100%; } .suggestions .media_result .options select[name=profile] { width: 100%; }
.suggestions .media_result .options select[name=category] { width: 100%; } .suggestions .media_result .options select[name=category] { width: 100%; }
.suggestions .media_result .button { .suggestions .media_result .button {
position: absolute; position: absolute;
margin: 2px 0 0 0; margin: 2px 0 0 0;
right: 15px; right: 15px;
bottom: 15px; bottom: 15px;
} }
.suggestions .media_result .thumbnail { .suggestions .media_result .thumbnail {
width: 100px; width: 100px;
@@ -116,7 +116,7 @@ var SuggestList = new Class({
} }
} }
}) : null }) : null
) );
$(m).inject(self.el); $(m).inject(self.el);
@@ -150,4 +150,4 @@ var SuggestList = new Class({
return this.el; return this.el;
} }
}) });
+1 -1
View File
@@ -131,7 +131,7 @@ class CoreNotifier(Notification):
for message in messages: for message in messages:
if message.get('time') > last_check: if message.get('time') > last_check:
message['sticky'] = True # Always sticky core messages message['sticky'] = True # Always sticky core messages
message_type = 'core.message.important' if message.get('important') else 'core.message' message_type = 'core.message.important' if message.get('important') else 'core.message'
fireEvent(message_type, message = message.get('message'), data = message) fireEvent(message_type, message = message.get('message'), data = message)
@@ -17,14 +17,14 @@ var NotificationBase = new Class({
App.addEvent('load', self.addTestButtons.bind(self)); App.addEvent('load', self.addTestButtons.bind(self));
// Notification bar // Notification bar
self.notifications = [] self.notifications = [];
App.addEvent('load', function(){ App.addEvent('load', function(){
App.block.notification = new Block.Menu(self, { App.block.notification = new Block.Menu(self, {
'button_class': 'icon2.eye-open', 'button_class': 'icon2.eye-open',
'class': 'notification_menu', 'class': 'notification_menu',
'onOpen': self.markAsRead.bind(self) 'onOpen': self.markAsRead.bind(self)
}) });
$(App.block.notification).inject(App.getBlock('search'), 'after'); $(App.block.notification).inject(App.getBlock('search'), 'after');
self.badge = new Element('div.badge').inject(App.block.notification, 'top').hide(); self.badge = new Element('div.badge').inject(App.block.notification, 'top').hide();
@@ -40,7 +40,7 @@ var NotificationBase = new Class({
var self = this; var self = this;
var added = new Date(); var added = new Date();
added.setTime(result.added*1000) added.setTime(result.added*1000);
result.el = App.getBlock('notification').addLink( result.el = App.getBlock('notification').addLink(
new Element('span.'+(result.read ? 'read' : '' )).adopt( new Element('span.'+(result.read ? 'read' : '' )).adopt(
@@ -51,7 +51,7 @@ var NotificationBase = new Class({
self.notifications.include(result); self.notifications.include(result);
if((result.data.important !== undefined || result.data.sticky !== undefined) && !result.read){ if((result.data.important !== undefined || result.data.sticky !== undefined) && !result.read){
var sticky = true var sticky = true;
App.trigger('message', [result.message, sticky, result]) App.trigger('message', [result.message, sticky, result])
} }
else if(!result.read){ else if(!result.read){
@@ -62,7 +62,7 @@ var NotificationBase = new Class({
setBadge: function(value){ setBadge: function(value){
var self = this; var self = this;
self.badge.set('text', value) self.badge.set('text', value);
self.badge[value ? 'show' : 'hide']() self.badge[value ? 'show' : 'hide']()
}, },
@@ -73,9 +73,9 @@ var NotificationBase = new Class({
if(!force_ids) { if(!force_ids) {
var rn = self.notifications.filter(function(n){ var rn = self.notifications.filter(function(n){
return !n.read && n.data.important === undefined return !n.read && n.data.important === undefined
}) });
var ids = [] var ids = [];
rn.each(function(n){ rn.each(function(n){
ids.include(n._id) ids.include(n._id)
}) })
@@ -106,7 +106,7 @@ var NotificationBase = new Class({
'onSuccess': function(json){ 'onSuccess': function(json){
self.processData(json, true) self.processData(json, true)
} }
}).send() }).send();
setInterval(function(){ setInterval(function(){
@@ -141,7 +141,7 @@ var NotificationBase = new Class({
stopPoll: function(){ stopPoll: function(){
if(this.request) if(this.request)
this.request.cancel() this.request.cancel();
this.stopped = true; this.stopped = true;
}, },
@@ -154,7 +154,7 @@ var NotificationBase = new Class({
App.trigger(result._t || result.type, [result]); App.trigger(result._t || result.type, [result]);
if(result.message && result.read === undefined && !init) if(result.message && result.read === undefined && !init)
self.showMessage(result.message); self.showMessage(result.message);
}) });
if(json.result.length > 0) if(json.result.length > 0)
self.last_id = json.result.getLast().message_id self.last_id = json.result.getLast().message_id
@@ -180,11 +180,11 @@ var NotificationBase = new Class({
}, 10); }, 10);
var hide_message = function(){ var hide_message = function(){
new_message.addClass('hide') new_message.addClass('hide');
setTimeout(function(){ setTimeout(function(){
new_message.destroy(); new_message.destroy();
}, 1000); }, 1000);
} };
if(sticky) if(sticky)
new_message.grab( new_message.grab(
@@ -206,7 +206,7 @@ var NotificationBase = new Class({
addTestButtons: function(){ addTestButtons: function(){
var self = this; var self = this;
var setting_page = App.getPage('Settings') var setting_page = App.getPage('Settings');
setting_page.addEvent('create', function(){ setting_page.addEvent('create', function(){
Object.each(setting_page.tabs.notifications.groups, self.addTestButton.bind(self)) Object.each(setting_page.tabs.notifications.groups, self.addTestButton.bind(self))
}) })
+2 -1
View File
@@ -97,7 +97,8 @@ config = [{
'name': 'smtp_server', 'name': 'smtp_server',
'label': 'SMTP server', 'label': 'SMTP server',
}, },
{ 'name': 'smtp_port', {
'name': 'smtp_port',
'label': 'SMTP server port', 'label': 'SMTP server port',
'default': '25', 'default': '25',
'type': 'int', 'type': 'int',
+2
View File
@@ -19,6 +19,8 @@ class Growl(Notification):
def __init__(self): def __init__(self):
super(Growl, self).__init__() super(Growl, self).__init__()
self.growl = None
if self.isEnabled(): if self.isEnabled():
addEvent('app.load', self.register) addEvent('app.load', self.register)
+1
View File
@@ -20,6 +20,7 @@ autoload = 'NMJ'
class NMJ(Notification): class NMJ(Notification):
# noinspection PyMissingConstructor
def __init__(self): def __init__(self):
addEvent('renamer.after', self.addToLibrary) addEvent('renamer.after', self.addToLibrary)
addApiView(self.testNotifyName(), self.test) addApiView(self.testNotifyName(), self.test)
+1 -1
View File
@@ -30,7 +30,7 @@ class Pushalot(Notification):
} }
headers = { headers = {
'Content-type': 'application/x-www-form-urlencoded' 'Content-type': 'application/x-www-form-urlencoded'
} }
try: try:
+3 -4
View File
@@ -33,10 +33,9 @@ class Pushover(Notification):
'url_title': toUnicode('%s on IMDb' % getTitle(data)), 'url_title': toUnicode('%s on IMDb' % getTitle(data)),
}) })
http_handler.request('POST', http_handler.request('POST', '/1/messages.json',
"/1/messages.json", headers = {'Content-type': 'application/x-www-form-urlencoded'},
headers = {'Content-type': 'application/x-www-form-urlencoded'}, body = tryUrlencode(api_data)
body = tryUrlencode(api_data)
) )
response = http_handler.getresponse() response = http_handler.getresponse()
@@ -59,7 +59,7 @@ var TwitterNotification = new Class({
).inject(fieldset.getElement('.test_button'), 'before'); ).inject(fieldset.getElement('.test_button'), 'before');
}) })
}, }
}); });
+1 -1
View File
@@ -89,7 +89,7 @@ class XBMC(Notification):
self.use_json_notifications[host] = False self.use_json_notifications[host] = False
# 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 r in resp: for r in resp:
if r.get('result') and r['result'] == 'OK': if r.get('result') and r['result'] == 'OK':
log.debug('Message delivered successfully!') log.debug('Message delivered successfully!')
+4 -3
View File
@@ -43,8 +43,8 @@ class Plugin(object):
http_failed_disabled = {} http_failed_disabled = {}
http_opener = requests.Session() http_opener = requests.Session()
def __new__(typ, *args, **kwargs): def __new__(cls, *args, **kwargs):
new_plugin = super(Plugin, typ).__new__(typ) new_plugin = super(Plugin, cls).__new__(cls)
new_plugin.registerPlugin() new_plugin.registerPlugin()
return new_plugin return new_plugin
@@ -329,7 +329,7 @@ class Plugin(object):
elif data.get('password'): elif data.get('password'):
tag += '{{%s}}' % data.get('password') tag += '{{%s}}' % data.get('password')
max_length = 127 - len(tag) # Some filesystems don't support 128+ long filenames max_length = 127 - len(tag) # Some filesystems don't support 128+ long filenames
return '%s%s' % (toSafeString(toUnicode(release_name)[:max_length]), tag) return '%s%s' % (toSafeString(toUnicode(release_name)[:max_length]), tag)
def createFileName(self, data, filedata, media): def createFileName(self, data, filedata, media):
@@ -349,6 +349,7 @@ class Plugin(object):
now = time.time() now = time.time()
file_too_new = False file_too_new = False
file_time = []
for cur_file in files: for cur_file in files:
# File got removed while checking # File got removed while checking
+2 -1
View File
@@ -17,7 +17,8 @@ if os.name == 'nt':
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 # noinspection PyUnresolvedReferences
import win32file
autoload = 'FileBrowser' autoload = 'FileBrowser'
@@ -9,7 +9,7 @@ var CategoryListBase = new Class({
setup: function(categories){ setup: function(categories){
var self = this; var self = this;
self.categories = [] self.categories = [];
Array.each(categories, self.createCategory.bind(self)); Array.each(categories, self.createCategory.bind(self));
}, },
@@ -17,7 +17,7 @@ var CategoryListBase = new Class({
addSettings: function(){ addSettings: function(){
var self = this; var self = this;
self.settings = App.getPage('Settings') self.settings = App.getPage('Settings');
self.settings.addEvent('create', function(){ self.settings.addEvent('create', function(){
var tab = self.settings.createSubTab('category', { var tab = self.settings.createSubTab('category', {
'label': 'Categories', 'label': 'Categories',
@@ -31,7 +31,7 @@ var CategoryListBase = new Class({
self.createList(); self.createList();
self.createOrdering(); self.createOrdering();
}) });
// Add categories in renamer // Add categories in renamer
self.settings.addEvent('create', function(){ self.settings.addEvent('create', function(){
@@ -97,9 +97,9 @@ var CategoryListBase = new Class({
createCategory: function(data){ createCategory: function(data){
var self = this; var self = this;
var data = data || {'id': randomString()} var data = data || {'id': randomString()};
var category = new Category(data) var category = new Category(data);
self.categories.include(category) self.categories.include(category);
return category; return category;
}, },
@@ -108,7 +108,7 @@ var CategoryListBase = new Class({
var self = this; var self = this;
var category_list; var category_list;
var group = self.settings.createGroup({ self.settings.createGroup({
'label': 'Category ordering' 'label': 'Category ordering'
}).adopt( }).adopt(
new Element('.ctrlHolder#category_ordering').adopt( new Element('.ctrlHolder#category_ordering').adopt(
@@ -118,7 +118,7 @@ var CategoryListBase = new Class({
'html': 'Change the order the categories are in the dropdown list.<br />First one will be default.' 'html': 'Change the order the categories are in the dropdown list.<br />First one will be default.'
}) })
) )
).inject(self.content) ).inject(self.content);
Array.each(self.categories, function(category){ Array.each(self.categories, function(category){
new Element('li', {'data-id': category.data._id}).adopt( new Element('li', {'data-id': category.data._id}).adopt(
@@ -145,7 +145,7 @@ var CategoryListBase = new Class({
var ids = []; var ids = [];
self.category_sortable.list.getElements('li').each(function(el, nr){ self.category_sortable.list.getElements('li').each(function(el){
ids.include(el.get('data-id')); ids.include(el.get('data-id'));
}); });
@@ -157,7 +157,7 @@ var CategoryListBase = new Class({
} }
}) });
window.CategoryList = new CategoryListBase(); window.CategoryList = new CategoryListBase();
@@ -235,8 +235,6 @@ var Category = new Class({
if(self.save_timer) clearTimeout(self.save_timer); if(self.save_timer) clearTimeout(self.save_timer);
self.save_timer = (function(){ self.save_timer = (function(){
var data = self.getData();
Api.request('category.save', { Api.request('category.save', {
'data': self.getData(), 'data': self.getData(),
'useSpinner': true, 'useSpinner': true,
@@ -257,7 +255,7 @@ var Category = new Class({
getData: function(){ getData: function(){
var self = this; var self = this;
var data = { return {
'id' : self.data._id, 'id' : self.data._id,
'label' : self.el.getElement('.category_label input').get('value'), 'label' : self.el.getElement('.category_label input').get('value'),
'required' : self.el.getElement('.category_required input').get('value'), 'required' : self.el.getElement('.category_required input').get('value'),
@@ -265,8 +263,6 @@ var Category = new Class({
'ignored' : self.el.getElement('.category_ignored input').get('value'), 'ignored' : self.el.getElement('.category_ignored input').get('value'),
'destination': self.data.destination 'destination': self.data.destination
} }
return data
}, },
del: function(){ del: function(){
+2 -2
View File
@@ -77,8 +77,8 @@ class Dashboard(Plugin):
if coming_soon: if coming_soon:
# Don't list older movies # Don't list older movies
if ((not late and (media['info']['year'] >= now_year-1) 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 (media['info']['year'] >= now_year - 1) and (not eta.get('dvd') and not eta.get('theater') or eta.get('dvd') and eta.get('dvd') > (now - 2419200))) or
(late and ((media['info']['year'] < now_year-1) or ((eta.get('dvd', 0) > 0 or eta.get('theater')) and eta.get('dvd') < (now - 2419200))))): (late and (media['info']['year'] < now_year - 1 or (eta.get('dvd', 0) > 0 or eta.get('theater')) and eta.get('dvd') < (now - 2419200)))):
medias.append(media) medias.append(media)
if len(medias) >= limit: if len(medias) >= limit:
+1 -2
View File
@@ -1,5 +1,4 @@
import os.path import os.path
import time
import traceback import traceback
from couchpotato import get_db from couchpotato import get_db
@@ -64,7 +63,7 @@ class FileManager(Plugin):
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 = {}
if not dest: # to Cache if not dest: # to Cache
dest = os.path.join(Env.get('cache_dir'), '%s.%s' % (md5(url), getExt(url))) dest = os.path.join(Env.get('cache_dir'), '%s.%s' % (md5(url), getExt(url)))
if not overwrite and os.path.isfile(dest): if not overwrite and os.path.isfile(dest):
+3 -3
View File
@@ -67,14 +67,14 @@ class Logging(Plugin):
if x is nr: if x is nr:
current_path = path current_path = path
log = '' log_content = ''
if current_path: if current_path:
f = open(current_path, 'r') f = open(current_path, 'r')
log = f.read() log_content = f.read()
return { return {
'success': True, 'success': True,
'log': toUnicode(log), 'log': toUnicode(log_content),
'total': total, 'total': total,
} }
+1 -1
View File
@@ -50,7 +50,7 @@
overflow: hidden; overflow: hidden;
line-height: 150%; line-height: 150%;
font-size: 11px; font-size: 11px;
font-family: Lucida Console, Monaco, Nimbus Mono L; font-family: Lucida Console, Monaco, Nimbus Mono L, monospace, serif;
} }
.page.log .container .error { .page.log .container .error {
+3 -4
View File
@@ -42,7 +42,7 @@ Page.Log = new Class({
} }
} }
}).inject(nav); }).inject(nav);
}; }
new Element('li', { new Element('li', {
'text': 'clear', 'text': 'clear',
@@ -63,7 +63,6 @@ Page.Log = new Class({
}, },
addColors: function(text){ addColors: function(text){
var self = this;
text = text text = text
.replace(/&/g, '&amp;') .replace(/&/g, '&amp;')
@@ -74,9 +73,9 @@ Page.Log = new Class({
.replace(/\u001b\[36m/gi, '</span><span class="debug">') .replace(/\u001b\[36m/gi, '</span><span class="debug">')
.replace(/\u001b\[33m/gi, '</span><span class="debug">') .replace(/\u001b\[33m/gi, '</span><span class="debug">')
.replace(/\u001b\[0m\n/gi, '</div><div class="time">') .replace(/\u001b\[0m\n/gi, '</div><div class="time">')
.replace(/\u001b\[0m/gi, '</span><span>') .replace(/\u001b\[0m/gi, '</span><span>');
return '<div class="time">' + text + '</div>'; return '<div class="time">' + text + '</div>';
} }
}) });
+3 -5
View File
@@ -160,7 +160,7 @@ class Manage(Plugin):
except: except:
log.error('Failed updating library: %s', (traceback.format_exc())) log.error('Failed updating library: %s', (traceback.format_exc()))
while True and not self.shuttingDown(): while self.in_progress and len(self.in_progress) > 0 and not self.shuttingDown():
delete_me = {} delete_me = {}
@@ -171,14 +171,12 @@ class Manage(Plugin):
for delete in delete_me: for delete in delete_me:
del self.in_progress[delete] del self.in_progress[delete]
if len(self.in_progress) == 0:
break
time.sleep(1) time.sleep(1)
fireEvent('notify.frontend', type = 'manage.updating', data = False) fireEvent('notify.frontend', type = 'manage.updating', data = False)
self.in_progress = False self.in_progress = False
# noinspection PyDefaultArgument
def createAddToLibrary(self, folder, added_identifiers = []): def createAddToLibrary(self, folder, added_identifiers = []):
def addToLibrary(group, total_found, to_go): def addToLibrary(group, total_found, to_go):
@@ -219,7 +217,7 @@ class Manage(Plugin):
pr = self.in_progress[folder] pr = self.in_progress[folder]
pr['to_go'] -= 1 pr['to_go'] -= 1
avg = (time.time() - pr['started'])/(pr['total'] - pr['to_go']) avg = (time.time() - pr['started']) / (pr['total'] - pr['to_go'])
pr['eta'] = tryInt(avg * pr['to_go']) pr['eta'] = tryInt(avg * pr['to_go'])
@@ -119,7 +119,7 @@ var Profile = new Class({
'label' : self.el.getElement('.quality_label input').get('value'), 'label' : self.el.getElement('.quality_label input').get('value'),
'wait_for' : self.el.getElement('.wait_for input').get('value'), 'wait_for' : self.el.getElement('.wait_for input').get('value'),
'types': [] 'types': []
} };
Array.each(self.type_container.getElements('.type'), function(type){ Array.each(self.type_container.getElements('.type'), function(type){
if(!type.hasClass('deleted') && type.getElement('select').get('value') != -1) if(!type.hasClass('deleted') && type.getElement('select').get('value') != -1)
@@ -129,7 +129,7 @@ var Profile = new Class({
'3d': +type.getElement('input.3d[type=checkbox]').checked, '3d': +type.getElement('input.3d[type=checkbox]').checked,
'wait_for': 0 'wait_for': 0
}); });
}) });
return data return data
}, },
@@ -261,10 +261,10 @@ Profile.Type = new Class({
self.finish = new Element('input.inlay.finish[type=checkbox]', { self.finish = new Element('input.inlay.finish[type=checkbox]', {
'checked': data.finish !== undefined ? data.finish : 1, 'checked': data.finish !== undefined ? data.finish : 1,
'events': { 'events': {
'change': function(e){ 'change': function(){
if(self.el == self.el.getParent().getElement(':first-child')){ if(self.el == self.el.getParent().getElement(':first-child')){
self.finish_class.check(); self.finish_class.check();
alert('Top quality always finishes the search') alert('Top quality always finishes the search');
return; return;
} }
@@ -280,7 +280,7 @@ Profile.Type = new Class({
self['3d'] = new Element('input.inlay.3d[type=checkbox]', { self['3d'] = new Element('input.inlay.3d[type=checkbox]', {
'checked': data['3d'] !== undefined ? data['3d'] : 0, 'checked': data['3d'] !== undefined ? data['3d'] : 0,
'events': { 'events': {
'change': function(e){ 'change': function(){
self.fireEvent('change'); self.fireEvent('change');
} }
} }
@@ -363,4 +363,4 @@ Profile.Type = new Class({
return this.el; return this.el;
} }
}) });
+3 -2
View File
@@ -63,6 +63,7 @@ class QualityPlugin(Plugin):
addEvent('app.test', self.doTest) addEvent('app.test', self.doTest)
self.order = []
self.addOrder() self.addOrder()
def addOrder(self): def addOrder(self):
@@ -247,12 +248,12 @@ class QualityPlugin(Plugin):
qualities = [qualities] if isinstance(qualities, (str, unicode)) else qualities qualities = [qualities] if isinstance(qualities, (str, unicode)) else qualities
for alt in qualities: for alt in qualities:
if (isinstance(alt, tuple)): if isinstance(alt, tuple):
if len(set(words) & set(alt)) == len(alt): if len(set(words) & set(alt)) == len(alt):
log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file)) log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file))
score += points.get(tag_type) score += points.get(tag_type)
if (isinstance(alt, (str, unicode)) and ss(alt.lower()) in cur_file.lower()): if isinstance(alt, (str, unicode)) and ss(alt.lower()) in cur_file.lower():
log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file)) log.debug('Found %s via %s %s in %s', (quality['identifier'], tag_type, quality.get(tag_type), cur_file))
score += points.get(tag_type) / 2 score += points.get(tag_type) / 2
@@ -8,7 +8,7 @@ var QualityBase = new Class({
self.qualities = data.qualities; self.qualities = data.qualities;
self.profiles = [] self.profiles = [];
Array.each(data.profiles, self.createProfilesClass.bind(self)); Array.each(data.profiles, self.createProfilesClass.bind(self));
App.addEvent('load', self.addSettings.bind(self)) App.addEvent('load', self.addSettings.bind(self))
@@ -37,7 +37,7 @@ var QualityBase = new Class({
addSettings: function(){ addSettings: function(){
var self = this; var self = this;
self.settings = App.getPage('Settings') self.settings = App.getPage('Settings');
self.settings.addEvent('create', function(){ self.settings.addEvent('create', function(){
var tab = self.settings.createSubTab('profile', { var tab = self.settings.createSubTab('profile', {
'label': 'Quality', 'label': 'Quality',
@@ -91,9 +91,9 @@ var QualityBase = new Class({
createProfilesClass: function(data){ createProfilesClass: function(data){
var self = this; var self = this;
var data = data || {'id': randomString()} var data = data || {'id': randomString()};
var profile = new Profile(data) var profile = new Profile(data);
self.profiles.include(profile) self.profiles.include(profile);
return profile; return profile;
}, },
@@ -102,7 +102,7 @@ var QualityBase = new Class({
var self = this; var self = this;
var profile_list; var profile_list;
var group = self.settings.createGroup({ self.settings.createGroup({
'label': 'Profile Defaults', 'label': 'Profile Defaults',
'description': '(Needs refresh \'' +(App.isMac() ? 'CMD+R' : 'F5')+ '\' after editing)' 'description': '(Needs refresh \'' +(App.isMac() ? 'CMD+R' : 'F5')+ '\' after editing)'
}).adopt( }).adopt(
@@ -113,7 +113,7 @@ var QualityBase = new Class({
'html': 'Change the order the profiles are in the dropdown list. Uncheck to hide it completely.<br />First one will be default.' 'html': 'Change the order the profiles are in the dropdown list. Uncheck to hide it completely.<br />First one will be default.'
}) })
) )
).inject(self.content) ).inject(self.content);
Array.each(self.profiles, function(profile){ Array.each(self.profiles, function(profile){
var check; var check;
@@ -175,14 +175,14 @@ var QualityBase = new Class({
'description': 'Edit the minimal and maximum sizes (in MB) for each quality.', 'description': 'Edit the minimal and maximum sizes (in MB) for each quality.',
'advanced': true, 'advanced': true,
'name': 'sizes' 'name': 'sizes'
}).inject(self.content) }).inject(self.content);
new Element('div.item.head.ctrlHolder').adopt( new Element('div.item.head.ctrlHolder').adopt(
new Element('span.label', {'text': 'Quality'}), new Element('span.label', {'text': 'Quality'}),
new Element('span.min', {'text': 'Min'}), new Element('span.min', {'text': 'Min'}),
new Element('span.max', {'text': 'Max'}) new Element('span.max', {'text': 'Max'})
).inject(group) ).inject(group);
Array.each(self.qualities, function(quality){ Array.each(self.qualities, function(quality){
new Element('div.ctrlHolder.item').adopt( new Element('div.ctrlHolder.item').adopt(
+6 -6
View File
@@ -148,7 +148,7 @@ class Renamer(Plugin):
log.debug('The provided media folder %s does not exist. Trying to find it in the \'from\' folder.', media_folder) log.debug('The provided media folder %s does not exist. Trying to find it in the \'from\' folder.', media_folder)
# Update to the from folder # Update to the from folder
if len(release_download.get('files'), []) == 1: if len(release_download.get('files', [])) == 1:
new_media_folder = from_folder new_media_folder = from_folder
else: else:
new_media_folder = os.path.join(from_folder, os.path.basename(media_folder)) new_media_folder = os.path.join(from_folder, os.path.basename(media_folder))
@@ -504,7 +504,7 @@ class Renamer(Plugin):
fireEvent('release.update_status', release['_id'], status = 'downloaded', single = True) fireEvent('release.update_status', release['_id'], status = 'downloaded', single = True)
# Remove leftover files # Remove leftover files
if not remove_leftovers: # Don't remove anything if not remove_leftovers: # Don't remove anything
break break
log.debug('Removing leftover files') log.debug('Removing leftover files')
@@ -529,8 +529,8 @@ class Renamer(Plugin):
parent_dir = os.path.dirname(src) parent_dir = os.path.dirname(src)
if delete_folders.count(parent_dir) == 0 and os.path.isdir(parent_dir) and \ if delete_folders.count(parent_dir) == 0 and os.path.isdir(parent_dir) and \
not isSubFolder(destination, parent_dir) and not isSubFolder(media_folder, parent_dir) and \ not isSubFolder(destination, parent_dir) and not isSubFolder(media_folder, parent_dir) and \
not isSubFolder(parent_dir, base_folder): not isSubFolder(parent_dir, base_folder):
delete_folders.append(parent_dir) delete_folders.append(parent_dir)
@@ -659,7 +659,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
for filename in tag_files: for filename in tag_files:
# Dont tag .ignore files # Don't tag .ignore files
if os.path.splitext(filename)[1] == '.ignore': if os.path.splitext(filename)[1] == '.ignore':
continue continue
@@ -1017,7 +1017,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
if release_download['pause'] and self.conf('file_action') == 'link': if release_download['pause'] and self.conf('file_action') == 'link':
fireEvent('download.pause', release_download = release_download, pause = False, single = True) fireEvent('download.pause', release_download = release_download, pause = False, single = True)
if release_download['process_complete']: if release_download['process_complete']:
#First make sure the files were succesfully processed # First make sure the files were successfully processed
if not self.hastagRelease(release_download = release_download, tag = 'failed_rename'): if not self.hastagRelease(release_download = release_download, tag = 'failed_rename'):
# Remove the seeding tag if it exists # Remove the seeding tag if it exists
self.untagRelease(release_download = release_download, tag = 'renamed_already') self.untagRelease(release_download = release_download, tag = 'renamed_already')
+4 -3
View File
@@ -28,7 +28,7 @@ class Scanner(Plugin):
ignored_in_path = [os.path.sep + 'extracted' + os.path.sep, 'extracting', '_unpack', '_failed_', '_unknown_', '_exists_', '_failed_remove_', ignored_in_path = [os.path.sep + 'extracted' + os.path.sep, 'extracting', '_unpack', '_failed_', '_unknown_', '_exists_', '_failed_remove_',
'_failed_rename_', '.appledouble', '.appledb', '.appledesktop', os.path.sep + '._', '.ds_store', 'cp.cpnfo', '_failed_rename_', '.appledouble', '.appledb', '.appledesktop', os.path.sep + '._', '.ds_store', 'cp.cpnfo',
'thumbs.db', 'ehthumbs.db', 'desktop.ini'] #unpacking, smb-crap, hidden files 'thumbs.db', 'ehthumbs.db', 'desktop.ini'] # unpacking, smb-crap, hidden files
ignore_names = ['extract', 'extracting', 'extracted', 'movie', 'movies', 'film', 'films', 'download', 'downloads', 'video_ts', 'audio_ts', 'bdmv', 'certificate'] ignore_names = ['extract', 'extracting', 'extracted', 'movie', 'movies', 'film', 'films', 'download', 'downloads', 'video_ts', 'audio_ts', 'bdmv', 'certificate']
extensions = { extensions = {
'movie': ['mkv', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4', 'm2ts', 'iso', 'img', 'mdf', 'ts', 'm4v'], 'movie': ['mkv', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4', 'm2ts', 'iso', 'img', 'mdf', 'ts', 'm4v'],
@@ -589,7 +589,7 @@ class Scanner(Plugin):
if len(movie) > 0: if len(movie) > 0:
imdb_id = movie[0].get('imdb') imdb_id = movie[0].get('imdb')
log.debug('Found movie via search: %s', cur_file) log.debug('Found movie via search: %s', identifier)
if imdb_id: break if imdb_id: break
else: else:
log.debug('Identifier to short to use for search: %s', identifier) log.debug('Identifier to short to use for search: %s', identifier)
@@ -835,6 +835,7 @@ class Scanner(Plugin):
cleaned = ' '.join(re.split('\W+', simplifyString(release_name))) cleaned = ' '.join(re.split('\W+', simplifyString(release_name)))
cleaned = re.sub(self.clean, ' ', cleaned) cleaned = re.sub(self.clean, ' ', cleaned)
year = None
for year_str in [file_name, release_name, cleaned]: for year_str in [file_name, release_name, cleaned]:
if not year_str: continue if not year_str: continue
year = self.findYear(year_str) year = self.findYear(year_str)
@@ -843,7 +844,7 @@ class Scanner(Plugin):
cp_guess = {} cp_guess = {}
if year: # Split name on year if year: # Split name on year
try: try:
movie_name = cleaned.rsplit(year, 1).pop(0).strip() movie_name = cleaned.rsplit(year, 1).pop(0).strip()
if movie_name: if movie_name:
@@ -32,7 +32,7 @@ var isCorrectUrl = function() {
} }
var addUserscript = function() { var addUserscript = function() {
// Add window param // Add window param
document.body.setAttribute('cp_auto_open', true) document.body.setAttribute('cp_auto_open', 'true')
// Load userscript // Load userscript
var e = document.createElement('script'); var e = document.createElement('script');
+2 -2
View File
@@ -35,7 +35,7 @@ class Userscript(Plugin):
'host': host, 'host': host,
} }
return self.renderTemplate(__file__, 'bookmark.js', **params) return self.renderTemplate(__file__, 'bookmark.js_tmpl', **params)
def getIncludes(self, **kwargs): def getIncludes(self, **kwargs):
@@ -60,7 +60,7 @@ class Userscript(Plugin):
'host': '%s://%s' % (self.request.protocol, self.request.headers.get('X-Forwarded-Host') or self.request.headers.get('host')), 'host': '%s://%s' % (self.request.protocol, self.request.headers.get('X-Forwarded-Host') or self.request.headers.get('host')),
} }
script = klass.renderTemplate(__file__, 'template.js', **params) script = klass.renderTemplate(__file__, 'template.js_tmpl', **params)
klass.createFile(os.path.join(Env.get('cache_dir'), 'couchpotato.user.js'), script) klass.createFile(os.path.join(Env.get('cache_dir'), 'couchpotato.user.js'), script)
self.redirect(Env.get('api_base') + 'file.cache/couchpotato.user.js') self.redirect(Env.get('api_base') + 'file.cache/couchpotato.user.js')
@@ -12,7 +12,7 @@ Page.Userscript = new Class({
} }
}, },
indexAction: function(param){ indexAction: function(){
var self = this; var self = this;
self.el.adopt( self.el.adopt(
@@ -60,7 +60,7 @@ var UserscriptSettingTab = new Class({
addSettings: function(){ addSettings: function(){
var self = this; var self = this;
self.settings = App.getPage('Settings') self.settings = App.getPage('Settings');
self.settings.addEvent('create', function(){ self.settings.addEvent('create', function(){
var host_url = window.location.protocol + '//' + window.location.host; var host_url = window.location.protocol + '//' + window.location.host;
@@ -74,7 +74,7 @@ var UserscriptSettingTab = new Class({
'text': 'Install userscript', 'text': 'Install userscript',
'href': Api.createUrl('userscript.get')+randomString()+'/couchpotato.user.js', 'href': Api.createUrl('userscript.get')+randomString()+'/couchpotato.user.js',
'target': '_blank' 'target': '_blank'
}), }),
new Element('span.or[text=or]'), new Element('span.or[text=or]'),
new Element('span.bookmarklet').adopt( new Element('span.bookmarklet').adopt(
new Element('a.button.green', { new Element('a.button.green', {
@@ -86,7 +86,7 @@ var UserscriptSettingTab = new Class({
'target': '', 'target': '',
'events': { 'events': {
'click': function(e){ 'click': function(e){
(e).stop() (e).stop();
alert('Drag it to your bookmark ;)') alert('Drag it to your bookmark ;)')
} }
} }
@@ -5,10 +5,9 @@
.page.wizard h1 { .page.wizard h1 {
padding: 10px 0; padding: 10px 0;
margin: 0 5px;
display: block; display: block;
font-size: 30px; font-size: 30px;
margin-top: 80px; margin: 80px 5px 0;
} }
.page.wizard .description { .page.wizard .description {
@@ -52,7 +51,7 @@
font-weight: normal; font-weight: normal;
border-bottom: 4px solid transparent; border-bottom: 4px solid transparent;
} }
.page.wizard .tabs li:hover a { border-color: #047792; } .page.wizard .tabs li:hover a { border-color: #047792; }
.page.wizard .tabs li.done a { border-color: #04bce6; } .page.wizard .tabs li.done a { border-color: #04bce6; }
@@ -111,10 +111,10 @@ Page.Wizard = new Class({
var form = self.el.getElement('.uniForm'); var form = self.el.getElement('.uniForm');
var tabs = self.el.getElement('.tabs'); var tabs = self.el.getElement('.tabs');
self.groups.each(function(group, nr){ self.groups.each(function(group){
if(self.headers[group]){ if(self.headers[group]){
group_container = new Element('.wgroup_'+group, { var group_container = new Element('.wgroup_'+group, {
'styles': { 'styles': {
'opacity': 0.2 'opacity': 0.2
}, },
@@ -129,7 +129,7 @@ Page.Wizard = new Class({
}) })
} }
var content = self.headers[group].content var content = self.headers[group].content;
group_container.adopt( group_container.adopt(
new Element('h1', { new Element('h1', {
'text': self.headers[group].title 'text': self.headers[group].title
@@ -144,7 +144,7 @@ Page.Wizard = new Class({
var tab_navigation = tabs.getElement('.t_'+group); var tab_navigation = tabs.getElement('.t_'+group);
if(!tab_navigation && self.headers[group] && self.headers[group].include){ if(!tab_navigation && self.headers[group] && self.headers[group].include){
tab_navigation = [] tab_navigation = [];
self.headers[group].include.each(function(inc){ self.headers[group].include.each(function(inc){
tab_navigation.include(tabs.getElement('.t_'+inc)); tab_navigation.include(tabs.getElement('.t_'+inc));
}) })
@@ -157,7 +157,7 @@ Page.Wizard = new Class({
self.headers[group].include.each(function(inc){ self.headers[group].include.each(function(inc){
self.el.getElement('.tab_'+inc).inject(group_container); self.el.getElement('.tab_'+inc).inject(group_container);
}) });
new Element('li.t_'+group).adopt( new Element('li.t_'+group).adopt(
new Element('a', { new Element('a', {
@@ -215,9 +215,9 @@ Page.Wizard = new Class({
self.groups.each(function(groups2, nr2){ self.groups.each(function(groups2, nr2){
var t2 = self.el.getElement('.t_'+groups2); var t2 = self.el.getElement('.t_'+groups2);
t2[nr2 > nr ? 'removeClass' : 'addClass' ]('done'); t2[nr2 > nr ? 'removeClass' : 'addClass' ]('done');
}) });
g.tween('opacity', 1); g.tween('opacity', 1);
} };
if(nr == 0) if(nr == 0)
func(); func();
@@ -241,4 +241,4 @@ Page.Wizard = new Class({
} }
}); });
+5 -1
View File
@@ -56,6 +56,10 @@ class Settings(object):
addEvent('database.setup', self.databaseSetup) addEvent('database.setup', self.databaseSetup)
self.file = None
self.p = None
self.log = None
def setFile(self, config_file): def setFile(self, config_file):
self.file = config_file self.file = config_file
@@ -195,7 +199,6 @@ class Settings(object):
def getOptions(self): def getOptions(self):
return self.options return self.options
def view(self, **kwargs): def view(self, **kwargs):
return { return {
'options': self.getOptions(), 'options': self.getOptions(),
@@ -254,6 +257,7 @@ class Settings(object):
'value': toUnicode(value), 'value': toUnicode(value),
}) })
class PropertyIndex(HashIndex): class PropertyIndex(HashIndex):
_version = 1 _version = 1
+9 -7
View File
@@ -100,14 +100,14 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
if not os.path.isdir(backup_path): os.makedirs(backup_path) if not os.path.isdir(backup_path): os.makedirs(backup_path)
for root, dirs, files in scandir.walk(backup_path): for root, dirs, files in scandir.walk(backup_path):
for file in files: for backup_file in files:
ints = re.findall('\d+', file) ints = re.findall('\d+', backup_file)
# Delete non zip files # Delete non zip files
if len(ints) != 1: if len(ints) != 1:
os.remove(os.path.join(backup_path, file)) os.remove(os.path.join(backup_path, backup_file))
else: else:
existing_backups.append((int(ints[0]), file)) existing_backups.append((int(ints[0]), backup_file))
# Remove all but the last 5 # Remove all but the last 5
for eb in existing_backups[:-backup_count]: for eb in existing_backups[:-backup_count]:
@@ -117,8 +117,8 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
new_backup = toUnicode(os.path.join(backup_path, '%s.tar.gz' % int(time.time()))) new_backup = toUnicode(os.path.join(backup_path, '%s.tar.gz' % int(time.time())))
zipf = tarfile.open(new_backup, 'w:gz') zipf = tarfile.open(new_backup, 'w:gz')
for root, dirs, files in scandir.walk(db_path): for root, dirs, files in scandir.walk(db_path):
for file in files: for zfilename in files:
zipf.add(os.path.join(root, file), arcname = 'database/%s' % os.path.join(root[len(db_path)+1:], file)) zipf.add(os.path.join(root, zfilename), arcname = 'database/%s' % os.path.join(root[len(db_path) + 1:], zfilename))
zipf.close() zipf.close()
# Open last # Open last
@@ -178,6 +178,7 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
logger.addHandler(hdlr2) logger.addHandler(hdlr2)
# Start logging & enable colors # Start logging & enable colors
# noinspection PyUnresolvedReferences
import color_logs import color_logs
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
log = CPLog(__name__) log = CPLog(__name__)
@@ -212,7 +213,8 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En
} }
# Load the app # Load the app
application = Application([], application = Application(
[],
log_function = lambda x: None, log_function = lambda x: None,
debug = config['use_reloader'], debug = config['use_reloader'],
gzip = True, gzip = True,
+1 -1
View File
@@ -369,7 +369,7 @@
// Create parallel callback // Create parallel callback
var callbacks = []; var callbacks = [];
self.global_events[name].each(function(handle, nr){ self.global_events[name].each(function(handle){
callbacks.push(function(callback){ callbacks.push(function(callback){
var results = handle.apply(handle, args || []); var results = handle.apply(handle, args || []);
@@ -68,7 +68,7 @@ var DownloadersBase = new Class({
testButtonName: function(fieldset){ testButtonName: function(fieldset){
var name = String(fieldset.getElement('h2').innerHTML).substring(0,String(fieldset.getElement('h2').innerHTML).indexOf("<span")); var name = String(fieldset.getElement('h2').innerHTML).substring(0,String(fieldset.getElement('h2').innerHTML).indexOf("<span"));
return 'Test '+name; return 'Test '+name;
}, }
}); });
+1 -1
View File
@@ -67,7 +67,7 @@ Page.Home = new Class({
// Force update after search // Force update after search
self.available_list.update(); self.available_list.update();
App.off('movie.searcher.ended', after_search); App.off('movie.searcher.ended', after_search);
} };
App.on('movie.searcher.ended', after_search); App.on('movie.searcher.ended', after_search);
} }
+4 -4
View File
@@ -105,7 +105,7 @@ Page.Manage = new Class({
} }
else { else {
// Capture progress so we can use it in our *each* closure // Capture progress so we can use it in our *each* closure
var progress = json.progress var progress = json.progress;
// Don't add loader when page is loading still // Don't add loader when page is loading still
if(!self.list.navigation) if(!self.list.navigation)
@@ -116,15 +116,15 @@ Page.Manage = new Class({
self.progress_container.empty(); self.progress_container.empty();
var sorted_table = self.parseProgress(json.progress) var sorted_table = self.parseProgress(json.progress);
sorted_table.each(function(folder){ sorted_table.each(function(folder){
var folder_progress = progress[folder] var folder_progress = progress[folder];
new Element('div').adopt( new Element('div').adopt(
new Element('span.folder', {'text': folder + new Element('span.folder', {'text': folder +
(folder_progress.eta > 0 ? ', ' + new Date ().increment('second', folder_progress.eta).timeDiffInWords().replace('from now', 'to go') : '') (folder_progress.eta > 0 ? ', ' + new Date ().increment('second', folder_progress.eta).timeDiffInWords().replace('from now', 'to go') : '')
}), }),
new Element('span.percentage', {'text': folder_progress.total ? (((folder_progress.total-folder_progress.to_go)/folder_progress.total)*100).round() + '%' : '0%'}) new Element('span.percentage', {'text': folder_progress.total ? Math.round(((folder_progress.total-folder_progress.to_go)/folder_progress.total)*100) + '%' : '0%'})
).inject(self.progress_container) ).inject(self.progress_container)
}); });
+4 -3
View File
@@ -370,7 +370,7 @@ var OptionBase = new Class({
createTooltip(self.options.description[1]).inject(hint, 'top'); createTooltip(self.options.description[1]).inject(hint, 'top');
} }
else { else {
var hint = new Element('p.formHint', { new Element('p.formHint', {
'html': self.options.description || '' 'html': self.options.description || ''
}).inject(self.el) }).inject(self.el)
} }
@@ -1312,8 +1312,9 @@ Option.Combined = new Class({
var head = new Element('div.head').inject(self.combined_list); var head = new Element('div.head').inject(self.combined_list);
Object.each(self.inputs, function(input, name){ Object.each(self.inputs, function(input, name){
var _in = input.getNext();
self.labels[name] = input.getPrevious().get('text'); self.labels[name] = input.getPrevious().get('text');
self.descriptions[name] = (_in = input.getNext()) ? _in.get('text') : ''; self.descriptions[name] = _in ? _in.get('text') : '';
new Element('abbr', { new Element('abbr', {
'class': name, 'class': name,
@@ -1465,4 +1466,4 @@ var createTooltip = function(description){
); );
return tip; return tip;
} };
+5 -5
View File
@@ -73,7 +73,7 @@ Page.Wanted = new Class({
} }
else { else {
var progress = json.movie; var progress = json.movie;
self.manual_search.set('text', 'Searching.. (' + (((progress.total-progress.to_go)/progress.total)*100).round() + '%)'); self.manual_search.set('text', 'Searching.. (' + Math.round(((progress.total-progress.to_go)/progress.total)*100) + '%)');
} }
} }
}); });
@@ -87,7 +87,7 @@ Page.Wanted = new Class({
var self = this; var self = this;
var options = { var options = {
'name': 'Scan_folder' 'name': 'Scan_folder'
} };
if(!self.folder_browser){ if(!self.folder_browser){
self.folder_browser = new Option['Directory']("Scan", "folder", "", options); self.folder_browser = new Option['Directory']("Scan", "folder", "", options);
@@ -96,9 +96,9 @@ Page.Wanted = new Class({
var folder = self.folder_browser.getValue(); var folder = self.folder_browser.getValue();
Api.request('renamer.scan', { Api.request('renamer.scan', {
'data': { 'data': {
'base_folder': folder, 'base_folder': folder
}, }
}); });
}; };
self.folder_browser.inject(self.el, 'top'); self.folder_browser.inject(self.el, 'top');
+57 -57
View File
@@ -111,7 +111,7 @@ body > .spinner, .mask{
width: 100%; width: 100%;
padding: 200px; padding: 200px;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
body > .mask { body > .mask {
padding: 20px; padding: 20px;
@@ -185,9 +185,9 @@ body > .spinner, .mask{
.icon2.completed:before { content: "\e070"; } .icon2.completed:before { content: "\e070"; }
.icon2.info:before { content: "\e089"; } .icon2.info:before { content: "\e089"; }
.icon2.attention:before { content: "\e009"; } .icon2.attention:before { content: "\e009"; }
.icon2.readd:before { .icon2.readd:before {
display: inline-block; display: inline-block;
content: "\e04b"; content: "\e04b";
transform: scale(-1, 1); transform: scale(-1, 1);
} }
.icon2.imdb:before { .icon2.imdb:before {
@@ -200,8 +200,8 @@ body > .spinner, .mask{
position: relative; position: relative;
top: -3px; top: -3px;
} }
.icon2.menu:before { .icon2.menu:before {
content: "\e076\00a0 \e076\00a0 \e076\00a0"; content: "\e076\00a0 \e076\00a0 \e076\00a0";
line-height: 6px; line-height: 6px;
transform: scaleX(2); transform: scaleX(2);
width: 20px; width: 20px;
@@ -213,7 +213,7 @@ body > .spinner, .mask{
margin-left: 5px; margin-left: 5px;
} }
@media screen and (-webkit-min-device-pixel-ratio:0) { @media screen and (-webkit-min-device-pixel-ratio:0) {
.icon2.menu:before { .icon2.menu:before {
margin-top: -7px; margin-top: -7px;
} }
} }
@@ -229,7 +229,7 @@ body > .spinner, .mask{
box-shadow: 0 0 10px rgba(0,0,0,.1); box-shadow: 0 0 10px rgba(0,0,0,.1);
transition: all .4s ease-in-out; transition: all .4s ease-in-out;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.header { .header {
height: 44px; height: 44px;
@@ -253,7 +253,7 @@ body > .spinner, .mask{
left: 0; left: 0;
bottom: 0; bottom: 0;
} }
.header .foldout { .header .foldout {
width: 44px; width: 44px;
height: 100%; height: 100%;
@@ -264,7 +264,7 @@ body > .spinner, .mask{
line-height: 42px; line-height: 42px;
color: #FFF; color: #FFF;
} }
.header .logo { .header .logo {
display: inline-block; display: inline-block;
font-size: 3em; font-size: 3em;
@@ -274,36 +274,36 @@ body > .spinner, .mask{
color: #FFF; color: #FFF;
font-weight: normal; font-weight: normal;
vertical-align: top; vertical-align: top;
font-family: Lobster; font-family: Lobster, sans-serif;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.header .foldout { .header .foldout {
display: inline-block; display: inline-block;
} }
.header .logo { .header .logo {
padding-top: 7px; padding-top: 7px;
border: 0; border: 0;
font-size: 1.7em; font-size: 1.7em;
} }
} }
@media all and (min-width: 481px) and (max-width: 640px) { @media all and (min-width: 481px) and (max-width: 640px) {
.header .logo { .header .logo {
display: none; display: none;
} }
} }
.header .navigation ul { .header .navigation ul {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100%; height: 100%;
} }
.header .navigation li { .header .navigation li {
color: #fff; color: #fff;
display: inline-block; display: inline-block;
@@ -317,7 +317,7 @@ body > .spinner, .mask{
.header .navigation li:first-child { .header .navigation li:first-child {
border: none; border: none;
} }
.header .navigation li a { .header .navigation li a {
display: block; display: block;
padding: 15px; padding: 15px;
@@ -327,13 +327,13 @@ body > .spinner, .mask{
border-width: 0 0 4px 0; border-width: 0 0 4px 0;
font-weight: normal; font-weight: normal;
} }
.header .navigation li:hover a { border-color: #047792; } .header .navigation li:hover a { border-color: #047792; }
.header .navigation li.active a { border-color: #04bce6; } .header .navigation li.active a { border-color: #04bce6; }
.header .navigation li.disabled { color: #e5e5e5; } .header .navigation li.disabled { color: #e5e5e5; }
.header .navigation li a { color: #fff; } .header .navigation li a { color: #fff; }
.header .navigation .backtotop { .header .navigation .backtotop {
opacity: 0; opacity: 0;
display: block; display: block;
@@ -349,24 +349,24 @@ body > .spinner, .mask{
font-weight: normal; font-weight: normal;
} }
.header:hover .navigation .backtotop { color: #fff; } .header:hover .navigation .backtotop { color: #fff; }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
body { body {
position: absolute; position: absolute;
width: 100%; width: 100%;
transition: all .5s cubic-bezier(0.9,0,0.1,1); transition: all .5s cubic-bezier(0.9,0,0.1,1);
left: 0; left: 0;
} }
.menu_shown body { .menu_shown body {
left: 240px; left: 240px;
} }
.header .navigation { .header .navigation {
height: 100%; height: 100%;
} }
.menu_shown .header .navigation .overlay { .menu_shown .header .navigation .overlay {
position: fixed; position: fixed;
right: 0; right: 0;
@@ -374,7 +374,7 @@ body > .spinner, .mask{
bottom: 0; bottom: 0;
left: 240px; left: 240px;
} }
.header .navigation ul { .header .navigation ul {
width: 240px; width: 240px;
position: fixed; position: fixed;
@@ -382,11 +382,11 @@ body > .spinner, .mask{
background: rgba(0,0,0,.5); background: rgba(0,0,0,.5);
transition: all .5s cubic-bezier(0.9,0,0.1,1); transition: all .5s cubic-bezier(0.9,0,0.1,1);
} }
.menu_shown .header .navigation ul { .menu_shown .header .navigation ul {
left: 0; left: 0;
} }
.header .navigation ul li { .header .navigation ul li {
display: block; display: block;
text-align: left; text-align: left;
@@ -397,7 +397,7 @@ body > .spinner, .mask{
border-width: 0 4px 0 0; border-width: 0 4px 0 0;
padding: 5px 20px; padding: 5px 20px;
} }
.header .navigation ul li.separator { .header .navigation ul li.separator {
background-color: rgba(255,255,255, .07); background-color: rgba(255,255,255, .07);
height: 5px; height: 5px;
@@ -410,31 +410,31 @@ body > .spinner, .mask{
height: 100%; height: 100%;
border-left: 1px solid rgba(255,255,255,.07); border-left: 1px solid rgba(255,255,255,.07);
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.header .more_menu { .header .more_menu {
display: none; display: none;
} }
} }
.header .more_menu .button { .header .more_menu .button {
height: 100%; height: 100%;
line-height: 66px; line-height: 66px;
text-align: center; text-align: center;
padding: 0; padding: 0;
} }
.header .more_menu .wrapper { .header .more_menu .wrapper {
width: 200px; width: 200px;
margin-left: -106px; margin-left: -106px;
margin-top: 22px; margin-top: 22px;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.header .more_menu .button { .header .more_menu .button {
line-height: 44px; line-height: 44px;
} }
.header .more_menu .wrapper { .header .more_menu .wrapper {
margin-top: 0; margin-top: 0;
} }
@@ -454,12 +454,12 @@ body > .spinner, .mask{
top: 0; top: 0;
right: 0; right: 0;
} }
.header .notification_menu { .header .notification_menu {
right: 60px; right: 60px;
display: block; display: block;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.header .notification_menu { .header .notification_menu {
right: 0; right: 0;
@@ -685,15 +685,15 @@ body > .spinner, .mask{
border-bottom: 4px solid transparent; border-bottom: 4px solid transparent;
border-radius: 0; border-radius: 0;
} }
.more_menu .button:hover { .more_menu .button:hover {
border-color: #047792; border-color: #047792;
} }
.more_menu.show .button { .more_menu.show .button {
border-color: #04bce6; border-color: #04bce6;
} }
.more_menu .wrapper { .more_menu .wrapper {
display: none; display: none;
top: 0; top: 0;
@@ -706,23 +706,23 @@ body > .spinner, .mask{
color: #444; color: #444;
background: #fff; background: #fff;
} }
.more_menu.show .wrapper { .more_menu.show .wrapper {
display: block; display: block;
top: 44px; top: 44px;
} }
.more_menu ul { .more_menu ul {
padding: 0; padding: 0;
margin: 0; margin: 0;
list-style: none; list-style: none;
} }
.more_menu .wrapper li { .more_menu .wrapper li {
width: 100%; width: 100%;
height: auto; height: auto;
} }
.more_menu .wrapper li a { .more_menu .wrapper li a {
display: block; display: block;
border-bottom: 1px solid rgba(255,255,255,0.2); border-bottom: 1px solid rgba(255,255,255,0.2);
@@ -735,21 +735,21 @@ body > .spinner, .mask{
} }
.more_menu .wrapper li:first-child a { padding-top: 5px; } .more_menu .wrapper li:first-child a { padding-top: 5px; }
.more_menu .wrapper li:last-child a { padding-bottom: 5px; } .more_menu .wrapper li:last-child a { padding-bottom: 5px; }
.more_menu .wrapper li .separator { .more_menu .wrapper li .separator {
border-bottom: 1px solid rgba(0,0,0,.1); border-bottom: 1px solid rgba(0,0,0,.1);
display: block; display: block;
height: 1px; height: 1px;
margin: 5px 0; margin: 5px 0;
} }
.more_menu .wrapper li:last-child a { .more_menu .wrapper li:last-child a {
border: none; border: none;
} }
.more_menu .wrapper li a:hover { .more_menu .wrapper li a:hover {
background: rgba(0,0,0,0.05); background: rgba(0,0,0,0.05);
} }
.messages { .messages {
position: fixed; position: fixed;
right: 0; right: 0;
@@ -823,7 +823,7 @@ body > .spinner, .mask{
margin: -200px 0 0 -200px; margin: -200px 0 0 -200px;
} }
@media all and (max-width: 480px) { @media all and (max-width: 480px) {
.login form { .login form {
padding: 0; padding: 0;
height: 300px; height: 300px;
@@ -833,9 +833,9 @@ body > .spinner, .mask{
top: 10px; top: 10px;
margin: 0; margin: 0;
} }
} }
.page.login .ctrlHolder { .page.login .ctrlHolder {
padding: 0; padding: 0;
margin: 0 0 20px; margin: 0 0 20px;
@@ -843,31 +843,31 @@ body > .spinner, .mask{
.page.login .ctrlHolder:hover { .page.login .ctrlHolder:hover {
background: none; background: none;
} }
.page.login input[type=text], .page.login input[type=text],
.page.login input[type=password] { .page.login input[type=password] {
width: 100% !important; width: 100% !important;
font-size: 25px; font-size: 25px;
padding: 14px !important; padding: 14px !important;
} }
.page.login .remember_me { .page.login .remember_me {
font-size: 15px; font-size: 15px;
float: left; float: left;
width: 150px; width: 150px;
padding: 20px 0; padding: 20px 0;
} }
.page.login .remember_me .check { .page.login .remember_me .check {
margin: 5px 5px 0 0; margin: 5px 5px 0 0;
} }
.page.login .button { .page.login .button {
font-size: 25px; font-size: 25px;
padding: 20px; padding: 20px;
float: right; float: right;
} }
/* Fonts */ /* Fonts */
@font-face { @font-face {
font-family: 'Elusive-Icons'; font-family: 'Elusive-Icons';
@@ -936,4 +936,4 @@ body > .spinner, .mask{
url('../fonts/Lobster-webfont.svg#lobster_1.4regular') format('svg'); url('../fonts/Lobster-webfont.svg#lobster_1.4regular') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
+1 -1
View File
@@ -741,7 +741,7 @@
.tooltip { .tooltip {
position: absolute; position: absolute;
right: 0px; right: 0;
width: 30px; width: 30px;
height: 30px; height: 30px;
} }
+1 -1
View File
@@ -26,7 +26,7 @@
) )
); );
documents.each(function(doc, nr){ documents.each(function(doc){
new Element('tr.document').adopt( new Element('tr.document').adopt(
new Element('td.id', {'text': doc['_id']}), new Element('td.id', {'text': doc['_id']}),
new Element('td._rev', {'text': doc['_rev']}), new Element('td._rev', {'text': doc['_rev']}),