Google Spreadsheet, script, backup file, subfolder - javascript

I need to backup a file on a daily basis, I have resolved this issue using the following script:
function myFunction() {
DocsList.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).makeCopy(SpreadsheetApp.getActiveSpreadsheet().getName() + "_Backup");
}
And I'm using the Time-driven trigger to set the hour I want the script creates the backup file. However, I would like these daily backups going to a specific Subfolder, lets call it "Daily Backup Folder".
Can someone help me with a script for that?
Thanks in advance!

using DocsList service:
try:
function backUp() {
var backup = DocsList.getFileById(SpreadsheetApp.getActiveSpreadsheet()
.getId())
.makeCopy(SpreadsheetApp.getActiveSpreadsheet()
.getName() + "_Backup");
backup.addToFolder(DocsList.getFolder('TEST BACKUP'));
backup.removeFromFolder(DocsList.getRootFolder());
}
However, since DocsList service is depreciated, you may want to consider Drive service.
Try:
function backUP() {
DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet()
.getId())
.makeCopy(SpreadsheetApp.getActiveSpreadsheet()
.getName() + "_Backup", (DriveApp.getFolderById('folder_id')));
}
Fill in the actual id of the folder 'Daily Backup folder' in the last line of the script and see if that works ?

makeCopy(name) is what you are using.
makeCopy(name, destination) is what you need to use.
Solution:
You will need to get your folder's ID. Open your the folder where you want to save your backup files in google drive and check it's URL in the browser's address bar.
It will look like:"https ://drive.google.com/drive/folders/zzzzz". Copy this zzzzz and replace the xxxxxx in the code below.
function myFunction() {
DocsList.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).makeCopy(SpreadsheetApp.getActiveSpreadsheet().getName() + "_Backup", DriveApp.getFolderById("xxxxxxxxxx"));
}

Related

Google Apps Script does not fully execute for other users after V8 was introduced

I wrote a script (with a lot of assistance from the good folks here) that copies a folder (and contents) on Google Drive using Google Sheets Scripts.
It worked fine for a long time but then I enabled the V8 engine (disabled now). The problem is, it still works for me (and maybe two other users) but does not work for everyone else. I'm not a programmer but I learned enough to help me automate some tasks on Excel/ Sheets.
So far, I've tried rechecking all the permissions, creating a brand new sheet, assigning new owners, removing triggers, learning more about V8. But it's not really working because I can't even figure out the problem.
I would appreciate any leads. TIA
PS: We're using shared drives and the Source/Target folder are accessible to all users.
Here's the script:
function onClick() {
ss.getRange("B2:B8").clearContent();
}
function start() {
var sourceFolder = ss.getRange("B19").getValue() ; // Change every month
var targetFolder = ss.getRange("B22").getValue();
var source = DriveApp.getFoldersByName(sourceFolder); // Grab the folder we're going to copy
var parentFolder=DriveApp.getFolderById(ss.getRange("B11").getValue()); // Destination for the new folder.
var target = parentFolder.createFolder(targetFolder);
if (source.hasNext()) {
copyFolder(source.next(), target);
}
}
function copyFolder(source, target) {
var folders = source.getFolders();
var files = source.getFiles();
var prefix = ss.getRange("B23").getValue();
while(files.hasNext()) {
var file = files.next();
file.makeCopy(file.getName(), target).setName(prefix + file.getName());
}
while(folders.hasNext()) {
var subFolder = folders.next();
var folderName = subFolder.getName();
var targetFolder = target.createFolder(folderName);
copyFolder(subFolder, targetFolder);
var NewFolderUrl = target.getUrl()
SpreadsheetApp.getActiveSheet().getRange('B8').setValue(NewFolderUrl);
}
//file.setName(prefix + file.getName());
}
Since you are not getting any logs for the users the script doesn't work for, the issue is most likely related to your functions not being executed properly and/or at all.
A issue for this is that the script is not being attached to the spreadsheet. You can try and declare the ss variable to the start function. Another issue for the behavior mentioned can be caused by passing wrong variables to the functions. You can check that by using console.log() and checking if the variables are the expected ones or not.
Moreover, since you share this script with multiple users, you might want to take a look into Edditor add-ons. This can make sharing easier as the users will only need to install the add-on.
Reference
Apps Script Troubleshooting;
Editor add-ons.
Through some trial and error - I've found that all someone had to do to run this script successfully was to open the SourceFolder once. It may be because it searches for it based on the file name.

Google Drive - how to move a specific file (.pdf) from a specific folder to another

