Example #1
0
def new_folder():
    path = utils.get_url_param(request.args, "path",
                               convert_path=True)  # Folder's parent path
    name = utils.get_url_param(request.args, "name")  # new folder's name

    parent_dir = CommonQuery.query_dir_by_relative_path(path)
    if not parent_dir:
        return utils.make_status_resp_ex(
            STATUS_ENUM.RESOURCE_MISSING)  # Parent folder isn't valid

    name = secure_filename(
        name) if app.config["SECURE_UPLOAD_FILENAME"] else name

    CommonQuery.insert_new_dir_record(parent_dir, name, commit=False)

    parent_dir.content_dir = parent_dir.content_dir + f"\0{name}" if parent_dir.content_dir else f"{name}"

    try:
        os.mkdir(os.path.join(parent_dir.abs_path, name))
        db.session.commit()
    except (exc.IntegrityError, FileExistsError):
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_ALREADY_EXISTS)
    except PermissionError:  # This program does not have privilege to create resource at the target path
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_ACCESS_DENIED)
    except OSError:  # OS preventing us from creating a folder with the provided name
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_ILLEGAL_PARAM)

    return utils.make_status_resp_ex(STATUS_ENUM.SUCCESS)
Example #2
0
def delete_dir_from_db(directory: Directory, commit=False):
    parent = CommonQuery.query_dir_by_relative_path(directory.parent_path)
    content_dir_list = parent.content_dir.split("\0")
    content_dir_list.remove(directory.name)
    parent.content_dir = "\0".join(content_dir_list)

    db.session.delete(directory)

    if commit:
        db.session.commit()
Example #3
0
def delete_file_from_db(file: File, commit=False):
    parent = CommonQuery.query_dir_by_relative_path(file.parent_path)
    content_file_list = parent.content_file.split("\0")
    content_file_list.remove(file.name)
    parent.content_file = "\0".join(content_file_list)

    db.session.delete(file)

    if commit:
        db.session.commit()
Example #4
0
def download_archive():
    path = get_url_param(request.args, "path", convert_path=True)

    directory = CommonQuery.query_dir_by_relative_path(path)

    if directory and directory.archive_path:
        return send_file(directory.archive_path,
                         attachment_filename=directory.archive_name,
                         as_attachment=True)
    else:
        return render_template("error/404.html")
Example #5
0
def delete_file_or_folder():
    content = request.json

    targets = []

    for path in content["folder"]:
        if os.name == "nt": path = path.replace("/", "\\")
        folder = CommonQuery.query_dir_by_relative_path(path)
        if not folder:
            return utils.make_status_resp(
                103, f"Folder with path: {path} does not exist",
                STATUS_TO_HTTP_CODE[103])
        targets.append(folder)

    for path in content["file"]:
        if os.name == "nt": path = path.replace("/", "\\")
        file = CommonQuery.query_file_by_relative_path(path)
        if not file:
            return utils.make_status_resp(
                103, f"File with path: {path} does not exist",
                STATUS_TO_HTTP_CODE[103])
        targets.append(file)

    failed_to_delete = [
    ]  # A list to store list of relative path if os.removed failed to remove them
    failed_to_delete_reason = None

    for target in targets:
        if app.config[
                "DELETE_MODE"] == 1:  # Remove the target both from the file system and the database
            try:
                api_utils.delete_file_or_directory_from_filesystem(target)
                api_utils.delete_file_or_directory_from_db(target)
            except PermissionError:
                failed_to_delete.append(target.rel_path)
                failed_to_delete_reason = 101
                continue

        elif app.config[
                "DELETE_MODE"] == 2:  # Only Remove the target from the database not the filesystem
            api_utils.delete_file_or_directory_from_db(target)

    db.session.commit()

    if failed_to_delete:
        return utils.make_status_resp(
            0,
            f"Errors [{STATUS_TO_MESSAGE[failed_to_delete_reason]}] has prevented some file from being deleted. A total of {len(failed_to_delete)} items out of {len(targets)} failed to be deleted",
            STATUS_TO_HTTP_CODE[0])

    return utils.make_status_resp_ex(STATUS_ENUM.SUCCESS)
