return session.query(User).filter(User.name == username).first() @app.before_request def check_valid_login(): # Allow access to root, login and swagger documentation without authentication if request.path == '/' or request.path.startswith('/auth/login') or \ request.path.startswith('/auth/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization auth_api = api.namespace('auth', description='Authentication') login_api_schema = api.schema( 'auth.login', { 'type': 'object', 'properties': { 'username': { 'type': 'string' }, 'password': { 'type': 'string' } } }) login_parser = api.parser()
from __future__ import unicode_literals, division, absolute_import import datetime from math import ceil from flask import jsonify from flask import request from flask_restplus import inputs from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.plugins.filter import series series_api = api.namespace('series', description='Flexget Series operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'})
from __future__ import unicode_literals, division, absolute_import from flask import jsonify from flexget.api import api, APIResource from flexget.utils.imdb import ImdbSearch imdb_api = api.namespace('imdb', description='IMDB lookup endpoint') class ObjectsContainer(object): movie_object = { 'type': 'object', 'properties': { 'imdb_id': {'type': 'string'}, 'match': {'type': 'number'}, 'name': {'type': 'string'}, 'url': {'type': 'string'}, 'year': {'type': 'string'}, 'thumbnail': {'type': 'string'} } } return_object = {'type': 'array', 'items': movie_object} return_schema = api.schema('imdb_search_schema', ObjectsContainer.return_object) @imdb_api.route('/search/<string:title>/') @api.doc(params={'title': 'Movie name or IMDB ID'})
from __future__ import unicode_literals, division, absolute_import import copy import logging from math import ceil from flask import jsonify, request from sqlalchemy.orm.exc import NoResultFound import flexget.plugins.list.entry_list as el from flexget.api import api, APIResource log = logging.getLogger('entry_list') entry_list_api = api.namespace('entry_list', description='Entry List operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema)
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flask import jsonify from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import NotFoundError, BadRequest, etag from flexget.components.tvmaze.api_tvmaze import APITVMaze tvmaze_api = api.namespace('tvmaze', description='TVMaze Shows') class ObjectsContainer(object): actor_object = { 'type': 'object', 'properties': { "last_update": { 'type': 'string', 'format': 'date-time' }, "medium_image": { 'type': 'string' }, "name": { 'type': 'string' }, "original_image": { 'type': 'string' }, "tvmaze_id": {
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin from flask import jsonify from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.internal.api_tvmaze import APITVMaze as tvm tvmaze_api = api.namespace('tvmaze', description='TVMaze Shows') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) actor_object = { 'type': 'object', 'properties': { "last_update": {'type': 'string', 'format': 'date-time'}, "medium_image": {'type': 'string'}, "name": {'type': 'string'}, "original_image": {'type': 'string'}, "tvmaze_id": {'type': 'integer'}, "url": {'type': 'string'}, }
from flask import jsonify, Response from flask import request from flexget.api import api, APIResource, ApiError, NotFoundError from flexget.config_schema import process_config from flexget.entry import Entry from flexget.event import event from flexget.options import get_parser from flexget.task import task_phases from flexget.utils import json from flexget.utils import requests from flexget.utils.lazy_dict import LazyLookup # Tasks API tasks_api = api.namespace('tasks', description='Manage Tasks') tasks_list_api_schema = api.schema('tasks.list', { "type": "object", "properties": { "tasks": { "type": "array", "items": {'$ref': '#/definitions/tasks.task'} } }, 'additionalProperties': False }) task_schema_validate = { 'type': 'object', 'properties': {
from __future__ import unicode_literals, division, absolute_import import logging from flask import request, jsonify from flexget.api import api, APIResource from flexget.api.app import empty_response, etag from flexget.components.variables.variables import variables_from_db, variables_to_db log = logging.getLogger('variables') variables_api = api.namespace('variables', description='View and edit config variables') @variables_api.route('/') class VariablesAPI(APIResource): @etag @api.response(200, model=empty_response) def get(self, session=None): """ Get variables data from DB """ return jsonify(variables_from_db()) @api.response(201, 'Successfully updated variables file') @api.validate(empty_response) @api.doc( description='Note that editing variables may not be persistent, depending on user config' ) def put(self, session=None): """ Store variables data to DB """ data = request.json
from __future__ import unicode_literals, division, absolute_import from builtins import * from flask import jsonify, request from jsonschema import RefResolutionError from flexget.api import api, APIResource from flexget.config_schema import schema_paths, resolve_ref schema_api = api.namespace('schema', description='Config and plugin schemas') _plugins_cache = None schema_api_list = api.schema('schema.list', { 'type': 'object', 'properties': { 'schemas': { 'type': 'array', 'items': {'type': 'object'} } } }) @schema_api.route('/') class SchemaAllAPI(APIResource): @api.response(200, model=schema_api_list) def get(self, session=None): """ List all schema definitions """ schemas = {} for path in schema_paths: schemas[path] = resolve_ref(path)
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import datetime from math import ceil from flask import jsonify, request from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.api.series import NoResultFound from flexget.plugins.filter import movie_queue as mq from flexget.utils import qualities movie_queue_api = api.namespace( 'movie_queue', description='Movie Queue operations (DEPRECATED)') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema)
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin from flask.helpers import send_file from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import APIError, BadRequest from flexget.utils.cache import cached_resource from requests import RequestException cached_api = api.namespace('cached', description='Cache remote resources') cached_parser = api.parser() cached_parser.add_argument('url', required=True, help='URL to cache') cached_parser.add_argument('force', type=inputs.boolean, default=False, help='Force fetching remote resource') @cached_api.route('/') @api.doc( description= 'Returns a cached copy of the requested resource, matching its mime type') class CachedResource(APIResource): @api.response(200, description='Cached resource') @api.response(BadRequest) @api.response(APIError) @api.doc(parser=cached_parser) def get(self, session=None): """ Cache remote resources """
from datetime import datetime from Queue import Queue, Empty from flask import request, jsonify, Response from flexget.options import get_parser from flexget.api import api, APIResource from flexget.utils import json from json import JSONEncoder from flexget.event import event from flexget.utils.lazy_dict import LazyLookup execution_api = api.namespace('execution', description='Execute tasks') def _task_info_dict(task): return { 'id': int(task.id), 'name': task.name, 'current_phase': task.current_phase, 'current_plugin': task.current_plugin, } task_info_schema = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'name': {'type': 'string'}, 'current_phase': {'type': 'string'}, 'current_plugin': {'type': 'string'},
from flask import jsonify from flexget.api import api, APIResource from flexget.config_schema import schema_paths, resolve_ref schema_api = api.namespace('schema', description='Flexget JSON schema') @schema_api.route('/') class SchemaAllAPI(APIResource): def get(self, session=None): schemas = {} for path in schema_paths: schemas[path] = resolve_ref(path) return jsonify({'schemas': schemas}) @schema_api.route('/<path:path>') @api.doc(params={'path': 'Path of schema'}) @api.response(404, 'invalid schema path') class SchemaAPI(APIResource): def get(self, path, session=None): path = '/schema/%s' % path if path in schema_paths: return resolve_ref(path) return {'error': 'invalid schema path'}, 404
from math import ceil from flask import jsonify, request from flask_restplus import inputs from loguru import logger from flexget.api import APIResource, api from flexget.api.app import BadRequest, NotFoundError, etag, pagination_headers from flexget.plugin import DependencyError, get_plugin_by_name, get_plugins logger = logger.bind(name='plugins') plugins_api = api.namespace('plugins', description='Get Flexget plugins') class ObjectsContainer: phase_object = { 'type': 'object', 'properties': { 'phase': { 'type': 'string' }, 'priority': { 'type': 'integer' } }, } plugin_object = { 'type': 'object', 'properties': {
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flask import jsonify from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import BadRequest, NotFoundError, success_response, base_message_schema, empty_response irc_api = api.namespace('irc', description='View and manage IRC connections') irc_parser = api.parser() irc_parser.add_argument('name', help='Name of connection. Leave empty to apply to all connections.') class ObjectsContainer(object): connection_object = { 'type': 'object', 'properties': { 'alive': {'type': 'boolean'}, 'channels': { 'type': 'array', 'items': { 'type': 'object', 'patternProperties': { '\w': {'type': 'integer'} } } }, 'connected_channels': {'type': 'array', 'items': {'type': 'string'}}, 'port': {'type': 'integer'}, 'server': {'type': 'string'} }
from __future__ import unicode_literals, division, absolute_import from math import ceil from operator import itemgetter from flask import jsonify, request from flexget.api import api, APIResource from flexget.plugins.filter import movie_queue as mq from flexget.utils import qualities movie_queue_api = api.namespace('movie_queue', description='Movie Queue operations') movie_object = { 'type': 'object', 'properties': { 'added': {'type': 'string'}, 'downloaded': {'type': 'string'}, 'entry_original_url': {'type': 'string'}, 'entry_title': {'type': 'string'}, 'entry_url': {'type': 'string'}, 'id': {'type': 'integer'}, 'imdb_id': {'type': 'string'}, 'quality': {'type': 'string'}, 'title': {'type': 'string'}, 'tmdb_id': {'type': 'string'}, } } movie_queue_schema = { 'type': 'object',
# Update our cache to mark the items that have expired for chunk in chunked(expired_series): num = session.query(TVDBSeries).filter(TVDBSeries.id.in_(chunk)).update({'expired': True}, 'fetch') log.debug('%s series marked as expired', num) for chunk in chunked(expired_episodes): num = session.query(TVDBEpisode).filter(TVDBEpisode.id.in_(chunk)).update({'expired': True}, 'fetch') log.debug('%s episodes marked as expired', num) # Save the time of this update session.commit() persist['last_local'] = datetime.now() persist['last_server'] = new_server tvdb_api = api.namespace('tvdb', description='TheTVDB Shows') tvdb_api_parser = api.parser() tvdb_api_parser.add_argument('search', type=str, required=True, help='TV Show name or tvdbid') @tvdb_api.route('/search/') class TVDBSearchApi(APIResource): @api.doc(parser=tvdb_api_parser) @api.response(400, 'missing search parameter') def get(self, session=None): args = tvdb_api_parser.parse_args() search = args['search'] if not search:
base_message_schema, etag, success_response, ) from flexget.config_schema import process_config from flexget.entry import Entry from flexget.event import event from flexget.log import capture_logs from flexget.options import get_parser from flexget.task import task_phases from flexget.terminal import capture_console from flexget.utils import json, requests from flexget.utils.lazy_dict import LazyLookup # Tasks API tasks_api = api.namespace('tasks', description='Manage Tasks') class ObjectsContainer: tasks_list_object = { 'oneOf': [ { 'type': 'array', 'items': { '$ref': '#/definitions/tasks.task' } }, { 'type': 'array', 'items': { 'type': 'string'
import traceback from time import sleep import cherrypy from flask import Response from flask_restplus import inputs from pyparsing import Word, Keyword, Group, Forward, Suppress, OneOrMore, oneOf, White, restOfLine, ParseException, \ Combine from pyparsing import nums, alphanums, printables from flexget._version import __version__ from flexget.api import api, APIResource, ApiError, __version__ as __api_version__ log = logging.getLogger('api.server') server_api = api.namespace('server', description='Manage Daemon') @server_api.route('/reload/') class ServerReloadAPI(APIResource): @api.response(ApiError, description='Error loading the config') @api.response(200, description='Newly reloaded config') def get(self, session=None): """ Reload Flexget config """ log.info('Reloading config from disk.') try: self.manager.load_config() except ValueError as e: raise ApiError('Error loading config: %s' % e.args[0]) log.info('Config successfully reloaded from disk.')
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flask import request, jsonify from flask_login import current_user from flexget.api import api, APIResource from flexget.api.app import BadRequest, base_message_schema, success_response from flexget.webserver import change_password, generate_token, WeakPassword user_api = api.namespace('user', description='Manage user login credentials') class ObjectsContainer(object): user_password_input = { 'type': 'object', 'properties': { 'password': {'type': 'string'} }, 'required': ['password'], 'additionalProperties': False } user_token_response = { 'type': 'object', 'properties': { 'token': {'type': 'string'} } }
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin import logging from flask import jsonify, request from math import ceil from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response, etag, NotFoundError, pagination_headers from flexget.plugins.filter.remember_rejected import RememberEntry, get_rejected log = logging.getLogger('rejected') rejected_api = api.namespace( 'rejected', description='View and manage remembered rejected entries') def rejected_entry_to_dict(entry): return { 'id': entry.id, 'added': entry.added, 'expires': entry.expires, 'title': entry.title, 'url': entry.url, 'rejected_by': entry.rejected_by, 'reason': entry.reason } class ObjectsContainer(object):
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin import logging from math import ceil from flask import jsonify, request from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response, NotFoundError, etag, pagination_headers from flexget.plugins.filter.retry_failed import FailedEntry, get_failures log = logging.getLogger('failed_api') retry_failed_api = api.namespace('failed', description='View and manage failed entries') class ObjectsContainer(object): retry_failed_entry_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'title': {'type': 'string'}, 'url': {'type': 'string'}, 'added_at': {'type': 'string', 'format': 'date-time'}, 'reason': {'type': 'string'}, 'count': {'type': 'integer'}, 'retry_time': {'type': ['string', 'null'], 'format': 'date-time'} }, 'required': ['id', 'title', 'url', 'added_at', 'reason', 'count', 'retry_time'],
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin from flask import request from flask_login import current_user from flexget.api import api, APIResource from flexget.webserver import change_password, generate_token, WeakPassword user_api = api.namespace('user', description='Manage user login credentials') user_password_input = { 'type': 'object', 'properties': { 'password': {'type': 'string'} } } user_password_input_schema = api.schema('user_password_input', user_password_input) default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'})
def load_user(username, session=None): return session.query(User).filter(User.name == username).first() @app.before_request def check_valid_login(): # Allow access to root, login and swagger documentation without authentication if request.path == '/' or request.path.startswith('/login') or \ request.path.startswith('/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization login_api = api.namespace('login', description='API Authentication') login_api_schema = api.schema('login', { 'type': 'object', 'properties': { 'username': {'type': 'string'}, 'password': {'type': 'string'} } }) login_parser = api.parser() login_parser.add_argument('remember', type=bool, required=False, default=False, help='Remember for next time') @login_api.route('/') @api.doc(description='Login to API with username and password')
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import copy from flask import request, jsonify from flexget.manager import manager from flexget.plugins.daemon.scheduler import schedule_schema, scheduler, scheduler_job_map from flexget.api import api, APIResource schedule_api = api.namespace('schedules', description='Task Scheduler') # SwaggerUI does not yet support anyOf or oneOf schedule_schema = copy.deepcopy(schedule_schema) schedule_schema['properties']['id'] = {'type': 'integer'} api_schedule_schema = api.schema('schedules.schedule', schedule_schema) api_schedules_list_schema = api.schema('schedules.list', { 'type': 'object', 'properties': { 'schedules': { 'type': 'array', 'items': schedule_schema } } }) def _schedule_by_id(schedule_id): for schedule in manager.config.get('schedules', []): if id(schedule) == schedule_id:
from __future__ import unicode_literals, division, absolute_import import copy from flask import jsonify from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.internal.api_trakt import ApiTrakt as at, list_actors, get_translations_dict trakt_api = api.namespace('trakt', description='Trakt lookup endpoint') class objects_container(object): internal_image_object = { "type": "object", "properties": { "full": {"type": ["string", "null"]}, "medium": {"type": ["string", "null"]}, "thumb": {"type": ["string", "null"]} }, 'additionalProperties': False } images_object = { "type": "object", "properties": { "banner": internal_image_object, "clearart": internal_image_object, "fanart": internal_image_object, "logo": internal_image_object,
from flask import jsonify, request from flask_restplus import inputs from future.moves.urllib.parse import unquote from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.api.app import ( NotFoundError, base_message_schema, success_response, etag, pagination_headers, ) from . import db seen_api = api.namespace('seen', description='Managed Flexget seen entries and fields') class ObjectsContainer(object): seen_field_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'field': { 'type': 'string' }, 'value': { 'type': 'string' },
import copy import datetime from math import ceil from flask import jsonify from flask import request from flask_restplus import inputs from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource, ApiClient from flexget.event import fire_event from flexget.plugin import PluginError from flexget.plugins.filter import series series_api = api.namespace('series', description='Flexget Series operations') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'}) begin_object = { 'type': 'object',
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin import logging from math import ceil from flask import jsonify, request from flask_restplus import inputs from flexget.plugin import get_plugins, get_plugin_by_name, DependencyError from flexget.api import api, APIResource from flexget.api.app import BadRequest, NotFoundError, etag, pagination_headers log = logging.getLogger('plugins') plugins_api = api.namespace('plugins', description='Get Flexget plugins') class ObjectsContainer(object): phase_object = { 'type': 'object', 'properties': { 'phase': {'type': 'string'}, 'priority': {'type': 'integer'} } } plugin_object = { 'type': 'object', 'properties': { 'name': {'type': 'string'},
import copy from flask import request from flexget.config_schema import process_config from flexget.api import api, APIResource, ApiError, NotFoundError # Tasks API tasks_api = api.namespace('tasks', description='Manage Tasks') task_api_schema = { 'type': 'object', 'properties': { 'name': {'type': 'string'}, 'config': {'$ref': '/schema/plugins'} }, 'additionalProperties': False } tasks_api_schema = { "type": "object", "properties": { "tasks": { "type": "array", "items": task_api_schema } }, 'additionalProperties': False }
from __future__ import unicode_literals, division, absolute_import from builtins import * import logging from math import ceil from flask import jsonify from sqlalchemy import desc from flexget.api import api, APIResource from flexget.plugins.output.history import History log = logging.getLogger('history') history_api = api.namespace('history', description='Entry History') history_api_schema = { 'type': 'object', 'properties': { 'entries': { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'details': {'type': 'string'}, 'filename': {'type': 'string'}, 'id': {'type': 'integer'}, 'task': {'type': 'string'}, 'time': {'type': 'string'}, 'title': {'type': 'string'}, 'url': {'type': 'string'}
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin from future.moves.urllib.parse import unquote import copy from math import ceil from flask import jsonify, request from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.filter import seen seen_api = api.namespace('seen', description='Managed Flexget seen entries and fields') PLUGIN_TASK_NAME = 'seen_plugin_API' # Name of task to use when adding entries via API default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) seen_field_object = { 'type': 'object',
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import request from flexget.api import api, APIResource, NotFoundError from flexget.plugins.modify.config_secrets import secrets_from_db, secrets_to_db log = logging.getLogger('secrets') secrets_api = api.namespace('secrets', description='View and edit secrets') empty_object = api.schema('empty_object', {'type': 'object'}) @secrets_api.route('/') class SecretsAPI(APIResource): @api.response(200) @api.response(NotFoundError) def get(self, session=None): return secrets_from_db() @api.response(201, 'Successfully updated secrets file') @api.response(NotFoundError) @api.validate(empty_object) @api.doc( description= 'Note that editing secrets may not be persistent, depending on user config' ) def put(self, session=None):
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import request from flexget.api import api, APIResource, NotFoundError from flexget.plugins.modify.config_secrets import secrets_from_db, secrets_to_db log = logging.getLogger('secrets') secrets_api = api.namespace('secrets', description='View and edit secrets') empty_object = api.schema('empty_object', {'type': 'object'}) @secrets_api.route('/') class SecretsAPI(APIResource): @api.response(200) @api.response(NotFoundError) def get(self, session=None): return secrets_from_db() @api.response(201, 'Successfully updated secrets file') @api.response(NotFoundError) @api.validate(empty_object) @api.doc(description='Note that editing secrets may not be persistent, depending on user config') def put(self, session=None): data = request.json secrets_to_db(data)
from flask import jsonify from flask_restx import inputs from flexget.api import APIResource, api from flexget.api.app import ( BadRequest, NotFoundError, base_message_schema, empty_response, success_response, ) irc_api = api.namespace('irc', description='View and manage IRC connections') irc_parser = api.parser() irc_parser.add_argument( 'name', help='Name of connection. Leave empty to apply to all connections.') class ObjectsContainer: connection_object = { 'type': 'object', 'properties': { 'alive': { 'type': 'boolean' }, 'channels': { 'type': 'array', 'items': { 'type': 'object',
return session.query(User).filter(User.name == username).first() @app.before_request def check_valid_login(): # Allow access to root, login and swagger documentation without authentication if request.path == '/' or request.path.startswith('/auth/login') or \ request.path.startswith('/auth/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization auth_api = api.namespace('auth', description='Authentication') login_api_schema = api.schema('auth.login', { 'type': 'object', 'properties': { 'username': {'type': 'string'}, 'password': {'type': 'string'} } }) login_parser = api.parser() login_parser.add_argument('remember', type=inputs.boolean, required=False, default=False, help='Remember login (sets persistent session cookies)' )
import logging from math import ceil from flask import jsonify from flask import request from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.api.app import Conflict, NotFoundError, base_message_schema, success_response, BadRequest, etag, \ pagination_headers from flexget.plugins.list import movie_list as ml from flexget.plugins.list.movie_list import MovieListBase log = logging.getLogger('movie_list') movie_list_api = api.namespace('movie_list', description='Movie List operations') class ObjectsContainer(object): input_movie_list_id_object = { 'type': 'array', 'items': { 'type': 'object', 'minProperties': 1, 'additionalProperties': True } } input_movie_entry = { 'type': 'object', 'properties': {
return session.query(User).filter(User.name == username).first() @app.before_request def check_valid_login(): # Allow access to root, login and swagger documentation without authentication if request.path == '/' or request.path.startswith('/login') or \ request.path.startswith('/logout') or request.path.startswith('/swagger'): return if not current_user.is_authenticated: return current_app.login_manager.unauthorized() # API Authentication and Authorization login_api = api.namespace('login', description='API Authentication') login_api_schema = api.schema( 'login', { 'type': 'object', 'properties': { 'username': { 'type': 'string' }, 'password': { 'type': 'string' } } }) login_parser = api.parser()
from flexget.api import api, APIResource from flexget.api.app import ( Conflict, NotFoundError, base_message_schema, success_response, BadRequest, etag, pagination_headers, ) from flexget.plugins.list import movie_list as ml from flexget.plugins.list.movie_list import MovieListBase log = logging.getLogger("movie_list") movie_list_api = api.namespace("movie_list", description="Movie List operations") class ObjectsContainer(object): input_movie_list_id_object = { "type": "array", "items": {"type": "object", "minProperties": 1, "additionalProperties": True}, } input_movie_entry = { "type": "object", "properties": { "movie_name": {"type": "string"}, "movie_year": {"type": "integer"}, "movie_identifiers": input_movie_list_id_object, },
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response schema_api = api.namespace( 'format_check', description='Test Flexget custom schema format validations') class ObjectContainer(object): format_checker_input = { 'type': 'object', 'properties': { 'quality': { 'type': 'string', 'format': 'quality' }, 'quality_requirements': { 'type': 'string', 'format': 'quality_requirements' }, 'time': { 'type': 'string', 'format': 'time' }, 'interval': { 'type': 'string', 'format': 'interval' },
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response schema_api = api.namespace( 'format_check', description='Test Flexget custom schema format validations' ) class ObjectContainer(object): format_checker_input = { 'type': 'object', 'properties': { 'quality': {'type': 'string', 'format': 'quality'}, 'quality_requirements': {'type': 'string', 'format': 'quality_requirements'}, 'time': {'type': 'string', 'format': 'time'}, 'interval': {'type': 'string', 'format': 'interval'}, 'size': {'type': 'string', 'format': 'size'}, 'percent': {'type': 'string', 'format': 'percent'}, 'regex': {'type': 'string', 'format': 'regex'}, 'file': {'type': 'string', 'format': 'file'}, 'path': {'type': 'string', 'format': 'path'}, 'url': {'type': 'string', 'format': 'url'}, 'episode_identifier': {'type': 'string', 'format': 'episode_identifier'}, 'episode_or_season_id': {'type': 'string', 'format': 'episode_or_season_id'}, }, }
from __future__ import unicode_literals, division, absolute_import import copy import logging from math import ceil from flask import jsonify, request from sqlalchemy.orm.exc import NoResultFound import flexget.plugins.list.entry_list as el from flexget.api import api, APIResource log = logging.getLogger('entry_list') entry_list_api = api.namespace('entry_list', description='Entry List operations') default_error_schema = { 'type': 'object', 'properties': { 'status': {'type': 'string'}, 'message': {'type': 'string'} } } empty_response = api.schema('empty', {'type': 'object'}) default_error_schema = api.schema('default_error_schema', default_error_schema) entry_list_base_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'name': {'type': 'string'},
from flask import jsonify, request from sqlalchemy.orm.exc import NoResultFound from flexget.plugins.list.pending_list import ( get_pending_lists, get_list_by_exact_name, PendingListList, get_list_by_id, delete_list_by_id, get_entries_by_list_id, get_entry_by_title, PendingListEntry, get_entry_by_id) from flexget.api import api, APIResource from flexget.api.app import (NotFoundError, base_message_schema, success_response, etag, pagination_headers, Conflict, BadRequest) log = logging.getLogger('pending_list') pending_list_api = api.namespace('pending_list', description='Pending List operations') class ObjectsContainer(object): pending_list_base_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'name': { 'type': 'string' }, 'added_on': { 'type': 'string' }
from __future__ import unicode_literals, division, absolute_import import datetime from math import ceil from flask import jsonify, request from flask_restplus import inputs from flexget.api import api, APIResource from flexget.plugins.api.series import NoResultFound from flexget.plugins.filter import movie_queue as mq from flexget.utils import qualities movie_queue_api = api.namespace('movie_queue', description='Movie Queue operations') default_error_schema = { 'type': 'object', 'properties': { 'status': { 'type': 'string' }, 'message': { 'type': 'string' } } } default_error_schema = api.schema('default_error_schema', default_error_schema) empty_response = api.schema('empty', {'type': 'object'})
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin import logging from flask import jsonify from sqlalchemy.orm.exc import NoResultFound from flexget.api import api, APIResource from flexget.plugins.filter.retry_failed import FailedEntry log = logging.getLogger('failed_api') retry_failed_api = api.namespace('failed', description='View and manage failed entries') empty_response = api.schema('empty', {'type': 'object'}) retry_failed_entry_object = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'title': { 'type': 'string' }, 'url': { 'type': 'string' }, 'added_at': {
from __future__ import unicode_literals, division, absolute_import from builtins import * # pylint: disable=unused-import, redefined-builtin from flask import jsonify from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import NotFoundError, BadRequest, etag from flexget.plugins.internal.api_tvdb import lookup_series, lookup_episode, search_for_series tvdb_api = api.namespace('tvdb', description='TheTVDB Shows') class ObjectsContainer(object): tvdb_series_object = { 'type': 'object', 'properties': { 'tvdb_id': {'type': 'integer'}, 'last_updated': {'type': 'string', 'format': 'date-time'}, 'expired': {'type': 'boolean'}, 'series_name': {'type': 'string'}, 'rating': {'type': 'number'}, 'status': {'type': 'string'}, 'runtime': {'type': 'integer'}, 'airs_time': {'type': 'string'}, 'airs_dayofweek': {'type': 'string'}, 'content_rating': {'type': 'string'}, 'network': {'type': 'string'}, 'overview': {'type': 'string'}, 'imdb_id': {'type': 'string'}, 'zap2it_id': {'type': 'string'},
scheduler.shutdown(wait=True) @event("manager.shutdown") def stop_scheduler(manager): if scheduler and scheduler.running: scheduler.shutdown(wait=False) @event("config.register") def register_config(): register_config_key("schedules", main_schema) register_schema("/schema/config/schedule", schedule_schema) schedule_api = api.namespace("schedules", description="Task Scheduler") api_schedule_schema = api.schema("schedule", schedule_schema) api_schedules_list_schema = api.schema("schedule", main_schema) def _schedule_by_id(schedule_id): for schedule in manager.config.get("schedules", []): if id(schedule) == schedule_id: schedule = schedule.copy() schedule["id"] = schedule_id return schedule @schedule_api.route("/") class SchedulesAPI(APIResource):
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flask.helpers import send_file from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import APIError, BadRequest from flexget.utils.cache import cached_resource from requests import RequestException cached_api = api.namespace('cached', description='Cache remote resources') cached_parser = api.parser() cached_parser.add_argument('url', required=True, help='URL to cache') cached_parser.add_argument( 'force', type=inputs.boolean, default=False, help='Force fetching remote resource' ) @cached_api.route('/') @api.doc(description='Returns a cached copy of the requested resource, matching its mime type') class CachedResource(APIResource): @api.response(200, description='Cached resource') @api.response(BadRequest) @api.response(APIError) @api.doc(parser=cached_parser) def get(self, session=None): """ Cache remote resources """ args = cached_parser.parse_args() url = args.get('url') force = args.get('force')
from flask import jsonify, request from flask_restplus import inputs from flexget.api import api, APIResource from flexget.api.app import ( base_message_schema, success_response, NotFoundError, etag, pagination_headers, BadRequest, ) from sqlalchemy.orm.exc import NoResultFound from . import db pending_api = api.namespace('pending', description='View and manage pending entries') class ObjectsContainer(object): pending_entry_object = { 'type': 'object', 'properties': { 'id': {'type': 'integer'}, 'task_name': {'type': 'string'}, 'title': {'type': 'string'}, 'url': {'type': 'string'}, 'approved': {'type': 'boolean'}, 'added': {'type': 'string', 'format': 'date-time'}, }, }
import cherrypy import yaml from flask import Response, jsonify, request from flask_restplus import inputs from pyparsing import Word, Keyword, Group, Forward, Suppress, OneOrMore, oneOf, White, restOfLine, ParseException, \ Combine from pyparsing import nums, alphanums, printables from yaml.error import YAMLError from flexget._version import __version__ from flexget.api import api, APIResource, ApiError, __version__ as __api_version__ log = logging.getLogger('api.server') server_api = api.namespace('server', description='Manage Daemon') yaml_error_response = { 'type': 'object', 'properties': { 'code': { 'type': 'integer' }, 'column': { 'type': 'integer' }, 'line': { 'type': 'integer' }, 'message': { 'type': 'string'
from flask import jsonify from flexget.api import api, APIResource from flexget.config_schema import schema_paths, resolve_ref schema_api = api.namespace('schema', description='Config and plugin schemas') _plugins_cache = None schema_api_list = api.schema( 'schema.list', { 'type': 'object', 'properties': { 'schemas': { 'type': 'array', 'items': { 'type': 'object' } } } }) @schema_api.route('/') class SchemaAllAPI(APIResource): @api.response(200, model=schema_api_list) def get(self, session=None): """ List all schema definitions """ schemas = {} for path in schema_paths: schemas[path] = resolve_ref(path) return jsonify({'schemas': schemas})
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin import copy from flask import request, jsonify from flexget.plugins.daemon.scheduler import schedule_schema, scheduler, scheduler_job_map, DEFAULT_SCHEDULES from flexget.api import api, APIResource from flexget.api.app import NotFoundError, APIError, base_message_schema, success_response, etag, Conflict schedule_api = api.namespace('schedules', description='Task Scheduler') class ObjectsContainer(object): # SwaggerUI does not yet support anyOf or oneOf schedule_object = copy.deepcopy(schedule_schema) schedule_object['properties']['id'] = {'type': 'integer'} schedule_object['maxProperties'] += 1 schedules_list = {'type': 'array', 'items': schedule_object} base_schedule_schema = api.schema('schedules.base', schedule_schema) api_schedule_schema = api.schema('schedules.schedule', ObjectsContainer.schedule_object) api_schedules_list_schema = api.schema('schedules.list', ObjectsContainer.schedules_list) def _schedule_by_id(schedule_id, schedules): for idx, schedule in enumerate(schedules): if schedule and id(schedule) == schedule_id:
from __future__ import unicode_literals, division, absolute_import from builtins import * # noqa pylint: disable=unused-import, redefined-builtin from flask import jsonify, request from flexget.db_schema import reset_schema, plugin_schemas from flexget.api import api, APIResource from flexget.api.app import base_message_schema, success_response, BadRequest db_api = api.namespace('database', description='Manage Flexget DB') class ObjectsContainer(object): plugin_list = {'type': 'array', 'items': {'type': 'string'}} database_input_object = { 'type': 'object', 'properties': { 'operation': {'type': 'string', 'enum': ['cleanup', 'vacuum', 'plugin_reset']}, 'plugin_name': {'type': 'string'}, }, 'required': ['operation'], 'additionalProperties': False, } plugins_schema = api.schema_model('plugins_list', ObjectsContainer.plugin_list) input_schema = api.schema_model('db_schema', ObjectsContainer.database_input_object) @db_api.route('/')
from datetime import datetime from Queue import Queue, Empty from flask import request, jsonify, Response from flexget.options import get_parser from flexget.api import api, APIResource from flexget.utils import json from json import JSONEncoder from flexget.event import event from flexget.utils.lazy_dict import LazyLookup execution_api = api.namespace('execution', description='Execute tasks') def _task_info_dict(task): return { 'id': int(task.id), 'name': task.name, 'current_phase': task.current_phase, 'current_plugin': task.current_plugin, } task_info_schema = { 'type': 'object', 'properties': { 'id': { 'type': 'integer' }, 'name': {