How to avoid creating duplicate folders in Google Drive - google-sheets

function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv');
for (var i = 0 ; i < sheets.length ; i++) {
var sheet = sheets[i];
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
}
}
This code creates CSV file from a spreadsheet by creating a folder with the spreadsheet's name with 'CSV' added to it. I have been unable to stop it from making a new folder each time, as I want the csv file to be placed in this specific folder each time to update the data. I know I need to see if the folder exists and if not, create it first, otherwise just put the csv file in the existing folder (or the one that was created). It sounds simple, but I have been unable to do it.

You could create a helper function that checks if the folder exists. If it exists the function can return the folder, if it doesn't it can create the folder. In both cases, it will return a folder object.
function yourFunction() {
/*
some code
....
*/
//Get the folder by calling the helper function.
var folder = getFolder("nameOfFolder");
//Create a file in the folder
folder.createFile("fileName", csvFile)
/*
some more code
....
*/
}
//Returns the folder or creates it if it doesn't exist.
function getFolder(folderName) {
var f = DriveApp.getFoldersByName(folderName);
return f.hasNext() ? f.next() : DriveApp.createFolder(folderName);
}

Test out the function below with a try{} catch(e){} to either find or create the folder.
NOTE: this function checks every folder on your drive, so if you have a large number of folders you may need to modify it to only check within a folder.
function testFolder(folderName){
var exist = false;
for(var i in targetFolders){
var parentFolder = DriveApp.getFolderById(targetFolders[i]);
var childFolders = parentFolder.getFolders();
while(childFolders.hasNext()) {
var child = childFolders.next();
Logger.log('listFolders ' + child.getName());
if(child.getName() == folderName){
exist=true;
break;
}
}
}
return exist;
}

Related

generate/making a grahic for each student in googlesheet and auto save the graphic image to gdrive

need your help again..
so I have many student. and every week we have exam.
so I want to make individual Graphic of their progress for every week.. and send it ass attachment with autocrat to their email.
my problem is
how do I make an individual graphic continuedly (i mean not one by one change the name)
how to save that individual graphic to google drive
how to get the link image on google drive
those 3 problem is to make report for my student one by one like this pic
please share idea with me.. I'm really thank you for helping me here..
here the spreadsheet link : https://docs.google.com/spreadsheets/d/1fmS7PM65CMGGe5g00ojqqiK2CFr5HFgo_6L_Qki7QLw/edit#gid=1364826426
I can't understand and solve your problem all, since your problem seems a bit too complex.
However, I know how to save a sheet as a PDF easier and get the PDF's URL automatically.
It needs a script program.
I made a sample program based on another answer.
This is my code.
function exportPDF(){
// get parameters
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = sheet.getRange("B2").getValue();
var fileName = sheet.getRange("B3").getValue();
sheet.getRange("B4").setValue("");
// export the sheet
var fileUrl = exportSheet(sheetName, fileName);
// show the url
sheet.getRange("B4").setValue(fileUrl);
}
// based on https://stackoverflow.com/questions/38335143/export-single-sheet-to-pdf-in-apps-script
function exportSheet(sheetName, fileName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var fileUrl = "";
try{
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].getSheetName() !== sheetName) {
sheets[i].hideSheet()
}
}
var file = DriveApp.createFile(ss.getBlob());
file.setName(fileName);
file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
fileUrl = file.getUrl();
}
catch(e){
console.log(e);
throw e;
}
finally{
for (var i = 0; i < sheets.length; i++) {
sheets[i].showSheet()
}
}
return fileUrl;
}
If this can help, check this sample sheet and make a copy. ([File]-[Make a copy])
https://docs.google.com/spreadsheets/d/1lCxNSaXsd9tno4xdog6Usa0l1SZeuXrc62Oi6TK-VsY/edit?usp=sharing
I have created three charts in the spreadsheet for you.
Save or publish your chart

How to add files to a list in vala?

I want to add files to a list and then access them in a for loop. This is how I try to do it:
private get_app_list () {
var file = new File.new_for_path (/usr/share/applications);
List<File> app_list = new List<File> ();
foreach (File desktop_file in app_list) {
// other code here
}
}
What is the right way to access files stored in a directory and then add them to a list??
using Posix;
...
List<File> app_list = new List<File> ();
//Open directory. Returns null on error
var dirHandle = Posix.opendir("/usr/share/applications");
unowned DirEnt entry;
//While there is an entry to read in the directory
while((entry = readdir(dir)) != null) {
//Get the name
var name = (string) entry.d_name;
//And add a new file to the app_list
app_list.add(new File.new_for_path("/usr/share/applications"+name);
}
If you want to merely display the available apps on system, you could use the utilities supplied by the Gio-2.0 lib. After adding dependency ('gio-2.0'), to your meson.build file you could use code similar to the following:
/* We use a `GListStore` here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, `GAppInfo`
* is the object we provide.
*/
var app_list = new GLib.ListStore (typeof (GLib.AppInfo));
var apps = GLib.AppInfo.get_all ();
foreach (var app in apps) {
app_list.append (app);
}
If however you need to list files inside a directory, it's possible also to use the higher level API provided by the same gio-2.0 library. Here is a sample code to enumerate files inside "/usr/share/applications/"
void main () {
var app_dir = GLib.File.new_for_path ("/usr/share/applications");
try {
var cancellable = new Cancellable ();
GLib.FileEnumerator enumerator = app_dir.enumerate_children (
GLib.FileAttribute.STANDARD_DISPLAY_NAME,
GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable
);
FileInfo ? file_info = null;
while (!cancellable.is_cancelled () &&
((file_info = enumerator.next_file (cancellable)) != null)) {
// Ignore directories
if (file_info.get_file_type () == GLib.FileType.DIRECTORY) {
continue;
}
// files could be added to a list_store here.
/*
* var files_list = new GLib.ListStore (typeof (GLib.FileInfo));
* files_list.append (file_info);
*/
print (file_info.get_display_name () + "\n");
}
} catch (GLib.Error err) {
info ("%s\n", err.message);
}
}
I hope this could be of any help.

Retrieve url of uploaded file from google form

I have found an extremely good google script for a google form that allows me to retrieve the answers of a google form in a spreadsheet along with the "getEditResponseUrl()" that will help me build a database that can be modified through the google form.
However, I am struggling in getting the url of an "upload file question". The question where the user is supposed to upload a file is the fourth one "facture".
The answer I get in my spreadsheet is only "[Ljava.lang.Object;#508c8b8b" but not the file.
Any idea how to make this work so that I get the url of the file that was uploaded by the user ?
Thank you and Kind regards
var ss = SpreadsheetApp.openById("spreadsheeturl"); // to be customised
var responseSheet = "Database"; // to be customised
function submitFormFunc(e) {
var items = e.response.getItemResponses();
var responses={};
for(var i = 0; i< items.length; i++) {
responses[items[i].getItem().getTitle()]=items[i].getResponse();
}
var responseRow = [];
responseRow.push(e.response.getTimestamp().toString());
responseRow.push(e.response.getId());
responseRow.push(responses["Challenge"]); // to be customised
responseRow.push(responses["Client"]);
responseRow.push(responses["Date"]);
responseRow.push(responses["Facture"]);
// to be customised
// add as many as needed
responseRow.push(FormApp.getActiveForm().getResponse(e.response.getId()).getEditResponseUrl());
var isNewItem = alreadyExist(ss,e.response.getId());
if(isNewItem<0){
ss.getSheetByName(responseSheet).appendRow(responseRow);
}
else{
ss.getSheetByName(responseSheet).getRange(isNewItem+2, 1, 1, 6).setValues([responseRow]);
}
}
function alreadyExist(ss,id){
var ids = ss.getSheetByName(responseSheet).getRange("B2:B").getValues();
for(var i=0; i< ids.length; i++){
if(ids[i][0]===id){
return(i);
}
}
return(-1);
}
Here's a snippet from the Form Notifications add-on that converts the uploaded file ids into Google Drive URLs and concatenates the result in case of multiple uploads.
var urls = answer.toString().split(",").map(function(f) {
return "https://drive.google.com/open?id=" + f;
}).join(", ");

Creating a hyperlink in active cell from uploaded file

I'm designing a shared Google Sheets for our team to keep track of each piece of content we produce. I want to implement a feature that allows people to upload a preview clip and have a hyperlink automatically created within the active cell.
My script so far serves up HTML as a user interface with a file upload and name entry. This part works fine and allows anyone to upload straight to Google Drive.
I've been having trouble getting it to automatically create a hyperlink in the active cell to the uploaded file. Been searching around, but haven't had a great deal of luck.
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('File Upload')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('form.html')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Upload A File');
}
function uploadFiles(form) {
try {
var dropbox = "Clips";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName);
return "File uploaded successfully " + file.getUrl();
} catch (error) {
return error.toString();
}
}
My suggestion is to modify the return value from uploadFiles() to be an object, then use the URL to populate a spreadsheet HYPERLINK() formula.
return "File uploaded successfully " + file.getUrl();
Becomes:
return {
result: "File uploaded successfully",
fileURL: file.getUrl(),
fileDesc: file.getDescription() // Could be other values
};
Next, a function that sets the formula. This server-side function would be called with the values to be used in the formula, which were previously returned from uploadFiles(). I'm assuming this is from your client-side JavaScript, but that's just a guess, since you didn't include that in your question.
function setHyperlink( fileURL, fileDesc ) {
var formula = '=HYPERLINK("' + fileURL + '","' + fileDesc + '")';
SpreadsheetApp.getActiveCell()
.setFormula( formula );
return true;
}
I ended up solving this issue using the GAS Properties Service - creating 2 new User Properties to contain URL and Name data.
I also found a few issues with getActiveCell - it kept placing the link in A1. Although I had used Google's suggested method for returning the active cell, I was able to use the fix suggested here:
http://bit.ly/20Gc7l6
Here's my final script
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('File Upload')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('form.html')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Upload A File');
}
function uploadFiles(form) {
try {
var dropbox = "Blacksand Clips";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile;
var file = folder.createFile(blob);
file.setDescription(file.getDescription());
var userProperties = PropertiesService.getUserProperties();
var link = file.getUrl();
var name = file.getName();
userProperties.setProperty('link', link);
userProperties.setProperty('name', name);
setHyperlink();
return "File uploaded successfully ";
} catch (error) {
return error.toString();
}
}
function setHyperlink() {
var userProperties = PropertiesService.getUserProperties();
var link = userProperties.getProperty('link');
var displayName = userProperties.getProperty('name');
var value = 'hyperlink("' + link + '","' + displayName + '")'
var ss = SpreadsheetApp.getActiveSheet();
var cell = ss.getActiveCell().activate();
cell.setFormula( value )
return true;
}

how to create .txt in local file system using Firefox extension

I am currently working on ffsniff extension code. In that I have to save data containing password information into a file in my local system. I have written my code but it is not even creating the file in my local system. (working in mozilla firefox)
Here is my code please help me out.
//// here data variable contains all the information
var fso = new ActiveXObject("Scripting.FileSystemObject");
varFileObject = fso.OpenTextFile("C:\\logs.txt", 2, true,0);
varFileObject.write(data);
varFileObject.close();
after this i tried different code:
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("Desk", Components.interfaces.nsIFile);
file.append("logs.txt");
var ostream = FileUtils.openSafeFileOutputStream(file)
var converter = Components.classes["#mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
}
});
but none of them is working..
Here's a working snippet that creates the destination directory if necessary and writes (overwrites) to file (in this case d:\temp-directory\temp-file.txt):
var {Cc,Ci,Cu}=require("chrome"); //for jetpack sdk.
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
var localFile = Cc["#mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
var data="test file content";
//localFile.initWithPath("D:\\temp-directory\\temp-file.txt"); //full path is okay if directory exists
localFile.initWithPath("D:\\temp-directory\\"); //otherwise specifiy directory, create it if necessary, and append leaf.
if(!localFile.exists()){
localFile.create(localFile.DIRECTORY_TYPE,FileUtils.PERMS_DIRECTORY);
}
localFile.append("temp-file.txt");
//localFile.createUnique(localFile.NORMAL_FILE_TYPE,FileUtils.PERMS_FILE); //optional: create a new unique file.
asyncSave(localFile,data,onDone);
function asyncSave(file,data,callbackDone){
// file is nsIFile, data is a string, optional: callbackDone(path,leafName,statusCode)
// default flags: FileUtils.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE);
var ostream = FileUtils.openSafeFileOutputStream(file);
var converter = Cc["#mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
// optional: callbackSaved(status).
NetUtil.asyncCopy(istream, ostream, callbackSaved);
function callbackSaved (status) {
if(callbackDone){
if(status===0)callbackDone( file.path, file.leafName, status); //sucess.
else callbackDone( null, null, status); //failure.
};
}
}
function onDone(path,leafName,statusCode){
console.log([statusCode===0?"OK":"error",path,leafName].join("\n"));
}
More information:
https://developer.mozilla.org/en-US/docs/Code_snippets/File_I_O
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/FileUtils.jsm
https://developer.mozilla.org/en-US/docs/PR_Open
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/NetUtil.jsm
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIFile
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsILocalFile
A simple example of how to read/write a file from the filesystem in windows, using Firefox Extension:
// Write File to filesystem
Components.utils.import("resource://gre/modules/osfile.jsm"); // load the OS module
var encoder = new TextEncoder(); // This encoder can be reused for several writes
var array = encoder.encode("just some text"); // Convert the text to an array
var promise = OS.File.writeAtomic("C:\\foo.txt", array,{tmpPath: "foo.txt.tmp"}); // Write the array atomically to "file.txt", using as temporary
alert("URL HOST has been saved");
//Read File from filesystem
var decoder = new TextDecoder(); // This decoder can be reused for several reads
var promise = OS.File.read("C:\\foo.txt"); // Read the complete file as an array
promise = promise.then(
function onSuccess(array) {
alert(decoder.decode(array)); // Convert this array to a text
}
);
This solution is for making file in ubuntu, hope this helps others:
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
file.append("trick_new");
if( !file.exists() || !file.isDirectory() ) { // if it doesn't exist, create
file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
}
this.log_file = file.path + "/newlog.html";
You can also use text-stream to write to a local file.
function writeTextToFile(text, filename) {
var fileIO = require("sdk/io/file");
var TextWriter = fileIO.open(filename, "w");
if (!TextWriter.closed) {
TextWriter.write(text);
TextWriter.close();
}
}

Resources