Example #6
0
def list_directory():
    path = utils.get_url_param(request.args, "path", convert_path=True)
    target_type = utils.get_url_param(request.args, "type")

    directory = CommonQuery.query_dir_by_relative_path(path)

    if not directory:
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_MISSING)

    data = api_utils.db_list_directory_bootstrap_table(
        directory
    ) if target_type == "table" else api_utils.db_list_directory_basic(
        directory)
    return utils.make_json_resp_with_status(data, 200)
Example #7
0
def upload_file():
    path = utils.get_url_param(request.args, "path", convert_path=True)

    files = request.files.getlist("File")

    parent_dir = CommonQuery.query_dir_by_relative_path(path)
    if not parent_dir:
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_MISSING)

    try:
        for file in files:
            file_name = secure_filename(
                file.filename
            ) if app.config["SECURE_UPLOAD_FILENAME"] else file.filename
            file_path = os.path.join(
                parent_dir.abs_path,
                file_name)  # Construct the new file's absolute path
            file.save(
                file_path
            )  # THe file have to be save before the database write cuz it needs to detect it's mime type
            # print("Saving file to: {}".format(file_path))

            # Add the file into the parent directory's record
            parent_dir.content_file = parent_dir.content_file + f"\0{file_name}" if parent_dir.content_file else f"{file_name}"

            CommonQuery.insert_new_file_record(parent_dir,
                                               file_name,
                                               commit=False)
    except (PermissionError):
        pass
    except (OSError):
        pass

    db.session.commit(
    )  # Update the parent folder's database entry to match the newly added file names

    return utils.make_status_resp_ex(STATUS_ENUM.SUCCESS)
Example #8
0
def db_list_directory_basic(record: Directory) -> dict:
    content = {"dirs": [], "files": []}
    if record.content_dir:
        for folder in record.content_dir.split("\0"):
            dir_rel_path = os.path.join(record.rel_path, folder)
            dir_info = CommonQuery.query_dir_by_relative_path(dir_rel_path)

            content["dirs"].append({
                "name": dir_info.name,
                "path": dir_info.rel_path.replace("\\", "/"),
                "size": dir_info.size,
                "last_mod": dir_info.last_mod,
                "dir_count": dir_info.dir_count,
                "file_count": dir_info.file_count
            })

    if record.content_file:
        for file in record.content_file.split("\0"):
            file_rel_path = os.path.join(record.rel_path, file)
            file_info = CommonQuery.query_file_by_relative_path(file_rel_path)

            content["files"].append({
                "name":
                file_info.name,
                "path":
                file_info.rel_path.replace("\\", "/"),
                "size":
                file_info.size,
                "last_mod":
                file_info.last_mod,
                "mimetype":
                file_info.mimetype
            })

    parent_path = record.rel_path.replace("\\", "/")
    return {parent_path: content}
Example #9
0
def download_folder():
    path = utils.get_url_param(request.args, "path", convert_path=True)

    directory = CommonQuery.query_dir_by_relative_path(path)
    if not directory:
        return utils.make_status_resp_ex(STATUS_ENUM.RESOURCE_MISSING)

    if not directory.archive_id:
        api_utils.generate_and_register_archive(
            directory, commit=True)  # Might take a long time
    elif directory.archive_id:  # If there is an existing archive
        return utils.make_json_resp_with_status(
            {
                "status":
                0,
                "details":
                f"There is an existing archive. view: /archive?path=<FolderPath> to access"
            }, 200)

    return utils.make_json_resp_with_status(
        {
            "status": 0,
            "details": "success, archive has been created"
        }, 201)  # 201 -> Created