File upload Queries

Please help/suggest to resolve below file upload cases in Frappe…

File Upload cases::

  • Upload file on specific path/folder/different server drive , we do not want to upload in default folder

  • We want to upload files to a remote file servers

  • Create Dynamic folder path (if not exist) and uploads the files in that path, if path already exists the upload the file in that folder path

  • Rename the file before uploading to remove the clash of file names in same folder

@NCP hey nihantra is there any insight you can give on this

Check this … Strange, exactly the same question :roll_eyes:

1 Like
class Student(Document):
     def custom_file_uploader(self):

        student_name = self.student_name
        state = self.state
        file_url = frappe.doc.get('attach')


        file_content = get_file(file_url)
        file_name_old = frappe.local.uploaded_filename
        file_name = f"{student_name}-{file_name_old}"

        # Create the folder based on the state field value
        folder_path = f"/home/frappe3/frappe-bench/apps/frappe/frappe/popup/doctype/student/{state}"
        os.makedirs(folder_path, exist_ok=True)

        file_path = os.path.join(folder_path, file_name)

        with open(file_path, "wb") as file:
            file.write(file_content)

      
frappe.ui.form.on('Student', {
  browse: function (frm) {
    new frappe.ui.FileUploader({
      method: 'frappe.popup.doctype.student.student.capture',
      
      make_attachments_public: "False",
      dialog_title: "Upload Files",
      disable_file_browser: "False",
      frm: frm,
      restrictions: {
          allowed_file_types: [".png",".pdf"]
      },
      on_success (file) {
          frappe.show_alert({
              message:__('File uploaded.'),
              indicator:'green'
          }, 5);   
      }
    
    });
  }
});

Is there a way to attach it to the Student Doctype or any attach field in the student doctype

@avc if you could help out. thank you

Hooks Can anyone explain the implementation of this @avc @NCP. I would be grateful. Thank you

Upload files to a remote file server

  • you can use a custom integration or library to transfer the file to the remote server after saving it locally. One popular library for transferring files to remote servers is paramiko .
import paramiko
from frappe.utils.file_manager import save_file

# default Frappe folder
file_doc = save_file(filedata, filename, dt, dn)

hostname = 'remote_server_ip'
username = 'remote_username'
password = 'remote_password'
remote_folder = '/path/to/remote/folder'

# Connect to the remote server using SSH
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)

# Transfer the file to the remote server
sftp = ssh.open_sftp()
local_path = file_doc.file_url
remote_path = f"{remote_folder}/{filename}"
sftp.put(local_path, remote_path)

sftp.close()
ssh.close()

IF YOU HAVE NAS (Network Attached Storage) for Storage like Synology then

  • you can use various methods such as FTP, SFTP, or SCP. We can transfer files to a using the paramiko library and SFTP:
# Define the Synology NAS details
hostname = 'nas_ip_address'
port = 22  # Default SFTP port for Synology NAS
username = 'nas_username'
password = 'nas_password'
remote_folder = '/path/to/remote/folder'

By Help of this you can achieve some logic to any kind of doctype

  • Client Script
frappe.ui.form.on("YourDoctype", {
    upload_file_button: function(frm) {
        var file_input = document.createElement("input");
        file_input.type = "file";
        file_input.accept = "image/*";  // Specify the accepted file types here

        file_input.onchange = function() {
            var file = file_input.files[0];
            var reader = new FileReader();

            reader.onload = function(e) {
                var filedata = e.target.result;

                frappe.call({
                    method: "upload_file_to_remote_server",
                    args: {
                        filedata: filedata,
                        filename: file.name
                    },
                    callback: function(response) {
                        if (response.message) {

                            frappe.msgprint("File transferred successfully.");
                        } else {

                            frappe.msgprint("File transfer failed.");
                        }
                    }
                });
            };

            reader.readAsDataURL(file);
        };

        file_input.click();
    }
});

*Server Script

import paramiko
@frappe.whitelist()
def upload_file_to_remote_server(filedata, filename):
    remote_hostname = 'remote_server_ip'
    remote_username = 'remote_username'
    remote_password = 'remote_password'
    remote_folder = '/path/to/remote/folder'
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(remote_hostname, username=remote_username, password=remote_password)
    sftp = ssh.open_sftp()
    remote_path = f"{remote_folder}/{filename}"
    sftp.putfo(filedata, remote_path)
    sftp.close()
    ssh.close()
    return True

Hope you understand how do that…!
Thanks…!

2 Likes