Example #1
0
def upload_images_route():
    """
    Upload images

    Request params:
    * Files uploaded as "multipart/form-data"

    Field names don't matter. Multiple files are supported
    """
    user = request.get('REMOTE_USER')

    files = [
        item.file for _, item in request.POST.items()
        if isinstance(item, FileUpload)
    ]
    try:
        assert files, "Files were not provided"
        if len(list(get_user_images(user))) + len(files) > max_images_per_uer:
            raise MaxImageLimitError('You cannot upload more than %s images' %
                                     max_images_per_uer)
        urls = upload_images(user, files)
        return {'data': urls}
    except (AssertionError, MaxImageLimitError) as e:
        return ErrorResponse(e, 400)
    except FileTooLargeError as e:
        return ErrorResponse(e, 413)
Example #2
0
def get_extensions_route():
    """
    Returns all extensions

    Query params:
    * api_version: string. Version of Ulauncher Extension API. Returns all extensions by default

    """
    result = []

    # filter by required API version
    api_version = request.GET.get('api_version')
    try:
        sort_by = request.GET.get('sort_by') or allowed_sort_by[0]
        sort_order = request.GET.get('sort_order') or allowed_sort_order[0]
        assert sort_by in allowed_sort_by, 'allowed sorty_by: ' + ', '.join(
            allowed_sort_by)
        assert sort_order in allowed_sort_order, 'allowed sort_order: ' + ', '.join(
            map(str, allowed_sort_order))
    except AssertionError as e:
        return ErrorResponse(e, 400)

    for ext in get_extensions(sort_by=sort_by, sort_order=int(sort_order)):
        if not api_version:
            result.append(ext)
        for req_version in ext.get('SupportedVersions', []):
            if satisfies(api_version, req_version):
                result.append(ext)

    return {'data': result}
Example #3
0
def create_extension_route():
    """
    Create extension

    Request params:
    * GithubUrl: (string)
    * Name: (string) extension display name
    * Description: (string)
    * DeveloperName: (string)
    * Images: (list) list of image URLs

    Response:
    * Extension object
    """
    user = request.get('REMOTE_USER')
    data = request.json

    try:
        assert data.get('Name'), 'Name cannot be empty'
        assert data.get('Description'), 'Description cannot be empty'
        assert data.get('DeveloperName'), 'DeveloperName cannot be empty'
        assert data.get('GithubUrl'), 'GithubUrl cannot be empty'
        assert isinstance(data.get('Images'),
                          list), 'Images must be a list of URLs'
        # pylint: disable=len-as-condition
        assert 0 < len(
            data['Images']
        ) < 6, 'You must upload at least 1 (max 5) screenshot of your extension'

        project_path = get_project_path(data['GithubUrl'])
        info = get_repo_info(project_path)
        try:
            versions = get_json(project_path, 'master', 'versions')
            versions_only = [v['required_api_version'] for v in versions]
            commit_or_branch = get_latest_version_commit(versions)
        except JsonFileNotFoundError:
            commit_or_branch = 'master'
            versions_only = ['^1.0.0']

        manifest = get_json(project_path, commit_or_branch, 'manifest')
        validate_manifest(manifest)

        for image_url in data['Images']:
            validate_image_url(image_url)

        data = put_extension(User=user,
                             GithubUrl=data['GithubUrl'],
                             ProjectPath=project_path,
                             Name=data['Name'],
                             Description=data['Description'],
                             DeveloperName=data['DeveloperName'],
                             Images=data['Images'],
                             SupportedVersions=versions_only,
                             GithubStars=info['stargazers_count'],
                             Published=True)
        return {'data': data}
    except (AssertionError, ImageUrlValidationError, InvalidGithubUrlError,
            HTTPError, ProjectValidationError,
            ExtensionAlreadyExistsError) as e:
        return ErrorResponse(e, 400)
