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_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 #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 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 #5
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 #6
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
Example #7
0
def init_db():
    # TODO: Determin if database has been initalized or not
    # if not, we have to call db.create_all()
    with app.app_context():
        if not is_database_initalized():
            db.create_all()
        app.logger.info("Initializing database records")

        extra_paths, missing_paths = get_missing_paths()
        if not extra_paths and not missing_paths:
            app.logger.info("Shared path did not change from previous run")

        for path in extra_paths:
            remove_shared_path_from_db(path)
        for path in missing_paths:
            add_shared_path_to_db(path)

        write_info("db_info.json")

        db_last_mod = CommonQuery.query_last_modified_item(push_context=False)
        for path in app.config["SHARED_DIRECTORY"]:
            indexed_files = index_file(path)
            scan_and_update_deleted_files(path, db_last_mod, indexed_files)
            scan_and_update_new_files(path, db_last_mod, indexed_files)