示例#1
0
文件: api.py 项目: Flexget/Flexget
    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)
        )
示例#2
0
文件: server.py 项目: Flexget/Flexget
 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)
示例#3
0
文件: api.py 项目: Flexget/Flexget
 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)
示例#4
0
文件: api.py 项目: Flexget/Flexget
    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)
        )
示例#5
0
 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')
示例#6
0
    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))
示例#7
0
 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)
示例#8
0
文件: api.py 项目: Flexget/Flexget
 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)
示例#9
0
文件: api.py 项目: Flexget/Flexget
 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))
示例#10
0
 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")
示例#11
0
 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)
示例#12
0
 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)
示例#13
0
 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)
示例#14
0
文件: database.py 项目: bbeck/Flexget
 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))
示例#15
0
文件: user.py 项目: Flexget/Flexget
 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')
示例#16
0
文件: tasks.py 项目: Flexget/Flexget
    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')
示例#17
0
 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)
示例#18
0
    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)
示例#19
0
    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)')
示例#20
0
    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)')
示例#21
0
文件: server.py 项目: Flexget/Flexget
    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')
示例#22
0
文件: api.py 项目: Flexget/Flexget
    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)
示例#23
0
文件: api.py 项目: Flexget/Flexget
    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))
示例#24
0
    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))
示例#25
0
    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)
示例#26
0
    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))
示例#27
0
    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')
示例#28
0
文件: api.py 项目: Flexget/Flexget
    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)
        )
示例#29
0
文件: api.py 项目: Flexget/Flexget
    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)
        )
示例#30
0
 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)
示例#31
0
 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)
示例#32
0
 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)
示例#33
0
    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')
示例#34
0
    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))
示例#35
0
 def post(self, session=None):
     """ Validate flexget custom schema"""
     # If validation passed, all is well
     return success_response('payload is valid')
示例#36
0
 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)
示例#37
0
 def get(self, session=None):
     """ Shutdown Flexget Daemon """
     args = shutdown_parser.parse_args()
     self.manager.shutdown(args['force'])
     return success_response('Shutdown requested')
示例#38
0
 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')
示例#39
0
 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
示例#40
0
 def get(self, session=None):
     """ Potentially increase performance and decrease database size"""
     session.execute('VACUUM')
     session.commit()
     return success_response('DB VACUUM triggered')
示例#41
0
    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')