diff --git a/couchpotato/core/_base/clientscript/main.py b/couchpotato/core/_base/clientscript/main.py index d3f07f80..323c2e4a 100644 --- a/couchpotato/core/_base/clientscript/main.py +++ b/couchpotato/core/_base/clientscript/main.py @@ -104,8 +104,6 @@ class ClientScript(Plugin): out_name = 'minified_' + out out = os.path.join(cache, out_name) - start = time.time() - raw = [] for file_path in files: f = open(file_path, 'r').read() @@ -121,15 +119,13 @@ class ClientScript(Plugin): raw.append({'file': file_path, 'date': int(os.path.getmtime(file_path)), 'data': data}) - print file_type, time.time() - start - # Combine all files together with some comments data = '' for r in raw: data += self.comment.get(file_type) % (r.get('file'), r.get('date')) data += r.get('data') + '\n\n' - self.createFile(out, ss(data.strip())) + self.createFile(out, data.strip()) if not self.minified.get(file_type): self.minified[file_type] = {} diff --git a/couchpotato/core/logger.py b/couchpotato/core/logger.py index f9afcb69..68a6c3f0 100644 --- a/couchpotato/core/logger.py +++ b/couchpotato/core/logger.py @@ -1,6 +1,5 @@ import logging import re -import traceback class CPLog(object): diff --git a/couchpotato/core/plugins/dashboard/main.py b/couchpotato/core/plugins/dashboard/main.py index b5ea4ac2..aabe856f 100644 --- a/couchpotato/core/plugins/dashboard/main.py +++ b/couchpotato/core/plugins/dashboard/main.py @@ -133,6 +133,7 @@ class Dashboard(Plugin): if len(movies) >= limit: break + db.expire_all() return jsonified({ 'success': True, 'empty': len(movies) == 0, diff --git a/couchpotato/core/plugins/library/main.py b/couchpotato/core/plugins/library/main.py index b91ebe1e..168aead1 100644 --- a/couchpotato/core/plugins/library/main.py +++ b/couchpotato/core/plugins/library/main.py @@ -20,7 +20,6 @@ class LibraryPlugin(Plugin): addEvent('library.update', self.update) addEvent('library.update_release_date', self.updateReleaseDate) - def add(self, attrs = {}, update_after = True): db = get_session() @@ -53,6 +52,7 @@ class LibraryPlugin(Plugin): library_dict = l.to_dict(self.default_dict) + db.expire_all() return library_dict def update(self, identifier, default_title = '', force = False): @@ -132,6 +132,7 @@ class LibraryPlugin(Plugin): library_dict = library.to_dict(self.default_dict) + db.expire_all() return library_dict def updateReleaseDate(self, identifier): @@ -150,6 +151,7 @@ class LibraryPlugin(Plugin): library.info = mergeDicts(library.info, {'release_date': dates }) db.commit() + db.expire_all() return dates diff --git a/couchpotato/core/plugins/movie/main.py b/couchpotato/core/plugins/movie/main.py index b3bbe8ac..cb7281fa 100644 --- a/couchpotato/core/plugins/movie/main.py +++ b/couchpotato/core/plugins/movie/main.py @@ -118,12 +118,13 @@ class MoviePlugin(Plugin): .filter(Movie.status_id == done_status.get('id'), Movie.last_edit < (now - week)) \ .all() - # for movie in movies: for rel in movie.releases: if rel.status_id in [available_status.get('id'), snatched_status.get('id')]: fireEvent('release.delete', id = rel.id, single = True) + db.expire_all() + def getView(self): movie_id = getParam('id') @@ -149,6 +150,7 @@ class MoviePlugin(Plugin): if m: results = m.to_dict(self.default_dict) + db.expire_all() return results def list(self, status = None, release_status = None, limit_offset = None, starts_with = None, search = None, order = None): @@ -216,15 +218,14 @@ class MoviePlugin(Plugin): results = q2.all() movies = [] for movie in results: - temp = movie.to_dict({ + movies.append(movie.to_dict({ 'profile': {'types': {}}, 'releases': {'files':{}, 'info': {}}, 'library': {'titles': {}, 'files':{}}, 'files': {}, - }) - movies.append(temp) + })) - #db.close() + db.expire_all() return (total_count, movies) def availableChars(self, status = None, release_status = None): @@ -259,7 +260,7 @@ class MoviePlugin(Plugin): if char not in chars: chars += str(char) - #db.close() + db.expire_all() return ''.join(sorted(chars, key = str.lower)) def listView(self): @@ -318,8 +319,7 @@ class MoviePlugin(Plugin): fireEvent('notify.frontend', type = 'movie.busy.%s' % id, data = True) fireEventAsync('library.update', identifier = movie.library.identifier, default_title = default_title, force = True, on_complete = self.createOnComplete(id)) - - #db.close() + db.expire_all() return jsonified({ 'success': True, }) @@ -428,7 +428,7 @@ class MoviePlugin(Plugin): if added: fireEvent('notify.frontend', type = 'movie.added', data = movie_dict, message = 'Successfully added "%s" to your wanted list.' % params.get('title', '')) - #db.close() + db.expire_all() return movie_dict @@ -478,7 +478,7 @@ class MoviePlugin(Plugin): movie_dict = m.to_dict(self.default_dict) fireEventAsync('searcher.single', movie_dict, on_complete = self.createNotifyFront(movie_id)) - #db.close() + db.expire_all() return jsonified({ 'success': True, }) @@ -540,7 +540,7 @@ class MoviePlugin(Plugin): if deleted: fireEvent('notify.frontend', type = 'movie.deleted', data = movie.to_dict()) - #db.close() + db.expire_all() return True def restatus(self, movie_id): @@ -568,7 +568,6 @@ class MoviePlugin(Plugin): m.status_id = active_status.get('id') if move_to_wanted else done_status.get('id') db.commit() - #db.close() return True @@ -578,6 +577,7 @@ class MoviePlugin(Plugin): db = get_session() movie = db.query(Movie).filter_by(id = movie_id).first() fireEventAsync('searcher.single', movie.to_dict(self.default_dict), on_complete = self.createNotifyFront(movie_id)) + db.expire_all() return onComplete @@ -588,5 +588,6 @@ class MoviePlugin(Plugin): db = get_session() movie = db.query(Movie).filter_by(id = movie_id).first() fireEvent('notify.frontend', type = 'movie.update.%s' % movie.id, data = movie.to_dict(self.default_dict)) + db.expire_all() return notifyFront diff --git a/couchpotato/core/plugins/movie/static/list.js b/couchpotato/core/plugins/movie/static/list.js index 047ac870..28195543 100644 --- a/couchpotato/core/plugins/movie/static/list.js +++ b/couchpotato/core/plugins/movie/static/list.js @@ -14,6 +14,7 @@ var MovieList = new Class({ movies: [], movies_added: {}, + total_movies: 0, letters: {}, filter: null, @@ -23,7 +24,7 @@ var MovieList = new Class({ self.offset = 0; self.filter = self.options.filter || { - 'startswith': null, + 'starts_with': null, 'search': null } @@ -115,7 +116,7 @@ var MovieList = new Class({ self.createMovie(movie); }); - self.total_movies = total; + self.total_movies += total; self.setCounter(total); }, @@ -127,6 +128,38 @@ var MovieList = new Class({ self.navigation_counter.set('text', (count || 0) + ' movies'); + if (self.empty_message) { + self.empty_message.destroy(); + self.empty_message = null; + } + + if(self.total_movies && count == 0 && !self.empty_message){ + var message = (self.filter.search ? 'for "'+self.filter.search+'"' : '') + + (self.filter.starts_with ? ' in '+self.filter.starts_with+'' : ''); + + self.empty_message = new Element('.message', { + 'html': 'No movies found ' + message + '.
' + }).grab( + new Element('a', { + 'text': 'Reset filter', + 'events': { + 'click': function(){ + self.filter = { + 'starts_with': null, + 'search': null + }; + self.navigation_search_input.set('value', ''); + self.reset(); + self.activateLetter(); + self.getMovies(true); + self.last_search_value = ''; + } + } + }) + ).inject(self.movie_list); + + } + }, createMovie: function(movie, inject_at){ @@ -192,6 +225,9 @@ var MovieList = new Class({ ), new Element('div.menus').adopt( self.navigation_counter = new Element('span.counter[title=Total]'), + self.filter_menu = new Block.Menu(self, { + 'class': 'filter' + }), self.navigation_actions = new Element('ul.actions', { 'events': { 'click:relay(li)': function(e, el){ @@ -199,14 +235,11 @@ var MovieList = new Class({ self.navigation_actions.getElements('.'+a).removeClass(a); self.changeView(el.get('data-view')); this.addClass(a); - + el.inject(el.getParent(), 'top') } } }), - self.filter_menu = new Block.Menu(self, { - 'class': 'filter' - }), self.navigation_menu = new Block.Menu(self, { 'class': 'extra' }) @@ -233,6 +266,10 @@ var MovieList = new Class({ }) ).addClass('search'); + self.filter_menu.addEvent('open', function(){ + self.navigation_search_input.focus(); + }); + self.filter_menu.addLink( self.navigation_alpha = new Element('ul.numbers', { 'events': { @@ -507,7 +544,7 @@ var MovieList = new Class({ 'limit_offset': self.options.limit ? self.options.limit + ',' + self.offset : null }, self.filter), 'onSuccess': function(json){ - + if(reset) self.movie_list.empty(); diff --git a/couchpotato/core/plugins/movie/static/movie.css b/couchpotato/core/plugins/movie/static/movie.css index 4416361c..37cdcdf4 100644 --- a/couchpotato/core/plugins/movie/static/movie.css +++ b/couchpotato/core/plugins/movie/static/movie.css @@ -9,6 +9,18 @@ clear: both; } + .movies > div .message { + display: block; + padding: 20px; + font-size: 20px; + color: white; + text-align: center; + } + .movies > div .message a { + padding: 20px; + display: block; + } + .movies.thumbs_list > div:not(.description) { margin-right: -4px; } @@ -825,6 +837,8 @@ vertical-align: top; z-index: 200; position: relative; + border: 1px solid rgba(255,255,255,.07); + border-width: 0 1px; } .movies .alph_nav .actions:hover { box-shadow: 0 100px 20px -10px rgba(0,0,0,0.55); @@ -927,8 +941,6 @@ } .movies .alph_nav .more_menu.filter { - border: 1px solid rgba(255,255,255,.07); - border-width: 0 1px; } .movies .alph_nav .more_menu.filter > a:before { @@ -940,7 +952,7 @@ } .movies .alph_nav .more_menu.filter .wrapper { - right: 45px; + right: 88px; width: 300px; } diff --git a/couchpotato/core/plugins/profile/main.py b/couchpotato/core/plugins/profile/main.py index 3dd89d9f..e9259b6d 100644 --- a/couchpotato/core/plugins/profile/main.py +++ b/couchpotato/core/plugins/profile/main.py @@ -62,6 +62,7 @@ class ProfilePlugin(Plugin): for profile in profiles: temp.append(profile.to_dict(self.to_dict)) + db.expire_all() return temp def save(self): @@ -109,6 +110,7 @@ class ProfilePlugin(Plugin): default = db.query(Profile).first() default_dict = default.to_dict(self.to_dict) + db.expire_all() return default_dict def saveOrder(self): @@ -151,6 +153,7 @@ class ProfilePlugin(Plugin): except Exception, e: message = log.error('Failed deleting Profile: %s', e) + db.expire_all() return jsonified({ 'success': success, 'message': message diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py index 37de4867..56e57158 100644 --- a/couchpotato/core/plugins/scanner/main.py +++ b/couchpotato/core/plugins/scanner/main.py @@ -336,7 +336,7 @@ class Scanner(Plugin): break if return_ignored is False and identifier in ignored_identifiers: - log.debug('Ignore file found, ignoring release: %s' % identifier) + log.debug('Ignore file found, ignoring release: %s', identifier) continue # Group extra (and easy) files first diff --git a/couchpotato/core/plugins/searcher/main.py b/couchpotato/core/plugins/searcher/main.py index dba0ea7e..23e8ea58 100644 --- a/couchpotato/core/plugins/searcher/main.py +++ b/couchpotato/core/plugins/searcher/main.py @@ -392,7 +392,7 @@ class Searcher(Plugin): req_match += len(list(set(nzb_words) & set(req))) == len(req) if self.conf('required_words') and req_match == 0: - log.info2("Wrong: Required word missing: %s" % nzb['name']) + log.info2('Wrong: Required word missing: %s', nzb['name']) return False # Ignore releases @@ -403,7 +403,7 @@ class Searcher(Plugin): ignored_match += len(list(set(nzb_words) & set(ignored))) == len(ignored) if self.conf('ignored_words') and ignored_match: - log.info2("Wrong: '%s' contains 'ignored words'" % (nzb['name'])) + log.info2("Wrong: '%s' contains 'ignored words'", (nzb['name'])) return False # Ignore porn stuff @@ -462,7 +462,7 @@ class Searcher(Plugin): if len(movie_words) <= 2 and self.correctYear([nzb['name']], movie['library']['year'], 0): return True - log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'" % (nzb['name'], movie_name, movie['library']['year'])) + log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'", (nzb['name'], movie_name, movie['library']['year'])) return False def containsOtherQuality(self, nzb, movie_year = None, preferred_quality = {}): diff --git a/couchpotato/core/providers/automation/base.py b/couchpotato/core/providers/automation/base.py index e33a44eb..4655c1ad 100644 --- a/couchpotato/core/providers/automation/base.py +++ b/couchpotato/core/providers/automation/base.py @@ -74,13 +74,13 @@ class Automation(Provider): req_match += len(list(set(movie_genres) & set(req))) == len(req) if self.getMinimal('required_genres') and req_match == 0: - log.info2("Required genre(s) missing for %s" % movie['original_title']) + log.info2('Required genre(s) missing for %s', movie['original_title']) return False for ign_set in ignored_genres: ign = splitString(ign_set, '&') if len(list(set(movie_genres) & set(ign))) == len(ign): - log.info2("%s has blacklisted genre(s): %s" % (movie['original_title'], ign)) + log.info2('%s has blacklisted genre(s): %s', (movie['original_title'], ign)) return False return True diff --git a/couchpotato/core/providers/automation/rottentomatoes/main.py b/couchpotato/core/providers/automation/rottentomatoes/main.py index 053b79e8..b4482023 100644 --- a/couchpotato/core/providers/automation/rottentomatoes/main.py +++ b/couchpotato/core/providers/automation/rottentomatoes/main.py @@ -35,10 +35,10 @@ class Rottentomatoes(Automation, RSS): name = result.group(0) if rating < tryInt(self.conf('tomatometer_percent')): - log.info2('%s seems to be rotten...' % name) + log.info2('%s seems to be rotten...', name) else: - log.info2('Found %s fresh enough movies, enqueuing: %s' % (rating, name)) + log.info2('Found %s fresh enough movies, enqueuing: %s', (rating, name)) year = datetime.datetime.now().strftime("%Y") imdb = self.search(name, year) diff --git a/couchpotato/core/providers/base.py b/couchpotato/core/providers/base.py index 1f0df964..809ec616 100644 --- a/couchpotato/core/providers/base.py +++ b/couchpotato/core/providers/base.py @@ -179,7 +179,7 @@ class YarrProvider(Provider): if hostname in download_url: return self except: - log.debug('Url % s doesn\'t belong to %s', (url, self.getName())) + log.debug('Url %s doesn\'t belong to %s', (url, self.getName())) return diff --git a/couchpotato/core/providers/torrent/passthepopcorn/main.py b/couchpotato/core/providers/torrent/passthepopcorn/main.py index 9abe51fb..3f2d16d3 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/main.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/main.py @@ -58,7 +58,7 @@ class PassThePopcorn(TorrentProvider): class PTPHTTPRedirectHandler(urllib2.HTTPRedirectHandler): def http_error_302(self, req, fp, code, msg, headers): - log.debug("302 detected; redirected to %s" % headers['Location']) + log.debug("302 detected; redirected to %s", headers['Location']) if (headers['Location'] != 'login.php'): return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers) else: @@ -84,7 +84,7 @@ class PassThePopcorn(TorrentProvider): txt = self.urlopen(url, opener = self.login_opener) res = json.loads(txt) except: - log.error('Search on PassThePopcorn.me (%s) failed (could not decode JSON)' % params) + log.error('Search on PassThePopcorn.me (%s) failed (could not decode JSON)', params) return try: @@ -96,10 +96,10 @@ class PassThePopcorn(TorrentProvider): for ptpmovie in res['Movies']: if not 'Torrents' in ptpmovie: - log.debug('Movie %s (%s) has NO torrents' % (ptpmovie['Title'], ptpmovie['Year'])) + log.debug('Movie %s (%s) has NO torrents', (ptpmovie['Title'], ptpmovie['Year'])) continue - log.debug('Movie %s (%s) has %d torrents' % (ptpmovie['Title'], ptpmovie['Year'], len(ptpmovie['Torrents']))) + log.debug('Movie %s (%s) has %d torrents', (ptpmovie['Title'], ptpmovie['Year'], len(ptpmovie['Torrents']))) for torrent in ptpmovie['Torrents']: torrent_id = tryInt(torrent['Id']) torrentdesc = '%s %s %s' % (torrent['Resolution'], torrent['Source'], torrent['Codec']) @@ -151,7 +151,7 @@ class PassThePopcorn(TorrentProvider): try: response = opener.open(self.urls['login'], self.getLoginParams()) except urllib2.URLError as e: - log.error('Login to PassThePopcorn failed: %s' % e) + log.error('Login to PassThePopcorn failed: %s', e) return False if response.getcode() == 200: @@ -159,7 +159,7 @@ class PassThePopcorn(TorrentProvider): self.login_opener = opener return True else: - log.error('Login to PassThePopcorn failed: returned code %d' % response.getcode()) + log.error('Login to PassThePopcorn failed: returned code %d', response.getcode()) return False def torrentMeetsQualitySpec(self, torrent, quality): @@ -172,7 +172,7 @@ class PassThePopcorn(TorrentProvider): seen_one = False if not field in torrent: - log.debug('Torrent with ID %s has no field "%s"; cannot apply post-search-filter for quality "%s"' % (torrent['Id'], field, quality)) + log.debug('Torrent with ID %s has no field "%s"; cannot apply post-search-filter for quality "%s"', (torrent['Id'], field, quality)) continue for spec in specs: