Google Drive API - Bulk Uploader, File Renaming and Timeouts - google-apps-script

I recently found a great google script which allows one to use Google Sheets to list lots of downloads (Jpegs in my case) and set titles. The script transloads(?)... moves the files from a remote place to your Google Drive. So no pointless downloading, uploading in-between.
function SaveToGoogleDrive(){
var folderID = 'FOLDER_HERE'; // put id of the Google Drive folder
var folder = DriveApp.getFolderById(folderID)// get the folder
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 1; i < data.length; i++) {
var pdfURL = data[i][2];
var myFileName = data[i][1] + '.pdf';
var file = UrlFetchApp.fetch(pdfURL);
folder.createFile(myFileName,file);
}
}
(code comes via - http://unexpectedweb.blogspot.com.es/2017/11/directly-save-file-to-google-drive-by.html )
The script should allow me to set a name for each upload, which will be applied to the file on adding to Google Drive, but this doesn't work for me.
Is there something obvious in the code which doesn't look good to you as renaming doesn't work. Perhaps there's a script that will allow me to rename once the files are all in my Google Drive?
Also- I'm transloading(?) about 500 files and Google's Scripts can only run for 6mins. How would I incorporate something like the script demonstrated here:
That code...
/* Based on https://gist.github.com/erickoledadevrel/91d3795949e158ab9830 */
function isTimeUp_(start) {
var now = new Date();
return now.getTime() - start.getTime() > 300000; // 5 minutes
}
function SaveToGoogleDrive(){
var folderID = 'FOLDER_HERE'; // put id of the Google Drive folder
var folder = DriveApp.getFolderById(folderID)// get the folder
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var threads = GmailApp.getInboxThreads(0, 50);
var start = new Date();
for (var i in threads) {
if (isTimeUp_(start)) {
Logger.log("Time up");
break;
}
// Process the thread otherwise
for (var i = 1; i < data.length; i++) {
var pdfURL = data[i][2];
var myFileName = data[i][1] + '.pdf';
var file = UrlFetchApp.fetch(pdfURL);
folder.createFile(myFileName, file);
}
}
}
Thanks for your thoughts. Having so much trouble marrying the two together with my limited knowledge.

Change
folder.createFile(myFileName,file);
to
folder.createFile(file).setName(myFileName);

Related

How update Google form display after changing file name with script

I'm using a Google form with multiples subpart (Multiple choices, Short answer...) and one upload file box.
When I upload a file, the name of the logged user is added into the file name. I don't want this.
So I use a Google script to change their name, it's ok in the folder directory (the file names are correctly updated), but in the Google form display ("Responses" section), there is always the old names.
How can I force the refresh of the Form display ?
Here is my script :
function myFunction() {
var existingForm = FormApp.getActiveForm();
var formResponses = existingForm.getResponses();
for (var i = 0; i < formResponses.length; i++) {
var formResponse = formResponses[i];
var itemResponses = formResponse.getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
var itemResponse = itemResponses[j];
var title = itemResponse.getItem().getTitle();
var files = itemResponse.getResponse();
for (var n in files) {
var my_file = files[n];
var dFile = DriveApp.getFileById(my_file);
var dFileName = dFile.getName();
dFile.setName("New name " + n);
}
}
}
}
Thanks for your help
Upon checking the available methods and Form Settings, there is no way to change the file names under Responses even if the actual file in the directory/folder is already renamed.
Even the Forms UI doesn't provide any way of renaming the uploaded file name under Responses so it is highly unlikely to be supported in Apps Script as well.

In the Google Drive Zip files in specific folder, get the adress of zipped file and add it to spreadsheet

I am not able to zip the file. For individual file, no problem.
I am no specialist, no coder, I just have to manage tones of DATA, I was doing things one file at the time, but the company is progressing so fast it will not be sustenable, I am asking newbee questions, sorry for that.
function zipall() {
var ss = SpreadsheetApp.openById("1Ib6ul8KHIcRfE1lJVpWou6SU9bYdBnU-jd8d5eEuWnw");
SpreadsheetApp.setActiveSpreadsheet(ss);
var sheet = ss.getSheetByName('Drive管理用');
for(var i=93; i<94; i++){
if (AdressData != 0 ){
var AdressData = sheet.getRange(i,26).getValue();
var folder = DriveApp.getFolderById(AdressData);
var files = folder.getFiles();
var blobs = [];
while (files.hasNext()) {
blobs.push(files.next().getBlob());
}
var zipBlob = Utilities.zip(blobs, folder.getName() + ".zip");
var fileId = DriveApp.createFile(zipBlob).getId()
//var url = "https://drive.google.com/uc?export=download&id=" + fileId;
//sheet.getRange(i,27).setValue(url);
}}}
I have an other error message
"File selection.zip exceeds the maximum file size.(行 19、ファイル「Code」)
表示しない" Message is shown
But I never had a size problem when I do it manually.
???