Example #4
0
def update_extension_route(id):
    """
    Update extension

    Request params:
    * Name: (string) extension display name
    * Description: (string)
    * DeveloperName: (string)
    * Images: (list) list of image URLs

    Response:
    * Extension object
    """
    user = request.get('REMOTE_USER')
    data = request.json

    try:
        ext = _verify_ext_auth(id)

        assert data.get('Name'), 'Name cannot be empty'
        assert data.get('Description'), 'Description cannot be empty'
        assert data.get('DeveloperName'), 'DeveloperName cannot be empty'
        assert isinstance(data.get('Images'),
                          list), 'Images must be a list of URLs'
        # pylint: disable=len-as-condition
        assert 0 < len(
            data['Images']
        ) < 6, 'You must upload at least 1 (max 5) screenshot of your extension'

        for image_url in data['Images']:
            validate_image_url(image_url)

        to_delete = set(ext['Images']) - set(data['Images'])
        delete_images(to_delete, user)

        data = update_extension(id,
                                Name=data['Name'],
                                Description=data['Description'],
                                DeveloperName=data['DeveloperName'],
                                Images=data['Images'])
        return {'data': data}
    except ExtensionNotFoundError as e:
        return ErrorResponse(e, 404)
    except (AssertionError, ImageUrlValidationError) as e:
        return ErrorResponse(e, 400)
    except AuthError as e:
        return ErrorResponse(e, 401)
Example #5
0
def get_extension_route(id):
    """
    Returns extension by ID
    """
    try:
        return {'data': get_extension(id)}
    except ExtensionNotFoundError as e:
        return ErrorResponse(e, 404)
Example #6
0
def validate_project():
    """
    Checks that versions.json file is valid

    Query params:
    * url: string. Example https://github.com/user/project

    Response:
    * {Name: (str), Description: (str), DeveloperName: (str)}
    """

    try:
        url = request.GET.get('url')
        assert url, 'query argument "url" cannot be empty'
        project_path = get_project_path(url)
        get_repo_info(project_path)
        try:
            versions = get_json(project_path, 'master', 'versions')
            commit_or_branch = get_latest_version_commit(versions)
        except JsonFileNotFoundError:
            commit_or_branch = 'master'
        except json.JSONDecodeError as e:
            return ErrorResponse(
                ProjectValidationError(f'Error in versions.json: {str(e)}'),
                400)

        manifest = get_json(project_path, commit_or_branch, 'manifest')
        validate_manifest(manifest)

        return {
            'data': {
                'GithubUrl': url,
                'Name': manifest['name'],
                'Description': manifest['description'],
                'DeveloperName': manifest['developer_name'],
            }
        }
    except json.JSONDecodeError as e:
        return ErrorResponse(
            ProjectValidationError(f'Error in manifest.json: {str(e)}'), 400)
    except (InvalidGithubUrlError, HTTPError, ProjectValidationError,
            AssertionError) as e:
        return ErrorResponse(e, 400)
Example #7
0
def delete_extension_route(id):
    """
    Deletes extension by ID
    """
    user = request.get('REMOTE_USER')
    try:
        ext = _verify_ext_auth(id)
        delete_images(ext['Images'], user)
        delete_extension(id, user=user)
        response.status = 204
    except (ExtensionDoesntBelongToUserError, AuthError) as e:
        return ErrorResponse(e, 401)
Example #8
0
    def wrapper(*args, **kwargs):
        if hasattr(callback,
                   'auth_required') and not request.get('REMOTE_USER'):
            try:
                decoded = parse_token(request.get_header('Authorization'))
                assert decoded['sub']
            except AuthError as e:
                return ErrorResponse(e, 401)

            request['REMOTE_USER'] = decoded['sub']

        return callback(*args, **kwargs)
Example #9
0
def get_ulauncher_release(version):
    """
    Fetches Ulauncher release from Github by given git tag (version)

    Note: This is necessary because Github API limits number of unauthenticated requests and it often blocks
    IPs that Travis CI uses, so Ulauncher releases could fail
    """
    headers = {'User-Agent': 'curl/7.47.0'}
    resp = http.request(
        'GET',
        'https://api.github.com/repos/ulauncher/ulauncher/releases',
        headers=headers)
    if resp.status != 200:
        return ErrorResponse(
            Exception('Could not get releases from Github. %s' % resp.data),
            400)
    releases = json.loads(resp.data)
    try:
        return next((r for r in releases if r['tag_name'] == version))
    except StopIteration:
        return ErrorResponse(
            Exception('Release version %s not found' % version), 404)