def delete(self, show_id, season_id, session): """ Deletes all season releases by show ID and season ID """ try: db.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: season = db.season_by_id(season_id, session) except NoResultFound: raise NotFoundError('seasons with ID %s not found' % season_id) if not db.season_in_show(show_id, season_id): raise BadRequest('season with id %s does not belong to show %s' % (season_id, show_id)) args = release_delete_parser.parse_args() downloaded = args.get('downloaded') is True if args.get('downloaded') is not None else None release_items = [] for release in season.releases: if ( downloaded and release.downloaded or downloaded is False and not release.downloaded or not downloaded ): release_items.append(release) for release in release_items: if args.get('forget'): fire_event('forget', release.title) db.delete_season_release_by_id(release.id) return success_response( 'successfully deleted all releases for season %s from show %s' % (season_id, show_id) )
def post(self, session=None): """ Manage server operations """ data = request.json if data['operation'] == 'reload': try: self.manager.load_config(output_to_console=False) except YAMLError as e: if ( hasattr(e, 'problem') and hasattr(e, 'context_mark') and hasattr(e, 'problem_mark') ): error = {} if e.problem is not None: error.update({'reason': e.problem}) if e.context_mark is not None: error.update( {'line': e.context_mark.line, 'column': e.context_mark.column} ) if e.problem_mark is not None: error.update( {'line': e.problem_mark.line, 'column': e.problem_mark.column} ) raise APIError(message='Invalid YAML syntax', payload=error) except ValueError as e: errors = [] for er in e.errors: errors.append({'error': er.message, 'config_path': er.json_pointer}) raise APIError('Error loading config: %s' % e.args[0], payload={'errors': errors}) response = 'Config successfully reloaded from disk' else: self.manager.shutdown(data.get('force')) response = 'Shutdown requested' return success_response(response)
def delete(self, session=None): """ Clears all rejected entries""" entries = session.query(db.RememberEntry).delete() if entries: session.commit() self.manager.config_changed() return success_response('successfully deleted %i rejected entries' % entries)
def delete(self, show_id, season_id, rel_id, session): """ Delete episode release by show ID, season ID and release ID """ try: db.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: db.season_by_id(season_id, session) except NoResultFound: raise NotFoundError('season with ID %s not found' % season_id) try: release = db.season_release_by_id(rel_id, session) except NoResultFound: raise NotFoundError('release with ID %s not found' % rel_id) if not db.season_in_show(show_id, season_id): raise BadRequest('season with id %s does not belong to show %s' % (season_id, show_id)) if not db.release_in_season(season_id, rel_id): raise BadRequest('release id %s does not belong to season %s' % (rel_id, season_id)) args = delete_parser.parse_args() if args.get('forget'): fire_event('forget', release.title) db.delete_season_release_by_id(rel_id) return success_response( 'successfully deleted release %d from season %d' % (rel_id, season_id) )
def delete(self, list_id, session=None): """ Delete list by ID """ try: el.delete_list_by_id(list_id=list_id, session=session) except NoResultFound: raise NotFoundError('list_id %d does not exist' % list_id) return success_response('list successfully deleted')
def delete(self, show_id, ep_id, session): """ Deletes all episodes releases by show ID and episode ID """ try: series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: episode = series.episode_by_id(ep_id, session) except NoResultFound: raise NotFoundError('episode with ID %s not found' % ep_id) if not series.episode_in_show(show_id, ep_id): raise BadRequest('episode with id %s does not belong to show %s' % (ep_id, show_id)) args = release_delete_parser.parse_args() downloaded = args.get('downloaded') is True if args.get('downloaded') is not None else None release_items = [] for release in episode.releases: if downloaded and release.downloaded or downloaded is False and not release.downloaded or not downloaded: release_items.append(release) for release in release_items: if args.get('forget'): fire_event('forget', release.title) series.delete_release_by_id(release.id) return success_response('successfully deleted all releases for episode %s from show %s' % (ep_id, show_id))
def delete(self, rejected_entry_id, session=None): """ Deletes a rejected entry """ try: entry = session.query(RememberEntry).filter(RememberEntry.id == rejected_entry_id).one() except NoResultFound: raise NotFoundError('rejected entry ID %d not found' % rejected_entry_id) session.delete(entry) return success_response('successfully deleted rejected entry %i' % rejected_entry_id)
def delete(self, entry_id, session=None): """Delete a pending entry""" try: entry = db.get_entry_by_id(session, entry_id) except NoResultFound: raise NotFoundError('No pending entry with ID %s' % entry_id) session.delete(entry) return success_response('successfully deleted entry with ID %s' % entry_id)
def delete(self, seen_entry_id, session): """ Delete seen entry by ID """ try: entry = db.get_entry_by_id(seen_entry_id, session=session) except NoResultFound: raise NotFoundError('Could not delete entry ID {0}'.format(seen_entry_id)) db.forget_by_id(entry.id, session=session) return success_response('successfully deleted seen entry {}'.format(seen_entry_id))
def delete(self, list_id, session=None): """ Delete list by ID """ try: movie_list = ml.get_list_by_id(list_id=list_id, session=session) except NoResultFound: raise NotFoundError("list_id %d does not exist" % list_id) session.delete(movie_list) return success_response("successfully deleted list")
def delete(self, list_id, movie_id, session=None): """ Delete a movie by list ID and movie ID """ try: movie = ml.get_movie_by_id(list_id=list_id, movie_id=movie_id, session=session) except NoResultFound: raise NotFoundError("could not find movie with id %d in list %d" % (movie_id, list_id)) log.debug("deleting movie %d", movie.id) session.delete(movie) return success_response("successfully deleted movie %d" % movie_id)
def delete(self, failed_entry_id, session=None): """ Delete failed entry by ID """ try: failed_entry = session.query(FailedEntry).filter(FailedEntry.id == failed_entry_id).one() except NoResultFound: raise NotFoundError('could not find entry with ID %i' % failed_entry_id) log.debug('deleting failed entry: "%s"' % failed_entry.title) session.delete(failed_entry) return success_response('successfully delete failed entry %d' % failed_entry_id)
def delete(self, list_id, entry_id, session=None): """ Delete an entry by list ID and entry ID """ try: entry = el.get_entry_by_id(list_id=list_id, entry_id=entry_id, session=session) except NoResultFound: raise NotFoundError('could not find entry with id %d in list %d' % (entry_id, list_id)) log.debug('deleting movie %d', entry.id) session.delete(entry) return success_response('successfully deleted entry %d' % entry.id)
def get(self, session=None): """ Reset the DB of a specific plugin """ args = plugin_parser.parse_args() plugin = args['plugin_name'] try: reset_schema(plugin) except ValueError: raise BadRequest('The plugin {} has no stored schema to reset'.format(plugin)) return success_response('Plugin {} DB reset was successful'.format(plugin))
def put(self, session=None): """ Change user password """ user = current_user data = request.json try: change_password(username=user.name, password=data.get('password'), session=session) except WeakPassword as e: raise BadRequest(e.value) return success_response('Successfully changed user password')
def delete(self, task, session=None): """ Delete a task """ try: self.manager.config['tasks'].pop(task) self.manager.user_config['tasks'].pop(task) except KeyError: raise NotFoundError('task does not exist') self.manager.save_config() self.manager.config_changed() return success_response('successfully deleted task')
def delete(self, show_id, session): """ Deletes all episodes of a show""" try: show = series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) args = delete_parser.parse_args() forget = args.get('forget') for episode in show.episodes: series.remove_series_entity(show.name, episode.identifier, forget) return success_response('successfully removed all series %s episodes from DB' % show_id)
def delete(self, show_id, session): """ Remove series from DB """ try: show = series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('Show with ID %s not found' % show_id) name = show.name args = delete_parser.parse_args() series.remove_series(name, forget=args.get('forget')) return success_response('successfully removed series %s from DB' % show_id)
def get(self, session=None): """Restarts IRC connections""" from flexget.plugins.daemon.irc import irc_manager if irc_manager is None: raise BadRequest('IRC daemon does not appear to be running') args = irc_parser.parse_args() connection = args.get('name') try: irc_manager.restart_connections(connection) except KeyError: raise NotFoundError('Connection {} is not a valid IRC connection'.format(connection)) return success_response('Successfully restarted connection(s)')
def get(self, session=None): """Stops IRC connections""" from flexget.plugins.daemon.irc import irc_manager if irc_manager is None: raise BadRequest('IRC daemon does not appear to be running') args = irc_stop_parser.parse_args() name = args.get('name') wait = args.get('wait') try: irc_manager.stop_connections(wait=wait, name=name) except KeyError: raise NotFoundError('Connection {} is not a valid IRC connection'.format(name)) return success_response('Successfully stopped connection(s)')
def post(self, session=None): """ Update config """ data = request.json try: raw_config = base64.b64decode(data['raw_config']) except (TypeError, binascii.Error): raise BadRequest(message='payload was not a valid base64 encoded string') try: config = yaml.safe_load(raw_config) except YAMLError as e: if hasattr(e, 'problem') and hasattr(e, 'context_mark') and hasattr(e, 'problem_mark'): error = {} if e.problem is not None: error.update({'reason': e.problem}) if e.context_mark is not None: error.update({'line': e.context_mark.line, 'column': e.context_mark.column}) if e.problem_mark is not None: error.update({'line': e.problem_mark.line, 'column': e.problem_mark.column}) raise BadRequest(message='Invalid YAML syntax', payload=error) try: backup_path = self.manager.update_config(config) except ValueError as e: errors = [] for er in e.errors: errors.append({'error': er.message, 'config_path': er.json_pointer}) raise BadRequest( message='Error loading config: %s' % e.args[0], payload={'errors': errors} ) try: self.manager.backup_config() except Exception as e: raise APIError( message='Failed to create config backup, config updated but NOT written to file', payload={'reason': str(e)}, ) try: with open(self.manager.config_path, 'w', encoding='utf-8') as f: f.write(raw_config.decode('utf-8').replace('\r\n', '\n')) except Exception as e: raise APIError( message='Failed to write new config to file, please load from backup', payload={'reason': str(e), 'backup_path': backup_path}, ) return success_response('Config was loaded and successfully updated to file')
def delete(self, session): """ Delete seen entries """ args = seen_base_parser.parse_args() value = args['value'] local = args['local'] if value: value = unquote(value) value = '%' + value + '%' seen_entries_list = db.search(value=value, status=local, session=session) deleted = 0 for se in seen_entries_list: db.forget_by_id(se.id, session=session) deleted += 1 return success_response('successfully deleted %i entries' % deleted)
def delete(self, session=None): """Delete pending entries""" args = filter_parser.parse_args() # Filter params task_name = args.get('task_name') approved = args.get('approved') deleted = session.query(db.PendingEntry) if task_name: deleted = deleted.filter(db.PendingEntry.task_name == task_name) if approved: deleted = deleted.filter(db.PendingEntry.approved == approved) deleted = deleted.delete() return success_response('deleted %s pending entries'.format(deleted))
def delete(self, show_id, ep_id, session): """ Forgets episode by show ID and episode ID """ try: show = series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: episode = series.episode_by_id(ep_id, session) except NoResultFound: raise NotFoundError('episode with ID %s not found' % ep_id) if not series.episode_in_show(show_id, ep_id): raise BadRequest('episode with id %s does not belong to show %s' % (ep_id, show_id)) args = delete_parser.parse_args() series.remove_series_entity(show.name, episode.identifier, args.get('forget')) return success_response('successfully removed episode %s from show %s' % (ep_id, show_id))
def delete(self, schedule_id, session=None): """ Delete a schedule """ schedules = self.manager.config.get('schedules') # Checks for boolean config if schedules is True: raise Conflict('Schedules usage is set to default, cannot delete') elif schedules is False: raise Conflict('Schedules are disables in config') for i in range(len(self.manager.config.get('schedules', []))): if id(self.manager.config['schedules'][i]) == schedule_id: del self.manager.config['schedules'][i] self.manager.save_config() self.manager.config_changed() return success_response('schedule %d successfully deleted' % schedule_id) raise NotFoundError('schedule %d not found' % schedule_id)
def put(self, show_id, ep_id, session): """ Marks all downloaded releases as not downloaded """ try: series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: episode = series.episode_by_id(ep_id, session) except NoResultFound: raise NotFoundError('episode with ID %s not found' % ep_id) if not series.episode_in_show(show_id, ep_id): raise BadRequest('episode with id %s does not belong to show %s' % (ep_id, show_id)) for release in episode.releases: if release.downloaded: release.downloaded = False return success_response( 'successfully reset download status for all releases for episode %s from show %s' % (ep_id, show_id))
def post(self, session=None): """ Login with username and password """ data = request.json user_name = data.get('username') password = data.get('password') if data: user = session.query(User).filter(User.name == user_name.lower()).first() if user: if user_name == 'flexget' and not user.password: raise Unauthorized('If this is your first time running the WebUI you need to set a password via' ' the command line by running `flexget web passwd <new_password>`') if user.password and check_password_hash(user.password, password): args = login_parser.parse_args() login_user(user, remember=args['remember']) return success_response('user logged in') raise Unauthorized('Invalid username or password')
def delete(self, show_id, season_id, session): """ Forgets season by show ID and season ID """ try: show = db.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: season = db.season_by_id(season_id, session) except NoResultFound: raise NotFoundError('season with ID %s not found' % season_id) if not db.season_in_show(show_id, season_id): raise BadRequest('season with id %s does not belong to show %s' % (season_id, show_id)) args = delete_parser.parse_args() db.remove_series_entity(show.name, season.identifier, args.get('forget')) return success_response( 'successfully removed season %s from show %s' % (season_id, show_id) )
def put(self, show_id, season_id, session): """ Marks all downloaded season releases as not downloaded """ try: db.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: season = db.season_by_id(season_id, session) except NoResultFound: raise NotFoundError('season with ID %s not found' % season_id) if not db.season_in_show(show_id, season_id): raise BadRequest('season with id %s does not belong to show %s' % (season_id, show_id)) for release in season.releases: if release.downloaded: release.downloaded = False return success_response( 'successfully reset download status for all releases for season %s from show %s' % (season_id, show_id) )
def post(self, session=None): """Perform DB operations""" data = request.json operation = data['operation'] if operation == 'cleanup': self.manager.db_cleanup(force=True) msg = 'DB Cleanup finished' elif operation == 'vacuum': session.execute('VACUUM') session.commit() msg = 'DB VACUUM finished' elif operation == 'plugin_reset': plugin_name = data.get('plugin_name') if not plugin_name: raise BadRequest('\'plugin_name\' attribute must be used when trying to reset plugin') try: reset_schema(plugin_name) msg = 'Plugin {} DB reset was successful'.format(plugin_name) except ValueError: raise BadRequest('The plugin {} has no stored schema to reset'.format(plugin_name)) return success_response(msg)
def post(self, session=None): """ Manage server operations """ data = request.json if data['operation'] == 'reload': try: self.manager.load_config(output_to_console=False) except YAMLError as e: if (hasattr(e, 'problem') and hasattr(e, 'context_mark') and hasattr(e, 'problem_mark')): error = {} if e.problem is not None: error.update({'reason': e.problem}) if e.context_mark is not None: error.update({ 'line': e.context_mark.line, 'column': e.context_mark.column }) if e.problem_mark is not None: error.update({ 'line': e.problem_mark.line, 'column': e.problem_mark.column }) raise APIError(message='Invalid YAML syntax', payload=error) except ValueError as e: errors = [] for er in e.errors: errors.append({ 'error': er.message, 'config_path': er.json_pointer }) raise APIError('Error loading config: %s' % e.args[0], payload={'errors': errors}) response = 'Config successfully reloaded from disk' else: self.manager.shutdown(data.get('force')) response = 'Shutdown requested' return success_response(response)
def post(self, session=None): """Perform DB operations""" data = request.json operation = data['operation'] if operation == 'cleanup': self.manager.db_cleanup(force=True) msg = 'DB Cleanup finished' elif operation == 'vacuum': session.execute('VACUUM') session.commit() msg = 'DB VACUUM finished' elif operation == 'plugin_reset': plugin_name = data.get('plugin_name') if not plugin_name: raise BadRequest( '\'plugin_name\' attribute must be used when trying to reset plugin' ) try: reset_schema(plugin_name) msg = 'Plugin {} DB reset was successful'.format(plugin_name) except ValueError: raise BadRequest('The plugin {} has no stored schema to reset'.format(plugin_name)) return success_response(msg)
def post(self, session=None): """ Login with username and password """ data = request.json user_name = data.get('username') password = data.get('password') if data: user = session.query(User).filter( User.name == user_name.lower()).first() if user: if user_name == 'flexget' and not user.password: raise Unauthorized( 'If this is your first time running the WebUI you need to set a password via' ' the command line by running `flexget web passwd <new_password>`' ) if user.password and check_password_hash( user.password, password): args = login_parser.parse_args() login_user(user, remember=args['remember']) return success_response('user logged in') raise Unauthorized('Invalid username or password')
def delete(self, show_id, ep_id, rel_id, session): """ Delete episode release by show ID, episode ID and release ID """ try: series.show_by_id(show_id, session=session) except NoResultFound: raise NotFoundError('show with ID %s not found' % show_id) try: series.episode_by_id(ep_id, session) except NoResultFound: raise NotFoundError('episode with ID %s not found' % ep_id) try: release = series.release_by_id(rel_id, session) except NoResultFound: raise NotFoundError('release with ID %s not found' % rel_id) if not series.episode_in_show(show_id, ep_id): raise BadRequest('episode with id %s does not belong to show %s' % (ep_id, show_id)) if not series.release_in_episode(ep_id, rel_id): raise BadRequest('release id %s does not belong to episode %s' % (rel_id, ep_id)) args = delete_parser.parse_args() if args.get('forget'): fire_event('forget', release.title) series.delete_release_by_id(rel_id) return success_response('successfully deleted release %d from episode %d' % (rel_id, ep_id))
def post(self, session=None): """ Validate flexget custom schema""" # If validation passed, all is well return success_response('payload is valid')
def delete(self, session=None): """ Clear all failed entries """ log.debug('deleting all failed entries') deleted = session.query(db.FailedEntry).delete() return success_response('successfully deleted %d failed entries' % deleted)
def get(self, session=None): """ Shutdown Flexget Daemon """ args = shutdown_parser.parse_args() self.manager.shutdown(args['force']) return success_response('Shutdown requested')
def get(self, session=None): """ Make all plugins clean un-needed data from the database """ self.manager.db_cleanup(force=True) return success_response('DB Cleanup triggered')
def get(self, session=None): """ Logout and clear session cookies """ flask_session.clear() resp = success_response('User logged out') resp.set_cookie('flexget.token', '', expires=0) return resp
def get(self, session=None): """ Potentially increase performance and decrease database size""" session.execute('VACUUM') session.commit() return success_response('DB VACUUM triggered')
def post(self, session: Session = None) -> Response: """ Update config """ config = {} data = request.json try: raw_config = base64.b64decode(data['raw_config']) except (TypeError, binascii.Error): raise BadRequest( message='payload was not a valid base64 encoded string') try: config = yaml.safe_load(raw_config) except YAMLError as e: if isinstance(e, MarkedYAMLError): error: Dict[str, int] = {} if e.problem is not None: error.update({'reason': e.problem}) if e.context_mark is not None: error.update({ 'line': e.context_mark.line, 'column': e.context_mark.column }) if e.problem_mark is not None: error.update({ 'line': e.problem_mark.line, 'column': e.problem_mark.column }) raise BadRequest(message='Invalid YAML syntax', payload=error) try: backup_path = self.manager.update_config(config) except ConfigError as e: errors = [] for er in e.errors: errors.append({ 'error': er.message, 'config_path': er.json_pointer }) raise BadRequest(message=f'Error loading config: {e.args[0]}', payload={'errors': errors}) try: self.manager.backup_config() except Exception as e: raise APIError( message= 'Failed to create config backup, config updated but NOT written to file', payload={'reason': str(e)}, ) try: with open(self.manager.config_path, 'w', encoding='utf-8') as f: f.write(raw_config.decode('utf-8').replace('\r\n', '\n')) except Exception as e: raise APIError( message= 'Failed to write new config to file, please load from backup', payload={ 'reason': str(e), 'backup_path': backup_path }, ) return success_response( 'Config was loaded and successfully updated to file')