Beispiel #1
0
def upload():
    """Upload file to S3."""

    if "file" not in request.files:
        return jsonify(success=False, message="File key is missing."), 400

    file_data = request.files["file"]
    filename = file_data.filename
    mime_type = file_data.mimetype
    _, extension = splitext(filename)

    if extension not in current_app.config["EDITOR_UPLOAD_ALLOWED_EXTENSIONS"]:
        return (
            jsonify(success=False,
                    message=f"File extension '{extension}' is not supported."),
            400,
        )

    key = hash_data(file_data.read())
    bucket = current_app.config.get("S3_EDITOR_BUCKET")

    file_data.seek(0)
    current_s3_instance.upload_file(file_data, key, filename, mime_type,
                                    current_app.config["S3_FILE_ACL"], bucket)
    file_url = current_s3_instance.get_s3_url(key, bucket)
    return jsonify({"path": file_url}), 200
Beispiel #2
0
def test_upload_file(inspire_app, s3):
    create_s3_bucket(KEY)
    filename = "file.txt"
    mimetype = "text/*"
    acl = "public-read"
    expected_content = "This is a demo file\n"
    record_fixture_path = pkg_resources.resource_filename(
        __name__, os.path.join("fixtures", "file.txt")
    )
    with open(record_fixture_path, "rb") as data:
        current_s3_instance.upload_file(data, KEY, filename, mimetype, acl)
    result = current_s3_instance.client.head_object(
        Bucket=current_s3_instance.get_bucket_for_file_key(KEY), Key=KEY
    )
    assert result["ContentDisposition"] == f'inline; filename="{filename}"'
    assert result["ContentType"] == mimetype
    content = (
        current_s3_instance.resource.Object(
            current_s3_instance.get_bucket_for_file_key(KEY), KEY
        )
        .get()["Body"]
        .read()
        .decode("utf-8")
    )
    assert content == expected_content
Beispiel #3
0
def write_sitemap_page_content(page, page_content):
    bucket = current_app.config["S3_SITEMAP_BUCKET"]
    file_data = page_content.encode("utf8")
    file_data = BytesIO(file_data)
    filename = get_sitemap_page_filename(page)
    current_s3_instance.upload_file(
        file_data,
        filename,
        filename,
        SITEMAP_MIME_TYPE,
        current_app.config["S3_FILE_ACL"],
        bucket,
    )
Beispiel #4
0
def generate_bibliography():
    content_length = request.content_length
    if content_length is not None and content_length > 10 * 1024 * 1024:
        raise FileTooBigError

    requested_format = request.args.get("format")
    bytes_file = request.files["file"]

    if not allowed_file(bytes_file.filename):
        raise FileFormatNotSupportedError

    text_file = TextIOWrapper(bytes_file, errors="ignore")

    reference_names = get_references(text_file)
    references, errors = find_references(reference_names, requested_format)

    if not references:
        raise NoReferencesFoundError

    file_data = "\n\n".join(references).encode("utf-8")
    key = hash_data(file_data)
    file_data = BytesIO(file_data)
    filename = get_filename(bytes_file.filename, requested_format)
    mime_type = get_mimetype(requested_format)
    bucket = current_app.config.get("S3_BIBLIOGRAPHY_GENERATOR_BUCKET")

    current_s3_instance.upload_file(file_data, key, filename, mime_type,
                                    current_app.config["S3_FILE_ACL"], bucket)
    download_url = current_s3_instance.get_s3_url(key, bucket)

    formatted_errors = []
    for error in errors:
        if error["type"] == "ambiguous":
            formatted_errors.append({
                "message":
                f"Ambiguous reference to {error['ref']} on line {error['line']}"
            })
        else:
            formatted_errors.append({
                "message":
                f"Reference to {error['ref']} not found on line {error['line']}"
            })

    response = {
        "data": {
            "download_url": download_url
        },
        "errors": formatted_errors
    }

    return jsonify(response)