My english is a colander and my programming skills in Javascript the same. I have in a specific folder of Google Drive several PDF files (about 10). Once a day, near midnight, I have to move these files separately (one for one) in specific Google Drive folders.
Actually I make this activity by hand, so I tried to automate it with a simple script.
I'm able to point to the specific folder, but NOT to the specific file.
In the samples I found around in Internet all files contained in a folder are moved to another folder, so the filesIterator technique are used.
But I don't need to iterate, I need to point the specific file and move it to anther folder.
Here my five (confused) program lines:
function moveFiles(source_folder, dest_folder) {
var source_folder = DriveApp.getFolderById('0B42Jhhzp_5X7QUlMdE9SZS0wMms');
var dest_folder = DriveApp.getFolderById('0B42Jhhzp_5X7TFZBMXpfeWpZNFk');
var file = getFilesByName('caa20170829.pdf');
// var files = source_folder.getFiles();
// Logger.log(file.getAs(MimeType.HTML).getDataAsString());
dest_folder.addFile(file);
source_folder.removeFile(file);
}
The error message I'm getting:
ReferenceError: "getFilesByName" not defined. (line 6, file "move")
Any help would be appreciated!
As suggested from Max Deepfield (thanks, Max), I edited the line 6 as follows
var file = DriveApp.getFilesByName('caa20170829.pdf');
and the error message changed to
Impossible to find the method addFile(FileIterator). (line 11, file "move")
Now i edited the 11. line as follows
DriveApp.dest_folder.addFile(file);
and the error message changes another time...
TypeError: Impossible to call the method "addFile" of undefined. (line 11, file "move")
Thanks to Hassan too, i am studying the examples he suggested.
But if someone would give further help... I thank in advance.
The problem is that the DriveApp Api doesn't have any methods to return single File. So you have to pass by the FileIterator.
First you don't have to put parameters in function moveFiles(source_folder, dest_folder), source_folder and dest_folder are defined inside the function. But I think you did this mistake du to the code you find on internet :)
Moreover, there is some wrong advice here: when you call DriveApp.getFolderById(), the API will return you a Folder. So you don't need to call DriveApp on this var anymore (for example DriveApp.dest_folder.addFile(file); is a bad call because the method addFile() is for Folder type, and dest_folder is already a Folder.
So you could try this, it works for me:
source_folder= DriveApp.getFolderById('YourFolderID1')
dest_folder=DriveApp.getFolderById('YourFolderID2')
var files = source_folder.getFilesByName("YourFileName").next();
dest_folder.addFile(files);
source_folder.removeFile(files);
I hope it helped you :)

save to localstorage dynamic JQuery rows

I think I have a major fault in my webpage design. I need to save the content if I reboot the computer or close the webpage.
I do not have access to any type of a database server only MS Access. I was thinking of utilizing localstorage as the page will be constantly viewed from the same computer.
I found this example [link]Edit functionality using javascript and local storage however I am not sure if it will work.
Can someone look at my example and let me know if I can do this or if I need to abandon this and start over.
$(document).ready(function () {
var id = 0;
// Add button functionality
$("table.dynatable button.add").click(function () {
id++;
var master = $(this).parents("table.dynatable");
// Get a new row based on the prototype row
var prot = master.find(".prototype").clone(true);
prot.attr("class", "")
prot.find(".id").attr("value", id);
master.find("tbody").append(prot);
});
// Remove button functionality
$(document).on("click", "table.dynatable button.remove", function () {
$(this).parents("tr").remove();
});
});
http://jsfiddle.net/deaconf19/csL68/
Thanks
If you are running the web page from a web-server -- that is, your URL begins with http:// or https://, then yes, you can use localStorage to save data.
If you are running the file directly from your hard drive, that is, your url begins with file:, then you'll have trouble. Chrome won't let you use localStorage -- I don't remember if Firefox does.
(If you need to run this from your local hard drive and not a server, and you are running under Windows, you can turn the file into an HTA and save data to a regular file.)

Inject local .js file into a webpage?

I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.
It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.
It's okay if I have to be at the computer to do this "by hand" with a console or something.
I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.
If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.
Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("MY.TargetSite.com") ) {
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
// Remove any compression or chunking
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
// Find the end of the HEAD script, so you can inject script block there.
var oRegEx = oRegEx = /(<\/head>)/gi
// replace the head-close tag with new-script + head-close
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");
// Set the response body to the changed body string
oSession.utilSetResponseBody(oBody);
}
Working example for www.html5rocks.com :
if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
oSession.utilDecodeResponse();
var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
var oRegEx = oRegEx = /(<\/head>)/gi
oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
oSession.utilSetResponseBody(oBody);
}
Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp
I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp
If you are using Chrome then check out dotjs.
It will do exactly what you want!
How about just using jquery's jQuery.getScript() method?
http://api.jquery.com/jQuery.getScript/
save the normal html pages to the file system, add the js files manually by hand, and then use fiddler to intercept those calls so you get your version of the html file

Valums file uploader: how to start with ID other than 0?

I'm using Andrew Valums' Ajax Upload plugin (GitHub link). Here is some code from it:
qq.getUniqueId = (function(){
var id = 0;
return function(){ return id++; };
})();
It's kind of a long story, but I'm in a situation where, under certain circumstances, I'd like the qq.getUniqueId function to start with an ID other than 0. It can still increment by one; it just has to start with something other than 0. What's the best way to do that?
Here are the steps to create a test environment:
Download the plugin: http://github.com/valums/file-uploader/zipball/master
Unzip it and move the "client" folder onto a web server.
Open the "demo.htm" file in a text editor, search for action: 'do-nothing.htm', and add onComplete: function(id, fileName, responseJSON) {alert(id)}, right after that.
Open the "demo.htm" file in a web browser. Be sure to access it through a web server (as opposed to just opening the local file) or else it won't work.
Upload a file. It should alert a "0" after the upload finishes. See if you can modify it so that I can pass in a different starting number.
Thanks!
Try replacing the function with one that calls the original, but adds an offset:
function offsetUniqueId(n) {
var old = qq.getUniqueId;
qq.getUniqueId = function() {
return old() + n;
}
}
See http://jsfiddle.net/alnitak/gWjqX/

Categories