Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overwrite an Image File with Google Apps Script

Can I overwrite an image file with Google Apps Script? I've tried:

file.setContent(newBlobImage);
file.replace(newBlobImage);

Neither of those work. .setContent() will delete whatever data was in the file, and it looks like maybe it just writes the variable name as text, or something like that. I'm assuming that both .setContent() and .replace() are meant for text documents, and maybe that's why they don't work.

If it were a text file, or a spreadsheet, I might be able to clear it, then append new content.

I can trash the file, then create a new one, but I'd rather not if there is some other way.

If I write a file with the same name, it won't overwrite the existing file, it creates a another file with the same name.

The only way I've been able to trash the file is with DocsList and the only success I've had with creating an image file is with DriveApp. So I have to trash the file with DocsList, then create another file with DriveApp.

Well, I've figured out how to delete the file without sending it to the trash, so I won't need to clean out the trash later. The Google Drive SDK inside of Apps Script has a remove method that didn't send the file to trash, it's just gone.

var myFolder = DriveApp.getFolderById('3Bg2dKau456ySkhNBWB98W5sSTM');

thisFile = myFolder.getFilesByName(myFileName);

while (thisFile.hasNext()) {
  var eachFile = thisFile.next();
  var idToDLET = eachFile.getId();
  Logger.log('idToDLET: ' + idToDLET);

  var rtrnFromDLET = Drive.Files.remove(idToDLET);
};

So, I'm combining the DriveApp service and the DriveAPI to delete the file without sending it to the trash. The DriveAPI .remove needs the file ID, but I don't have the file ID, so the file gets looked up by name, then the file ID is retrieved, then the ID is used to delete the file. So, if I can't find a way to overwrite the file, I can at least delete the old file without it going to the trash.

I just noticed that the DriveAPI service has a Patch and an Update option.

.patch(resource, fileId, optionalArgs)

Google Documentation Patch Updates file metadata.

The resource arg is probably the metadata. The fileId is self explanatory. I'm guessing that the optionalArgs are parameters that follow the HTTP Request Patch semantics? I don't know.

It looks like both Patch and Update will update data. Update is a PUT request that will

clears previously set data if you don't supply optional parameters.

According to the documentation. So it's safer to use a Patch request because any parameters that are missing are simply ignored. I haven't tried it yet, but maybe this is the answer.

I'm getting an error with Patch, so I'll try Update:

.update(resource, fileId, mediaData)

That has a arg for mediaData in the form of a blob. And I think that is what I need. But I'm not sure what the resource parameter needs. So I'm stuck there.

like image 327
Alan Wells Avatar asked Jun 15 '14 01:06

Alan Wells


People also ask

How do I overwrite a file on Google Drive?

Right-click the file and select Manage versions. Click Upload new version and select a file from your computer. When the new version is done uploading, click Close.

How do you overwrite in Google Sheets?

Go to the add-on menu inside the Google Spreadsheet, choose Save Emails > Create Rule and check the option that says “Overwrite attachments”.

How do I assign an image to a script in Google Sheets?

Return to Sheets and insert an image or drawing by selecting Insert > Image or Insert > Drawing. After inserting the image or drawing, click it. A small drop-down menu selector will appear in the top right-hand corner. Click it and choose Assign script.


2 Answers

An image file can be overwritten with Google Apps Script and the DriveAPI using the update() method:

.update(File resource, String fileId, Blob mediaData)

Where file resource is:

var myFileName = 'fileName' + '.jpg';

var file = {
  title: myFileName,
  mimeType: 'image/jpeg'
};

I'm getting the file ID with the DriveApp service, and the Blob is what was uploaded by the user.

In order to use DriveAPI, you need to add it through the Resources, Advanced Google Services menu. Set the Drive API to ON.

var allFilesByName,file,myFolder,myVar,theFileID,thisFile;
   //Define var names without assigning a value

file = {
  title: myFileName,
  mimeType: 'image/jpeg'
};

myFolder = DriveApp.getFolderById('Folder ID');

allFilesByName = myFolder.getFilesByName(myFileName);

while (allFilesByName.hasNext()) {
  thisFile = allFilesByName.next();
  theFileID = thisFile.getId();
  //Logger.log('theFileID: ' + theFileID);
  
  myVar = Drive.Files.update(file, theFileID, uploadedBlob);
};
like image 69
Alan Wells Avatar answered Oct 10 '22 16:10

Alan Wells


Thank you for this track !

This allowed me to find a solution to my problem : move a bound form after copying and moved his spreadsheet.

The Drive app advanced service must be activated in the "Resource Script Editor" to run this script.

function spreadsheetCopy() {
  // Below is the file to be copied with a bound form.
  var fileToCopy = DriveApp.getFileById("file_key"); // key is fileId
  var saveFolder = DriveApp.getFolderById("folder_key"); // key is folderId
  var currentFolder = "";
  ( fileToCopy.getParents().next() ) ? currentFolder = fileToCopy.getParents().next() : currentFolder = DriveApp.getRootFolder();  
  Logger.log(currentFolder)
  var copyFile = fileToCopy.makeCopy(saveFolder),
      copyName = copyFile.getName(); 
  Utilities.sleep(30000);
 moveFormCopy(currentFolder, saveFolder, copyName);
}

function moveFormCopy(currentFolder, saveFolder, copyName) {  
  var formsInFolder = currentFolder.getFilesByType(MimeType.GOOGLE_FORMS);
  var form, copyForm, copyFormMimeType, copyFormName, copyFormId;
  while ( formsInFolder.hasNext() ) {
    form = formsInFolder.next();
    if ( copyName === form.getName() ) {
      copyForm = form;
      copyFormMimeType = copyForm.getMimeType();
      copyFormName = copyForm.getName();
      copyFormId = copyForm.getId();
      break;
    }
  };  
  var resource = {title: copyName, mimeType: copyFormMimeType};
  Drive.Files.patch(resource, copyFormId, {addParents: saveFolder.getId(), removeParents: currentFolder.getId()})
}
like image 37
Jean Gorene Avatar answered Oct 10 '22 16:10

Jean Gorene