Beispiel #5
0
    def add_file(
        app_context,
        control_number,
        uuid,
        url,
        original_url=None,
        key=None,
        filename=None,
        *args,
        **kwargs,
    ):
        """Adds files to s3.

        Args:
            app_context: Original app context should be passed here if running in separate thread
        """
        with app_context.app.app_context():
            if current_s3_instance.is_s3_url(
                    url) and not current_app.config.get(
                        "UPDATE_S3_FILES_METADATA", False):
                result = {}
                if key not in url:
                    filename = filename or key
                    key = url.split("/")[-1]
                    result.update({"key": key, "filename": filename})
                LOGGER.info(
                    "File already on S3 - Skipping",
                    url=url,
                    key=key,
                    recid=control_number,
                    uuid=uuid,
                    thread=threading.get_ident(),
                )
                return result
            file_data = download_file_from_url(url)
            new_key = hash_data(file_data)
            mimetype = magic.from_buffer(file_data, mime=True)
            file_data = BytesIO(file_data)
            filename = filename or key
            acl = current_app.config["S3_FILE_ACL"]
            if current_s3_instance.file_exists(new_key):
                LOGGER.info(
                    "Replacing file metadata",
                    key=new_key,
                    recid=control_number,
                    uuid=uuid,
                    thread=threading.get_ident(),
                )
                current_s3_instance.replace_file_metadata(
                    new_key, filename, mimetype, acl)
            else:
                LOGGER.info(
                    "Uploading file to s3",
                    key=new_key,
                    recid=control_number,
                    uuid=uuid,
                    thread=threading.get_ident(),
                )
                current_s3_instance.upload_file(file_data, new_key, filename,
                                                mimetype, acl)
            result = {
                "key": new_key,
                "filename": filename,
                "url": current_s3_instance.get_file_url(new_key),
            }
            if (url.startswith("http")
                    and not current_s3_instance.is_s3_url(url)
                    and not original_url):
                result["original_url"] = url
            return result
    def add_file(
        app_context,
        url,
        original_url=None,
        key=None,
        filename=None,
        *args,
        **kwargs,
    ):
        """Adds files to s3.

        Args:
            app_context: Original app context should be passed here if running in separate thread
        """
        with app_context.app.app_context():
            is_s3_or_public_url = current_s3_instance.is_s3_url_with_bucket_prefix(
                url) or current_s3_instance.is_public_url(url)
            if is_s3_or_public_url and not current_app.config.get(
                    "UPDATE_S3_FILES_METADATA", False):
                result = {}
                if key not in url:
                    filename = filename or key
                    key = url.split("/")[-1]
                    result.update({"key": key, "filename": filename})
                if current_s3_instance.is_s3_url(url):
                    url = current_s3_instance.get_public_url(key)
                    result.update({"url": url})

                LOGGER.info(
                    "File already on S3 - Skipping",
                    url=url,
                    key=key,
                    thread=threading.get_ident(),
                )
                return result
            file_data = download_file_from_url(url)
            new_key = hash_data(file_data)
            mimetype = magic.from_buffer(file_data, mime=True)
            file_data = BytesIO(file_data)
            filename = filename or key
            if not filename:
                filename = new_key
            if mimetype in current_app.config.get(
                    "FILES_RESTRICTED_MIMETYPES"):
                LOGGER.error(
                    "Unsupported file type - Aborting",
                    key=key,
                    mimetype=mimetype,
                    thread=threading.get_ident(),
                )
                raise UnsupportedFileError(mimetype)
            acl = current_app.config["S3_FILE_ACL"]
            if current_s3_instance.file_exists(new_key):
                LOGGER.info(
                    "Replacing file metadata",
                    key=new_key,
                    thread=threading.get_ident(),
                )
                current_s3_instance.replace_file_metadata(
                    new_key, filename, mimetype, acl)
            else:
                LOGGER.info(
                    "Uploading file to s3",
                    key=new_key,
                    thread=threading.get_ident(),
                )
                current_s3_instance.upload_file(file_data, new_key, filename,
                                                mimetype, acl)
            result = {
                "key": new_key,
                "filename": filename,
                "url": current_s3_instance.get_public_url(new_key),
            }
            if (url.startswith("http")
                    and not current_s3_instance.is_s3_url(url)
                    and not current_s3_instance.is_public_url(url)
                    and not original_url):
                result["original_url"] = url
            return result