copy spreadsheet to a specific folder and remove viewers from the copy

I'm trying to make a copy of the active spreadsheet to a specific folder, then remove all editors from the copied spreadsheet and keep myself as Owner.
Here is my code :
//Save Spreadsheet in selected folder
function freezeSS(vname,option) {
if (vname != ""){
var mainSs = SpreadsheetApp.getActiveSpreadsheet();
var SSID = mainSs.getId();
var CopyDate = Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yy-HH:mm"); // Function Date + Format
var file = DriveApp.getFileById(SSID);
if (option == "Public") {
var folder = DriveApp.getFolderById("0B_EpGZ420rEUfk1mZ2Z3RmFKUk9xaGd1bm1CdGhmZ0FCbTdVT2p2MUlJY3NZUTV0MTR0LTQ");
file.makeCopy(vname + "_" + CopyDate, folder);
}
else {
var folder = DriveApp.getFolderById("0B_EpGZ420rEUfk9jTl81NXNVOXNhRDF2N2R4c1FGTW9wQTB5Q3dNS25nd1NEejBTWWd1RFk");
var backup = file.makeCopy(vname + "_" + CopyDate, folder);
var editors = backup.getEditors().getEmail();
Logger.log(editors);
var permision = backup.removeEditor(editors);
}
} return false;
}
Everything works but I have a problem in removing editors. I always get an error and still have the same editors as in the original spreadsheet.
As the documentation states, you have 2 options for removeEditor():
removeEditor(user)
or
removeEditor(emailAddress)
You're using neither, you'll need to make a loop in the getEditors() without the getEmail(), this one will also get into the loop, as so:
var editors = backup.getEditors();
for( i in editors ){
var email = editors[i].getEmail();
var permision = backup.removeEditor(email);
}
or shorter:
var editors = backup.getEditors();
for( i in editors )
var permision = backup.removeEditor(editors[i]);
BTW, this was well documented, a ctrl+c ctrl+v from there would almost solve your problem, please take a little more time to fiddle with it.
https://developers.google.com/apps-script/reference/drive/user#getEmail();

Google Apps Script Exporting Blank Copy of Copied Template Spreadsheet

I have a source spreadsheet with content.
I have a destination template for that content.
I select and copy the content in the source spreadsheet.
I create a copy of the destination template and paste in the source spreadsheet content.
I then execute some code to export the destination template as an XLSX file and attach it to an email.
The email and the attachment come through, but the contents of the XLSX file match the original template - the content I pasted in is missing.
Yet if I take my export string and run it through the browser, it exports the XLSX file just fine with the contents!
It appears the export function is running before the content paste is complete and sending the newly created destination template without the contents.
I've already tried Utilities.sleep(30000), but no matter how long I wait, I always get a blank copy of the original template. WTF?!
Complete code:
function sendVendor() {
// Open the Active Spreadsheet
var ssMaster = SpreadsheetApp.getActiveSpreadsheet();
var sheetInsert = ssMaster.getSheetByName('Insert RFQ');
var rfqNumber = sheetInsert.getRange('AW2').getValue();
var sheetWorkUp = ssMaster.getSheetByName('WORK UP');
var backgroundColor = '#FF5050';
var row = 11;
var newSheetRow = 13;
var numRows = 0;
var valuesPartNumbers = sheetWorkUp.getRange(12, 2, 233, 1).getValues();
var size = valuesPartNumbers.filter(function(value) { return value != '' }).length;
size = size - 1;
// Create the new RFQ from Template
var template = DocsList.getFileById('1M2f5yoaYppx8TYO_MhctEhKM_5eW-QCxlmJdjWg9VUs'); // Quote Workup Template
var newRFQ = template.makeCopy('Vendor RFQ Request ' + rfqNumber);
var newRFQId = newRFQ.getId();
var folderNew = DocsList.getFolder('Vendor RFQ Requests');
newRFQ.addToFolder(folderNew)
// Open new RFQ
var ssTemplate = SpreadsheetApp.openById(newRFQId);
var sheetVendorRequest = ssTemplate.getSheetByName('Vendor Request');
var newTemplateURL = ssTemplate.getUrl();
var needPricing = new Array();
var valuesFRCosts = sheetWorkUp.getRange(12, 8, size, 1).getValues();
for (var i = 0; i < valuesFRCosts.length; i++) {
row++;
if (valuesFRCosts[i][0] == '') {
var sheetWorkUpRow = sheetWorkUp.getRange(row, 1, 1, sheetWorkUp.getLastColumn());
sheetWorkUpRow.setBackground(backgroundColor);
var sendToTemplate = sheetWorkUp.getRange(row, 1, 1, 6).getValues();
sendToTemplate[0].splice(2, 1);
sheetVendorRequest.getRange(newSheetRow, 2, 1, 5).setValues(sendToTemplate);
newSheetRow++;
}
}
var url = 'https://docs.google.com/feeds/download/spreadsheets/Export?key=' + newRFQId + '&exportFormat=xlsx';
var doc = UrlFetchApp.fetch(url);
var attachments = [{fileName:'Vendor RFQ Request ' + rfqNumber, content: doc.getContent(),mimeType:"application/vnd.ms-excel"}];
MailApp.sendEmail("user#domain.com", "Excel Export Test", "See the attached Excel file.", {attachments: attachments});
}
The solution is to add SpreadsheetApp.flush(); prior to the export (just before var url). The SpreadsheetApp was still occupied with the template (in memory) after being copied - flushing it, and then exporting, forces the script to make a new call to the new Spreadsheet and get the latest data.
Thank you, Faustino Rodriguez.

GAS Loop goes indefinite

Problem:-
I need to get Name and ID of the latest created document from some Google Drive folders.
Solution:-
I wasn’t able to find an easy way to get it, hence, created a loop for files within the folder to get max date - then loop again in folder to match the date and Log the name and date – the below code (when commented as mentioned) works properly for the solution.
Instead of rewriting the whole code with just a different folder name, I tried creating a loop for folder name as well.
However app script goes into infinite loop giving out the Maximum execution time limit message.
Any help appreciated.
function Get_lastestdate() {
//Define Spreadsheet and sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("PEOPLE");
//comment from here to work properly
for (var i =1; i < 4; i++) {
if (i = 1) { var foldername = "Folder1"}
if (i = 2) { var foldername = "Folder2"}
if (i = 3) { var foldername = "Folder3"}
// till here
//Define folder and files
var folder = DocsList.getFolder(foldername); //set folder name in case commenting.
var lastfile = folder.getFiles();
//Make a blank array
var noofdaysarray = []
var yeararray = []
//Loop to get all No of days in a year & the year
for (var i in lastfile) {
noofdaysarray.push(Utilities.formatDate(lastfile[i].getDateCreated(),"GMT","D"));
yeararray.push(Utilities.formatDate(lastfile[i].getDateCreated(),"GMT","y"));
}
//Get the max date from date and year
var largestdate = Math.max.apply(Math, noofdaysarray);
var largestyear = Math.max.apply(Math, yeararray);
//Get maximum available date
var matchcriteria = largestdate + largestyear
//Again loop for matching criteria with the actual date uploaded
for (var i in lastfile) {
var lastdate = Utilities.formatDate(lastfile[i].getDateCreated(),"GMT","D");
var lastyear = Utilities.formatDate(lastfile[i].getDateCreated(),"GMT","y");
var wholedate = parseInt(lastdate) + parseInt(lastyear); //parseInt is for converting text to number
//Get doc name if both dates matches
if (wholedate == matchcriteria) {
Logger.log(lastfile[i].getId());
Logger.log(lastfile[i].getName());
}
}
} //comment this as a part of loop
}
Between:- If there's an easier way to do it, please let me know.
You can use DocsList to retrieve the last modified files. you told that you want the last created but maybe the last modified can be usefull. Check the code bellow:
function findLastModified() {
//Retrieve folder
var folder = DocsList.getFolderById("0B0kQD4hSd4KASUJKb2cya0NET1U");
//Ask for 5 files
var numberOfFiles = 5;
//The first parameter is the search query, in this case we want all files
var filesResult = folder.findForPaging("", 5);
//By Default they will be sorted by last modified date
var files = filesResult.getFiles();
Logger.log("Found "+files.length+" files");
//Iterate
for(var x in files) {
var file = files[x];
Logger.log(file.getLastUpdated());
}
}
Live version here.
Dont use "i" in both inner and outer loops. that will be a problem.
wouldn't it be easier to do something like this so you only do one loop?
var mostRecentDate = new Date(2000,01,01);
var fileName="";
var fileId="";
for(var i = 1; i<5; i++){
var folder = DocsList.getFolder('Folder'+i);
var files = folder.getFiles();
for(var j in files) {
if(files[j].getDateCreated()>mostRecentDate){ //or getLastUpdated
mostRecentDate=files[j].getDateCreated();
fileName=files[j].getName();
fileId=files[j].getId();
}
}
}
Logger.log("File: " + filename + " Id: " + fileId + " Created: " + mostRecentDate);
You may need to do paging if you have a huge number of files & folders to iterate through.