Skip to content

Amending Files #46

@Citysystems-smart

Description

@Citysystems-smart

During amending a doc, the document exists on original doc being copied using copy_attachments_from_amended_from from frappe.
during that this function being run

def dfp_external_storage_upload_file(self, local_file=None):
		"""
		Critical fields: "dfp_external_storage_s3_key", "dfp_external_storage" and "file_url"
		:param local_file: if given, file path for reading the content. If not given, the content field of this File is used
		"""
  
		if self.dfp_external_storage_ignored_doctypes():
			self.dfp_external_storage = ""
			return False
		if not self.dfp_external_storage_doc or not self.dfp_external_storage_doc.enabled:
			return False
		if self.is_folder:
			return False
		if self.dfp_external_storage_s3_key:
			# File already on S3
			return False
		if self.file_url and self.file_url.startswith(URL_PREFIXES):
			# frappe.throw(_("Not implemented save http(s)://file(s) to local."))
			raise NotImplementedError("http(s)://file(s) not ready to be saved to local or external storage(s).")

		original_file_url = self.file_url

		# Define S3 key
		# key = f"{frappe.local.site}/{self.file_name}" # << Before 2024.03.03
		base, extension = os.path.splitext(self.file_name)
		key = f"{frappe.local.site}/{base}-{self.name}{extension}"

		is_public = "/public" if not self.is_private else ""
		if not local_file:
			local_file = "./" + frappe.local.site + is_public + self.file_url

		try:
			if not os.path.exists(local_file):
				frappe.throw(_("Local file not found"))
			with open(local_file, "rb") as f:
				self.dfp_external_storage_client.put_object(
					bucket_name=self.dfp_external_storage_doc.bucket_name,
					object_name=key,
					data=f,
					length=os.path.getsize(local_file),
					# Meta removed because same s3 file can be used within different File docs
					# metadata={"frappe_file_id": self.name}
				)

			self.dfp_external_storage_s3_key = key
			self.dfp_external_storage = self.dfp_external_storage_doc.name
			self.file_url = f"/{DFP_EXTERNAL_STORAGE_URL_SEGMENT_FOR_FILE_LOAD}/{self.name}/{self.file_name}"
			os.remove(local_file)
		except Exception as e:
			error_msg = _("Error saving file in remote folder: {}").format(str(e))
			frappe.log_error(f"{error_msg}: {self.file_name}", message=e)
			# If file is new we upload to local filesystem
			if not self.get_doc_before_save():
				error_extra = _("File saved in local filesystem.")
				frappe.log_error(f"{error_msg} {error_extra}: {self.file_name}")
				self.dfp_external_storage_s3_key = ""
				self.dfp_external_storage = ""
				self.file_url = original_file_url
			# If modifing existent file throw error
			else:
				frappe.throw(error_msg)


during checking the file already being added to S3 so this function failed and fall back to frappe. because it failed and frappe check it is start with /file it being change to public automatically

i add

`        if self.file_url and self.file_url.startswith(
            f"/{DFP_EXTERNAL_STORAGE_URL_SEGMENT_FOR_FILE_LOAD}/"
        ):
            renderer = DFPExternalStorageFileRenderer(path=self.file_url)
            if renderer.can_render():
                s3_data = frappe.get_value(
                    "File", renderer.file_id_get(), fieldname="*")
                if s3_data:
                    self.dfp_external_storage = s3_data["dfp_external_storage"]
                    self.dfp_external_storage_s3_key = s3_data[
                        "dfp_external_storage_s3_key"
                    ]
                    self.content_hash = s3_data["content_hash"]
                    self.file_size = s3_data["file_size"]
                    self.is_private = s3_data["is_private"]
                    self.file_url = self._remote_file_local_path_get()
                    self.flags.ignore_duplicate_entry_error = True
                    return False  # already on S3, no upload needed

`

on the beining of dfp_external_storage_upload_file and it seems works to check during amend or duplicating doc
hence: the solution being made from AI

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions