diff --git a/couchpotato/__init__.py b/couchpotato/__init__.py index 04756fa4..b8aa3ab9 100644 --- a/couchpotato/__init__.py +++ b/couchpotato/__init__.py @@ -22,7 +22,7 @@ class BaseHandler(RequestHandler): username = Env.setting('username') password = Env.setting('password') - if username or password: + if username and password: return self.get_secure_cookie('user') else: # Login when no username or password are set return True diff --git a/couchpotato/core/downloaders/rtorrent/main.py b/couchpotato/core/downloaders/rtorrent/main.py index 680c44aa..161c671a 100755 --- a/couchpotato/core/downloaders/rtorrent/main.py +++ b/couchpotato/core/downloaders/rtorrent/main.py @@ -1,20 +1,19 @@ from base64 import b16encode, b32decode -from datetime import timedelta -from hashlib import sha1 -import shutil -from couchpotato.core.helpers.encoding import ss -from rtorrent.err import MethodError - from bencode import bencode, bdecode from couchpotato.core.downloaders.base import Downloader, StatusList +from couchpotato.core.helpers.encoding import ss from couchpotato.core.logger import CPLog +from datetime import timedelta +from hashlib import sha1 from rtorrent import RTorrent - +from rtorrent.err import MethodError +import shutil log = CPLog(__name__) class rTorrent(Downloader): + protocol = ['torrent', 'torrent_magnet'] rt = None @@ -194,7 +193,7 @@ class rTorrent(Downloader): if torrent is None: return False - torrent.erase() # just removes the torrent, doesn't delete data + torrent.erase() # just removes the torrent, doesn't delete data if delete_files: shutil.rmtree(item['folder'], True) diff --git a/couchpotato/core/plugins/manage/main.py b/couchpotato/core/plugins/manage/main.py index ec86f594..702b1293 100644 --- a/couchpotato/core/plugins/manage/main.py +++ b/couchpotato/core/plugins/manage/main.py @@ -118,7 +118,9 @@ class Manage(Plugin): fireEvent('movie.delete', movie_id = done_movie['id'], delete_from = 'all') else: - for release in done_movie.get('releases', []): + releases = fireEvent('release.for_movie', id = done_movie.get('id'), single = True) + + for release in releases: if len(release.get('files', [])) == 0: fireEvent('release.delete', release['id']) else: @@ -129,9 +131,9 @@ class Manage(Plugin): break # Check if there are duplicate releases (different quality) use the last one, delete the rest - if len(done_movie.get('releases', [])) > 1: + if len(releases) > 1: used_files = {} - for release in done_movie.get('releases', []): + for release in releases: for release_file in release.get('files', []): already_used = used_files.get(release_file['path']) diff --git a/couchpotato/core/plugins/release/main.py b/couchpotato/core/plugins/release/main.py index 72089cc9..46857adf 100644 --- a/couchpotato/core/plugins/release/main.py +++ b/couchpotato/core/plugins/release/main.py @@ -37,13 +37,14 @@ class Release(Plugin): 'id': {'type': 'id', 'desc': 'ID of the release object in release-table'} } }) - addApiView('release.for_movie', self.forMovie, docs = { + addApiView('release.for_movie', self.forMovieView, docs = { 'desc': 'Returns all releases for a movie. Ordered by score(desc)', 'params': { 'id': {'type': 'id', 'desc': 'ID of the movie'} } }) + addEvent('release.for_movie', self.forMovie) addEvent('release.delete', self.delete) addEvent('release.clean', self.clean) @@ -216,7 +217,7 @@ class Release(Plugin): 'success': False } - def forMovie(self, id = None, **kwargs): + def forMovie(self, id = None): db = get_session() @@ -229,6 +230,12 @@ class Release(Plugin): releases = [r.to_dict({'info':{}, 'files':{}}) for r in releases_raw] releases = sorted(releases, key = lambda k: k['info'].get('score', 0), reverse = True) + return releases + + def forMovieView(self, id = None, **kwargs): + + releases = self.forMovie(id) + return { 'releases': releases, 'success': True diff --git a/couchpotato/core/plugins/suggestion/main.py b/couchpotato/core/plugins/suggestion/main.py index d6fdeb42..2cedeba6 100644 --- a/couchpotato/core/plugins/suggestion/main.py +++ b/couchpotato/core/plugins/suggestion/main.py @@ -3,7 +3,7 @@ from couchpotato.api import addApiView from couchpotato.core.event import fireEvent from couchpotato.core.helpers.variable import splitString from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import Movie +from couchpotato.core.settings.model import Movie, Library from couchpotato.environment import Env from sqlalchemy.orm import joinedload_all from sqlalchemy.sql.expression import or_ @@ -20,6 +20,7 @@ class Suggestion(Plugin): movies = splitString(kwargs.get('movies', '')) ignored = splitString(kwargs.get('ignored', '')) + seen = splitString(kwargs.get('seen', '')) cached_suggestion = self.getCache('suggestion_cached') if cached_suggestion: @@ -35,6 +36,8 @@ class Suggestion(Plugin): if not ignored or len(ignored) == 0: ignored = splitString(Env.prop('suggest_ignore', default = '')) + if not seen or len(seen) == 0: + movies.extend(splitString(Env.prop('suggest_seen', default = ''))) suggestions = fireEvent('movie.suggest', movies = movies, ignore = ignored, single = True) self.setCache('suggestion_cached', suggestions, timeout = 6048000) # Cache for 10 weeks @@ -45,17 +48,21 @@ class Suggestion(Plugin): 'suggestions': suggestions[:int(limit)] } - def ignoreView(self, imdb = None, limit = 6, remove_only = False, **kwargs): + def ignoreView(self, imdb = None, limit = 6, remove_only = False, mark_seen = False, **kwargs): ignored = splitString(Env.prop('suggest_ignore', default = '')) + seen = splitString(Env.prop('suggest_seen', default = '')) new_suggestions = [] if imdb: - if not remove_only: + if mark_seen: + seen.append(imdb) + Env.prop('suggest_seen', ','.join(set(seen))) + elif not remove_only: ignored.append(imdb) Env.prop('suggest_ignore', ','.join(set(ignored))) - new_suggestions = self.updateSuggestionCache(ignore_imdb = imdb, limit = limit, ignored = ignored) + new_suggestions = self.updateSuggestionCache(ignore_imdb = imdb, limit = limit, ignored = ignored, seen = seen) return { 'result': True, @@ -63,12 +70,13 @@ class Suggestion(Plugin): 'suggestions': new_suggestions[limit - 1:limit] } - def updateSuggestionCache(self, ignore_imdb = None, limit = 6, ignored = None): + def updateSuggestionCache(self, ignore_imdb = None, limit = 6, ignored = None, seen = None): # Combine with previous suggestion_cache cached_suggestion = self.getCache('suggestion_cached') new_suggestions = [] ignored = [] if not ignored else ignored + seen = [] if not seen else seen if ignore_imdb: for cs in cached_suggestion: @@ -78,10 +86,15 @@ class Suggestion(Plugin): # Get new results and add them if len(new_suggestions) - 1 < limit: + active_status, done_status = fireEvent('status.get', ['active', 'done'], single = True) + db = get_session() active_movies = db.query(Movie) \ - .filter(or_(*[Movie.status.has(identifier = s) for s in ['active', 'done']])).all() - movies = [x.library.identifier for x in active_movies] + .join(Library) \ + .with_entities(Library.identifier) \ + .filter(Movie.status_id.in_([active_status.get('id'), done_status.get('id')])).all() + movies = [x[0] for x in active_movies] + movies.extend(seen) ignored.extend([x.get('imdb') for x in cached_suggestion]) suggestions = fireEvent('movie.suggest', movies = movies, ignore = list(set(ignored)), single = True) diff --git a/couchpotato/core/plugins/suggestion/static/suggest.css b/couchpotato/core/plugins/suggestion/static/suggest.css index 2b05abf9..c321ca28 100644 --- a/couchpotato/core/plugins/suggestion/static/suggest.css +++ b/couchpotato/core/plugins/suggestion/static/suggest.css @@ -105,7 +105,7 @@ bottom: 10px; right: 10px; display: none; - width: 120px; + width: 140px; } .suggestions .movie_result:hover .actions { display: block; diff --git a/couchpotato/core/plugins/suggestion/static/suggest.js b/couchpotato/core/plugins/suggestion/static/suggest.js index 817d965f..e6226711 100644 --- a/couchpotato/core/plugins/suggestion/static/suggest.js +++ b/couchpotato/core/plugins/suggestion/static/suggest.js @@ -26,6 +26,20 @@ var SuggestList = new Class({ 'onComplete': self.fill.bind(self) }); + }, + 'click:relay(a.eye-open)': function(e, el){ + (e).stop(); + + $(el).getParent('.movie_result').destroy(); + + Api.request('suggestion.ignore', { + 'data': { + 'imdb': el.get('data-seen'), + 'mark_seen': 1 + }, + 'onComplete': self.fill.bind(self) + }); + } } }).grab( @@ -43,7 +57,7 @@ var SuggestList = new Class({ fill: function(json){ var self = this; - + if(!json) return; Object.each(json.suggestions, function(movie){ @@ -69,6 +83,10 @@ var SuggestList = new Class({ new Element('a.delete.icon2', { 'title': 'Don\'t suggest this movie again', 'data-ignore': movie.imdb + }), + new Element('a.eye-open.icon2', { + 'title': 'Seen it, like it, don\'t add', + 'data-seen': movie.imdb }) ) ); @@ -88,7 +106,7 @@ var SuggestList = new Class({ $(m).inject(self.el); }); - + self.fireEvent('loaded'); }, diff --git a/couchpotato/core/providers/info/themoviedb/main.py b/couchpotato/core/providers/info/themoviedb/main.py index 387355f8..376ddad0 100644 --- a/couchpotato/core/providers/info/themoviedb/main.py +++ b/couchpotato/core/providers/info/themoviedb/main.py @@ -1,6 +1,5 @@ from couchpotato.core.event import addEvent -from couchpotato.core.helpers.encoding import simplifyString, toUnicode, ss -from couchpotato.core.helpers.variable import md5 +from couchpotato.core.helpers.encoding import simplifyString, toUnicode from couchpotato.core.logger import CPLog from couchpotato.core.providers.info.base import MovieProvider import tmdb3 @@ -129,11 +128,9 @@ class TheMovieDb(MovieProvider): movie_data['titles'].append(movie.originaltitle) for alt in movie.alternate_titles: alt_name = alt.title - if alt_name and not alt_name in movie_data['titles'] and alt_name.lower() != 'none' and alt_name is not None: + if alt_name and alt_name not in movie_data['titles'] and alt_name.lower() != 'none' and alt_name is not None: movie_data['titles'].append(alt_name) - movie_data['titles'] = list(set(movie_data['titles'])) - # Cache movie parsed self.setCache(cache_key, movie_data) @@ -143,7 +140,7 @@ class TheMovieDb(MovieProvider): image_url = '' try: - image_url = getattr(movie, type).geturl(size='original') + image_url = getattr(movie, type).geturl(size = 'original') except: log.debug('Failed getting %s.%s for "%s"', (type, size, movie.title)) diff --git a/init/ubuntu b/init/ubuntu index 511d9ee8..7f770a67 100644 --- a/init/ubuntu +++ b/init/ubuntu @@ -52,7 +52,7 @@ APP_PATH=${CP_HOME-/opt/couchpotato/} DATA_DIR=${CP_DATA-/var/couchpotato} # Path to store PID file -PID_FILE=${CP_PID_FILE-/var/run/couchpotato.pid} +PID_FILE=${CP_PIDFILE-/var/run/couchpotato.pid} # path to python bin DAEMON=${PYTHON_BIN-/usr/bin/python}