Getting Started

Managing Files

Updated: December 2, 2024

Learn how to upload files on your Nuxeo server and attach them to a document.

Create a Document from an Existing File

Goal

Upload a file to your Nuxeo Platform instance, create a contract and attach the file to the contract.

Prerequisites

Procedure

  1. Download the file AwesomeTech-Contract.docx. You will upload it in the next few steps.
  2. Create a file called uploadContract.js with the following content. Be sure to replace the filePath variable with the path to the contract you want to upload.

    // We need to require path and fs to browse the filesystem
    let Nuxeo = require('nuxeo');
    let path = require('path');
    let fs = require('fs');
    let nuxeo = new Nuxeo({
      auth: {
        method: 'basic',
        username: 'sconnor',
        password: 'sconnor'
      }
    });
    
    // Full path to the file that should be uploaded
    // ** Be sure to modify the path **
    let filePath = '/path/to/file/filename.something';
    
    // Path where the document should be created in Nuxeo Platform
    let whereToCreate = '/default-domain/workspaces/North America/awesome-tech';
    
    fs.stat(filePath, (err, stats) => {
      if (err) {
        console.log(`File cannot be found.\nPlease check the filePath variable (currently set to ${filePath}).`);
        return;
      }
      if (!stats.isFile()) {
        console.log(`${filePath} is not a file.\nPlease check the filePath variable.`);
        return;
      }
    
      // We create a blob from the filePath passed as variable
      let blob = new Nuxeo.Blob({
        'content': fs.createReadStream(filePath),
        'name': path.basename(filePath),
        'size': stats.size
      });
      let fileName = path.basename(filePath);
    
      // Then upload the file
      nuxeo.batchUpload()
        .upload(blob)
        .then(uploadedFile => {
          console.log('File is uploaded, we will now create a document to attach it.');
    
          // We create a contract and attach the file to it
          // We could also attach the file to an existing contract
          let contractToCreate = {
            'entity-type': 'document',
            'type': 'BCContract',
            'name': 'awesome-contract',
            'properties': {
              'dc:title': fileName,
              'file:content': uploadedFile.blob,
              'bcsalescommon:amount': '15000'
            }
          };
    
          return nuxeo.repository().create(whereToCreate, contractToCreate, { schemas: ['*'] });
        })
        .then(contract => {
          console.log('Contract has been created as follows:');
          console.log(contract);
          console.log(`Blob can be downloaded here: ${contract.get('file:content').data}.\nNote that a file security policy restricts downloads to Administrators and members of the managers group.\nYou can log in as sconnor / sconnor to download it.`);
        })
        .catch(error => {
           console.log(error);
         });
    });
    
  3. Save and run:

    $ node uploadContract.js
    

Note: You can download the file if you log in as an Administrator or a member of the managers group (e.g. by using sconnor / sconnor), otherwise download is forbidden.

 

Attaching Files to an Existing Document

Goal

The contract for Skynet AI maintenance you just created should contain other files that have been signed: a non-disclosure agreement, rates and specific conditions. Attach them to the contract on top of the existing file.

Prerequisites

  • Section "Create a Document from an Existing File" above.

Procedure

  1. Download the file contract-attachments.zip and unzip it. You will attach the files it contains to the contract in the next few steps.
  2. Create a file called attachFilesToContract.js with the following content. Be sure to replace the filePath variable with the path to the unzipped attachment folder.

    // We need to require path and fs to browse the filesystem
    let Nuxeo = require('nuxeo');
    let path = require('path');
    let fs = require('fs');
    let nuxeo = new Nuxeo({
      auth: {
        method: 'basic',
        username: 'sconnor',
        password: 'sconnor'
      }
    }); 
    
    // Further calls will return all document properties
    nuxeo.schemas('*');
    
    // Phase 0
    // Defining the variables that will be needed to attach files to the document:
    // Where attachments are located on the disk
    // ** Be sure to modify the path, keeping the trailing slash **
    let filesPath = '/path/to/contract-attachments/';
    // Which contract to update - No need to change if you followed our instructions so far
    let contractToUpdatePath = '/default-domain/workspaces/North America/awesome-tech/awesome-contract';
    // In which document property we'll store the attachments
    // Please DO NOT change or you would need to adapt the code in phase 2
    let propertiesToUpdate = {
      'files:files': []
    };
    
    // Phase 1
    // Look for attachments and upload them in an upload batch
    // The upload batch's content can be attached to a document afterward
    fs.readdir(filesPath, (err, files) => {
        if (err) {
            console.log(`Attachments folder cannot be found.\nPlease check the filesPath variable (currently set to ${filesPath}).`);
            return;
        }
    
        // Create an empty batch into which we will upload files
        let attachmentsBatch = nuxeo.batchUpload();
        files.forEach(file => {
                try {
                    // Be sure to use statSync
                    // By using a synchronous method we won't have to deal with the callback
                    // and will prevent attaching the batch's content to the document too soon
                    let stats = fs.statSync(`${filesPath}/${file}`);
                    if (!stats.isFile()) {
                        console.log(`${file} is not a file. Aborting.`);
                        attachmentsBatch.cancel();
                        return;
                    }
    
                    // We create a blob that can be uploaded from the file
                    let nxBlob = new Nuxeo.Blob({
                        'content': fs.createReadStream(`${filesPath}/${file}`),
                        'name': path.basename(`${filesPath}/${file}`),
                        'size': stats.size
                    });
    
                    // And upload it into the batch
                    attachmentsBatch.upload(nxBlob)
                        .then(uploadedFile => {
                            console.log(`File ${file} has been uploaded.`);
                        })
                        .catch(error => {
                            console.log(`File ${file} could not be uploaded. Aborting.`);
                            console.log(error);
                            attachmentsBatch.cancel();
                            return;
                        });
    
                } catch(error) {
                    console.log('Apologies, an error occurred while looking for attachments to upload. Aborting.');
                    console.log(error);
                    attachmentsBatch.cancel();
                    return;
                }
            });
    
        // Phase 2
        // We attach the batch's content into a document once upload is finished
        attachmentsBatch.done()
            .then(uploadedFiles => {
                // Parsing the batch files
                // so that they can be added to the files:files property
                for (var uploadedFilesIndex = 0; uploadedFilesIndex < uploadedFiles.blobs.length; uploadedFilesIndex++) {
                    var currentFile = uploadedFiles.blobs[uploadedFilesIndex];
                    propertiesToUpdate['files:files'].push({
                        'file': {
                            'upload-batch': currentFile['upload-batch'],
                            'upload-fileId': currentFile['fileIdx']
                        }
                    });
                }
                // Retrieving the contract to update it
                return nuxeo.repository().fetch(contractToUpdatePath);
            })
            .then(contract => {
                // Contract has been retrieved
                // Let's update it with its new properties
                contract.set(propertiesToUpdate);
                return contract.save();
            })
            .then(contract => {
                console.log('Contract has been updated. It contains the following attachments:');
                console.log(contract.properties['files:files']);
            })
            .catch(error => {
                console.log('Apologies, an error occurred while updating the contract. Aborting.');
                attachmentsBatch.cancel();
                console.log(error);
                return;
            });
    });
    
  3. Save and run:

    $ node attachFilesToContract.js
    

Note: You can download the attachments if you log in as an Administrator or a member of the managers group (e.g. by using sconnor / sconnor), otherwise download is forbidden.