def download(self): db = get_session() id = getParam('id') rel = db.query(Relea).filter_by(id = id).first() if rel: item = {} for info in rel.info: item[info.identifier] = info.value # Get matching provider provider = fireEvent('provider.belongs_to', item['url'], single = True) item['download'] = provider.download fireEvent('searcher.download', data = item, movie = rel.movie.to_dict({ 'profile': {'types': {'quality': {}}}, 'releases': {'status': {}, 'quality': {}}, 'library': {'titles': {}, 'files':{}}, 'files': {} })) return jsonified({ 'success': True }) else: log.error('Couldn\'t find release with id: %s' % id) return jsonified({ 'success': False })
def getAuthorizationUrl(self): referer = getParam('host') callback_url = cleanHost(referer) + '%snotify.%s.credentials/' % (url_for('api.index').lstrip('/'), self.getName().lower()) oauth_consumer = oauth2.Consumer(self.consumer_key, self.consumer_secret) oauth_client = oauth2.Client(oauth_consumer) resp, content = oauth_client.request(self.urls['request'], 'POST', body = tryUrlencode({'oauth_callback': callback_url})) if resp['status'] != '200': log.error('Invalid response from Twitter requesting temp token: %s' % resp['status']) return jsonified({ 'success': False, }) else: self.request_token = dict(parse_qsl(content)) auth_url = self.urls['authorize'] + ("?oauth_token=%s" % self.request_token['oauth_token']) log.info('Redirecting to "%s"' % auth_url) return jsonified({ 'success': True, 'url': auth_url, })
def download(self): db = get_session() id = getParam("id") snatched_status = fireEvent("status.add", "snatched", single=True) done_status = fireEvent("status.get", "done", single=True) rel = db.query(Relea).filter_by(id=id).first() if rel: item = {} for info in rel.info: item[info.identifier] = info.value fireEvent("notify.frontend", type="release.download", data=True, message='Snatching "%s"' % item["name"]) # Get matching provider provider = fireEvent("provider.belongs_to", item["url"], provider=item.get("provider"), single=True) if item["type"] != "torrent_magnet": item["download"] = provider.download success = fireEvent( "searcher.download", data=item, movie=rel.movie.to_dict( { "profile": {"types": {"quality": {}}}, "releases": {"status": {}, "quality": {}}, "library": {"titles": {}, "files": {}}, "files": {}, } ), manual=True, single=True, ) if success: db.expunge_all() rel = db.query(Relea).filter_by(id=id).first() # Get release again if rel.status_id != done_status.get("id"): rel.status_id = snatched_status.get("id") db.commit() fireEvent( "notify.frontend", type="release.download", data=True, message='Successfully snatched "%s"' % item["name"], ) return jsonified({"success": success}) else: log.error("Couldn't find release with id: %s", id) return jsonified({"success": False})
def add2(self): db = get_session() rand = random.randrange(10000, 90000, 2) lib_id = getParam("lib_id") qua_id = getParam("qua_id") name = getParam("name") identifier = "azerty12345678900" + str(rand) + "00" + lib_id + "00" + qua_id if not lib_id or not qua_id or not name: return jsonified({"success": False}) # Add movie done_status = fireEvent("status.get", "done", single=True) snatched_status = fireEvent("status.get", "snatched", single=True) movie = db.query(Movie).filter_by(library_id=lib_id).first() if not movie: log.debug("Update status to snatched") movie = Movie(library_id=lib_id, profile_id=0, status_id=snatched_status.get("id")) db.add(movie) db.commit() # Add Release rls = db.query(Relea).filter_by(identifier=identifier).first() if not rls: log.debug("Add a %s release for movie %s.", (snatched_status.get("label"), movie.id)) rls = Relea(identifier=identifier, movie=movie, quality_id=qua_id, status_id=snatched_status.get("id")) db.add(rls) db.commit() # Add ReleaseInfo log.debug("Add a %s releaseinfo for movie %s.", (snatched_status.get("label"), movie.id)) infos = { "name": "azerty", "type": "nzb", "size": "700", "description": "", "url": "", "age": "1", "score": "100", } infos["name"] = name for key, value in infos.items(): rls_info = ReleaseInfo(identifier=key, value=toUnicode(value)) rls.info.append(rls_info) db.commit() log.info("New %s release added for movie %s.", (snatched_status.get("label"), movie.id)) return jsonified({"success": True, "identifier": identifier})
def download(self): db = get_session() id = getParam('id') snatched_status = fireEvent('status.add', 'snatched', single = True) done_status = fireEvent('status.get', 'done', single = True) rel = db.query(Relea).filter_by(id = id).first() if rel: item = {} for info in rel.info: item[info.identifier] = info.value fireEvent('notify.frontend', type = 'release.download', data = True, message = 'Snatching "%s"' % item['name']) # Get matching provider provider = fireEvent('provider.belongs_to', item['url'], provider = item.get('provider'), single = True) if item['type'] != 'torrent_magnet': item['download'] = provider.download success = fireEvent('searcher.download', data = item, movie = rel.movie.to_dict({ 'profile': {'types': {'quality': {}}}, 'releases': {'status': {}, 'quality': {}}, 'library': {'titles': {}, 'files':{}}, 'files': {} }), manual = True, single = True) if success: db.expunge_all() rel = db.query(Relea).filter_by(id = id).first() # Get release again if rel.status_id != done_status.get('id'): rel.status_id = snatched_status.get('id') db.commit() fireEvent('notify.frontend', type = 'release.download', data = True, message = 'Successfully snatched "%s"' % item['name']) return jsonified({ 'success': success }) else: log.error('Couldn\'t find release with id: %s', id) return jsonified({ 'success': False })
def add(self): params = getParams() db = get_session(); library = fireEvent('library.add', single = True, attrs = params) status = fireEvent('status.add', 'active', single = True) m = db.query(Movie).filter_by(library_id = library.id).first() if not m: m = Movie( library_id = library.id, profile_id = params.get('profile_id') ) db.add(m) m.status_id = status.id db.commit() return jsonified({ 'success': True, 'added': True, 'movie': m.to_dict(deep = { 'releases': {'status': {}, 'quality': {}}, 'library': {'titles': {}} }) })
def save(self): params = getParams() db = get_session() p = db.query(Profile).filter_by(id=params.get("id")).first() if not p: p = Profile() db.add(p) p.label = params.get("label") p.order = params.get("order", p.order if p.order else 0) p.core = params.get("core", False) # delete old types [db.delete(t) for t in p.types] order = 0 for type in params.get("types", []): t = ProfileType( order=order, finish=type.get("finish"), wait_for=params.get("wait_for"), quality_id=type.get("quality_id"), ) p.types.append(t) order += 1 db.commit() return jsonified({"success": True, "profile": p.to_dict(deep={"types": {}})})
def deleteView(self): release_id = getParam('id') return jsonified({ 'success': self.delete(release_id) })
def edit(self): params = getParams() db = get_session() available_status = fireEvent('status.get', 'available', single = True) ids = params.get('id').split(',') for movie_id in ids: m = db.query(Movie).filter_by(id = movie_id).first() m.profile_id = params.get('profile_id') # Remove releases for rel in m.releases: if rel.status_id is available_status.get('id'): db.delete(rel) db.commit() # Default title if params.get('default_title'): for title in m.library.titles: title.default = params.get('default_title').lower() == title.title.lower() db.commit() fireEvent('movie.restatus', m.id) movie_dict = m.to_dict(self.default_dict) fireEventAsync('searcher.single', movie_dict) return jsonified({ 'success': True, })
def get(self): nr = int(getParam('nr', 0)) current_path = None total = 1 for x in range(0, 50): path = '%s%s' % (Env.get('log_path'), '.%s' % x if x > 0 else '') # Check see if the log exists if not os.path.isfile(path): total = x - 1 break # Set current path if x is nr: current_path = path log = '' if current_path: f = open(current_path, 'r') log = f.read() return jsonified({ 'success': True, 'log': log, 'total': total, })
def refresh(self): db = get_session() for id in getParam('id').split(','): fireEvent('notify.frontend', type='movie.busy.%s' % id, data=True) movie = db.query(Movie).filter_by(id=id).first() if movie: # Get current selected title default_title = '' for title in movie.library.titles: if title.default: default_title = title.title fireEventAsync( 'library.update', identifier=movie.library.identifier, default_title=default_title, force=True, on_complete=self.createOnComplete(id)) #db.close() return jsonified({ 'success': True, })
def view(self): path = getParam('path', '/') # Set proper home dir for some systems try: import pwd os.environ['HOME'] = pwd.getpwuid(os.geteuid()).pw_dir except: pass home = os.path.expanduser('~') if not path: path = home try: dirs = self.getDirectories(path = path, show_hidden = getParam('show_hidden', True)) except: dirs = [] parent = os.path.dirname(path.rstrip(os.path.sep)) if parent == path.rstrip(os.path.sep): parent = '/' elif parent != '/' and parent[-2:] != ':\\': parent += os.path.sep return jsonified({ 'is_root': path == '/', 'empty': len(dirs) == 0, 'parent': parent, 'home': home + os.path.sep, 'platform': os.name, 'dirs': dirs, })
def tryNextReleaseView(self): trynext = self.tryNextRelease(getParam('id')) return jsonified({ 'success': trynext })
def scanView(self): fireEventAsync('renamer.scan') return jsonified({ 'success': True })
def listView(self): params = getParams() status = splitString(params.get('status', None)) release_status = splitString(params.get('release_status', None)) limit_offset = params.get('limit_offset', None) starts_with = params.get('starts_with', None) search = params.get('search', None) order = params.get('order', None) total_movies, movies = self.list( status = status, release_status = release_status, limit_offset = limit_offset, starts_with = starts_with, search = search, order = order ) return jsonified({ 'success': True, 'empty': len(movies) == 0, 'total': total_movies, 'movies': movies, })
def listener(self): messages = [] for message in self.messages: #delete message older then 15s if message['time'] > (time.time() - 15): messages.append(message) # Get unread if getParam('init'): db = get_session() notifications = db.query(Notif) \ .filter(or_(Notif.read == False, Notif.added > (time.time() - 259200))) \ .all() for n in notifications: ndict = n.to_dict() ndict['type'] = 'notification' messages.append(ndict) #db.close() self.messages = [] return jsonified({ 'success': True, 'result': messages, })
def charView(self): params = getParams() status = params.get("status", ["active"]) chars = self.availableChars(status) return jsonified({"success": True, "empty": len(chars) == 0, "chars": chars})
def refresh(self): db = get_session() for id in getParam("id").split(","): movie = db.query(Movie).filter_by(id=id).first() if movie: # Get current selected title default_title = "" for title in movie.library.titles: if title.default: default_title = title.title fireEvent( "notify.frontend", type="movie.busy.%s" % id, data=True, message='Updating "%s"' % default_title ) fireEventAsync( "library.update", identifier=movie.library.identifier, default_title=default_title, force=True, on_complete=self.createOnComplete(id), ) # db.close() return jsonified({"success": True})
def view(self): path = getParam('path', '/') home = getUserDir() if not path: path = home try: dirs = self.getDirectories(path = path, show_hidden = getParam('show_hidden', True)) except: dirs = [] parent = os.path.dirname(path.rstrip(os.path.sep)) if parent == path.rstrip(os.path.sep): parent = '/' elif parent != '/' and parent[-2:] != ':\\': parent += os.path.sep return jsonified({ 'is_root': path == '/', 'empty': len(dirs) == 0, 'parent': parent, 'home': home + os.path.sep, 'platform': os.name, 'dirs': dirs, })
def listView(self): db = get_session() limit_offset = getParam('limit_offset', None) q = db.query(Notif) if limit_offset: splt = [x.strip() for x in limit_offset.split(',')] limit = splt[0] offset = 0 if len(splt) is 1 else splt[1] q = q.limit(limit).offset(offset) results = q.all() notifications = [] for n in results: ndict = n.to_dict() ndict['type'] = 'notification' notifications.append(ndict) #db.close() return jsonified({ 'success': True, 'empty': len(notifications) == 0, 'notifications': notifications })
def edit(self): params = getParams() db = get_session() available_status = fireEvent("status.get", "available", single=True) ids = params.get("id").split(",") for movie_id in ids: m = db.query(Movie).filter_by(id=movie_id).first() m.profile_id = params.get("profile_id") # Remove releases for rel in m.releases: if rel.status_id is available_status.get("id"): db.delete(rel) db.commit() # Default title if params.get("default_title"): for title in m.library.titles: title.default = params.get("default_title").lower() == title.title.lower() db.commit() fireEvent("movie.restatus", m.id) movie_dict = m.to_dict(self.default_dict) fireEventAsync("searcher.single", movie_dict) return jsonified({"success": True})
def addView(self): params = getParams() movie_dict = self.add(params) return jsonified({"success": True, "added": True if movie_dict else False, "movie": movie_dict})
def getInfo(self): return jsonified({ 'repo_name': self.repo_name, 'last_check': self.last_check, 'update_version': self.update_version, 'version': self.getVersion() })
def updateLibraryView(self): full = getParam('full', default = 1) fireEventAsync('manage.update', full = True if full == '1' else False) return jsonified({ 'success': True })
def charView(self): params = getParams() status = splitString(params.get("status", None)) release_status = splitString(params.get("release_status", None)) chars = self.availableChars(status, release_status) return jsonified({"success": True, "empty": len(chars) == 0, "chars": chars})
def queueSortView(self): full = getParam('mode', default = 1) fireEventAsync('queue.sort', mode = True if mode == '1' else False) return jsonified({ 'success': True })
def test(self): test_type = self.testNotifyName() log.info("Sending test to %s", test_type) success = self._notify(message=self.test_message, data={}, listener="test") return jsonified({"success": success})
def getView(self): movie_id = getParam('id') movie = self.get(movie_id) if movie_id else None return jsonified({ 'success': movie is not None, 'movie': movie, })
def index(): from couchpotato import app routes = [] for route, x in sorted(app.view_functions.iteritems()): if route[0:4] == 'api.': routes += [route[4:]] return jsonified({'routes': routes})
def updateLibraryView(self): params = getParams() fireEventAsync('manage.update', full = params.get('full', True)) return jsonified({ 'success': True })
def failed(self): return jsonified({'success': False})
def checkView(self): return jsonified({ 'update_available': self.check(), 'info': self.updater.info() })
def getInfo(self): return jsonified(self.info())
class ProfilePlugin(Plugin): def __init__(self): addEvent('profile.all', self.all) addApiView('profile.save', self.save) addApiView('profile.save_order', self.saveOrder) addApiView('profile.delete', self.delete) addEvent('app.initialize', self.fill, priority = 90) def all(self): db = get_session() profiles = db.query(Profile).all() temp = [] for profile in profiles: temp.append(profile.to_dict(deep = {'types': {}})) return temp def save(self): params = getParams() db = get_session() p = db.query(Profile).filter_by(id = params.get('id')).first() if not p: p = Profile() db.add(p) p.label = params.get('label') p.order = params.get('order', p.order if p.order else 0) p.core = params.get('core', False) #delete old types [db.delete(t) for t in p.types] order = 0 for type in params.get('types', []): t = ProfileType( order = order, finish = type.get('finish') if order > 0 else 1, wait_for = params.get('wait_for'), quality_id = type.get('quality_id') ) p.types.append(t) order += 1 db.commit() profile_dict = p.to_dict(deep = {'types': {}}) return jsonified({ 'success': True, 'profile': profile_dict }) def saveOrder(self): params = getParams() db = get_session() order = 0 for profile in params.get('ids', []): p = db.query(Profile).filter_by(id = profile).first() p.hide = params.get('hidden')[order] p.order = order order += 1 db.commit() return jsonified({ 'success': True }) def delete(self): id = getParam('id') db = get_session() success = False message = '' try: p = db.query(Profile).filter_by(id = id).first() db.delete(p) db.commit() success = True except Exception, e: message = 'Failed deleting Profile: %s' % e log.error(message) return jsonified({ 'success': success, 'message': message })
def doUpdateView(self): return jsonified({'success': self.doUpdate()})
def deleteView(self): release_id = getParam('id') #db.close() return jsonified({'success': self.delete(release_id)})
def getSoonView(self): params = getParams() db = get_session() # Get profiles first, determine pre or post theater profiles = fireEvent('profile.all', single = True) qualities = fireEvent('quality.all', single = True) pre_releases = fireEvent('quality.pre_releases', single = True) id_pre = {} for quality in qualities: id_pre[quality.get('id')] = quality.get('identifier') in pre_releases # See what the profile contain and cache it profile_pre = {} for profile in profiles: contains = {} for profile_type in profile.get('types', []): contains['theater' if id_pre.get(profile_type.get('quality_id')) else 'dvd'] = True profile_pre[profile.get('id')] = contains # Get all active movies q = db.query(Movie) \ .join(Movie.profile, Movie.library) \ .filter(or_(*[Movie.status.has(identifier = s) for s in ['active']])) \ .group_by(Movie.id) # Add limit limit_offset = params.get('limit_offset') limit = 12 if limit_offset: splt = splitString(limit_offset) if isinstance(limit_offset, (str, unicode)) else limit_offset limit = tryInt(splt[0]) all_movies = q.all() if params.get('random', False): random.shuffle(all_movies) movies = [] for movie in all_movies: pp = profile_pre.get(movie.profile.id) eta = movie.library.info.get('release_date', {}) coming_soon = False # Theater quality if pp.get('theater') and fireEvent('searcher.could_be_released', True, eta, single = True): coming_soon = True if pp.get('dvd') and fireEvent('searcher.could_be_released', False, eta, single = True): coming_soon = True if coming_soon: temp = movie.to_dict({ 'profile': {'types': {}}, 'releases': {'files':{}, 'info': {}}, 'library': {'titles': {}, 'files':{}}, 'files': {}, }) movies.append(temp) if len(movies) >= limit: break return jsonified({ 'success': True, 'empty': len(movies) == 0, 'movies': movies, })
def view(self): return jsonified({ 'options': self.getOptions(), 'values': self.getValues() })
def getProgress(self): return jsonified({'progress': self.in_progress})
def tryNextReleaseView(self): trynext = self.tryNextRelease(getParam('id')) return jsonified({'success': trynext})
def available(self): return jsonified({ 'success': True })
def versionView(self): return jsonified({ 'version': self.version() })
def scanView(self): fireEventAsync('renamer.scan') return jsonified({'success': True})
def test(self): return jsonified({'success': self.addToLibrary()})
def getInfo(self): return jsonified(self.updater.info())
def getSoonView(self): params = getParams() db = get_session() now = time.time() # Get profiles first, determine pre or post theater profiles = fireEvent('profile.all', single = True) qualities = fireEvent('quality.all', single = True) pre_releases = fireEvent('quality.pre_releases', single = True) id_pre = {} for quality in qualities: id_pre[quality.get('id')] = quality.get('identifier') in pre_releases # See what the profile contain and cache it profile_pre = {} for profile in profiles: contains = {} for profile_type in profile.get('types', []): contains['theater' if id_pre.get(profile_type.get('quality_id')) else 'dvd'] = True profile_pre[profile.get('id')] = contains # Get all active movies active_status, snatched_status, downloaded_status, available_status = fireEvent('status.get', ['active', 'snatched', 'downloaded', 'available'], single = True) subq = db.query(Movie).filter(Movie.status_id == active_status.get('id')).subquery() q = db.query(Movie).join((subq, subq.c.id == Movie.id)) \ .options(joinedload_all('releases')) \ .options(joinedload_all('profile.types')) \ .options(joinedload_all('library.titles')) \ .options(joinedload_all('library.files')) \ .options(joinedload_all('status')) \ .options(joinedload_all('files')) # Add limit limit_offset = params.get('limit_offset') limit = 12 if limit_offset: splt = splitString(limit_offset) if isinstance(limit_offset, (str, unicode)) else limit_offset limit = tryInt(splt[0]) all_movies = q.all() if params.get('random', False): random.shuffle(all_movies) movies = [] for movie in all_movies: pp = profile_pre.get(movie.profile.id) eta = movie.library.info.get('release_date', {}) or {} coming_soon = False # Theater quality if pp.get('theater') and fireEvent('searcher.could_be_released', True, eta, single = True): coming_soon = True if pp.get('dvd') and fireEvent('searcher.could_be_released', False, eta, single = True): coming_soon = True # Skip if movie is snatched/downloaded/available skip = False for release in movie.releases: if release.status_id in [snatched_status.get('id'), downloaded_status.get('id'), available_status.get('id')]: skip = True break if skip: continue if coming_soon: temp = movie.to_dict({ 'profile': {'types': {}}, 'releases': {'files':{}, 'info': {}}, 'library': {'titles': {}, 'files':{}}, 'files': {}, }) # Don't list older movies if ((not params.get('late') and (not eta.get('dvd') or (eta.get('dvd') and eta.get('dvd') > (now - 2419200)))) or \ (params.get('late') and eta.get('dvd') and eta.get('dvd') < (now - 2419200))): movies.append(temp) if len(movies) >= limit: break db.expire_all() return jsonified({ 'success': True, 'empty': len(movies) == 0, 'movies': movies, })
class ProfilePlugin(Plugin): to_dict = {'types': {}} def __init__(self): addEvent('profile.all', self.all) addEvent('profile.default', self.default) addApiView('profile.save', self.save) addApiView('profile.save_order', self.saveOrder) addApiView('profile.delete', self.delete) addApiView('profile.list', self.allView, docs = { 'desc': 'List all available profiles', 'return': {'type': 'object', 'example': """{ 'success': True, 'list': array, profiles }"""} }) addEvent('app.initialize', self.fill, priority = 90) addEvent('app.load', self.forceDefaults) def forceDefaults(self): # Get all active movies without profile active_status = fireEvent('status.get', 'active', single = True) db = get_session() movies = db.query(Movie).filter(Movie.status_id == active_status.get('id'), Movie.profile == None).all() if len(movies) > 0: default_profile = self.default() for movie in movies: movie.profile_id = default_profile.get('id') db.commit() def allView(self): return jsonified({ 'success': True, 'list': self.all() }) def all(self): db = get_session() profiles = db.query(Profile).all() temp = [] for profile in profiles: temp.append(profile.to_dict(self.to_dict)) db.expire_all() return temp def save(self): params = getParams() db = get_session() p = db.query(Profile).filter_by(id = params.get('id')).first() if not p: p = Profile() db.add(p) p.label = toUnicode(params.get('label')) p.order = params.get('order', p.order if p.order else 0) p.core = params.get('core', False) #delete old types [db.delete(t) for t in p.types] order = 0 for type in params.get('types', []): t = ProfileType( order = order, finish = type.get('finish') if order > 0 else 1, wait_for = params.get('wait_for'), quality_id = type.get('quality_id') ) p.types.append(t) order += 1 db.commit() profile_dict = p.to_dict(self.to_dict) return jsonified({ 'success': True, 'profile': profile_dict }) def default(self): db = get_session() default = db.query(Profile).first() default_dict = default.to_dict(self.to_dict) db.expire_all() return default_dict def saveOrder(self): params = getParams() db = get_session() order = 0 for profile in params.get('ids', []): p = db.query(Profile).filter_by(id = profile).first() p.hide = params.get('hidden')[order] p.order = order order += 1 db.commit() return jsonified({ 'success': True }) def delete(self): id = getParam('id') db = get_session() success = False message = '' try: p = db.query(Profile).filter_by(id = id).first() db.delete(p) db.commit() # Force defaults on all empty profile movies self.forceDefaults() success = True except Exception, e: message = log.error('Failed deleting Profile: %s', e) db.expire_all() return jsonified({ 'success': success, 'message': message })
def updateLibraryView(self): full = getParam('full', default=1) fireEventAsync('manage.update', full=True if full == '1' else False) return jsonified({'success': True})
def test(self): return jsonified({'success': os.path.isfile(self.index_path)})
def allView(self): return jsonified({ 'success': True, 'list': self.all() })
def getTypesView(self): return jsonified({ 'types': self.getTypes() })