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)
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)
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()
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)
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)
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
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)