Alfresco moving document - listener

I have an execution listener script, that moves a file during the workflow to another folder, from In folder to Execut.
When I'm starting workflow from User files it works good, but from document library in site it doesn't work, showing error org.alfresco.scripts.ScriptException: 05190025 Failed to execute supplied script: Destination Node is a mandatory parameter
The folder tree in document library is the same.
var dest = companyhome.childByNamePath("Execut");
for (var i = 0; i < bpm_package.children.length; i++){
bpm_package.children[i].move(dest);
}
What is the problem?
i'm understood what the problem is, this code companyhome.childByNamePath("Execut"); defines path to users folder and than moves documents from document library folders to user files folder. Need to define correct destination folder path in document library.
How to do it?
document moves from doc library to users folder, but I need that it moves to folder in document library
and I don't know how to define path.
I'm trying companyhome.childByNamePath("site/main/documentLibrary/Execut");
but it doesn't work

Update your process defination with below code.
var dest = companyhome.childByNamePath("Sites/main/documentLibrary/Execut");
for (var i = 0; i < bpm_package.children.length; i++)
{
bpm_package.children[i].move(dest);
}
You are using wrong path.Path for site is Sites/main/documentLibrary/Execut
and not site/main/documentLibrary/Execut

Related

Remove files from GDrive Trash

I have backup scripts that are copying my files into GDrive and it's also deleting files that are older than X days. But this is filling my bin with lot of these files. I want to remove them from trash bin.
I wrote this code:
function getTrashedFiles() {
//find every file in bin
var trashedSearch = DriveApp.searchFiles('trashed=true');
while (trashedSearch.hasNext()) {
var file = trashedSearch.next();
if (file.getName().indexOf("DBKLP") >= 0) {
//this is correctly printing files that I want to remove
Logger.log(file.getName());
//this should remove from bin
DriveApp.removeFile(file);
}
}
}
This code correctly finds every file, that starts at "DBKLP". But when it runs, it's not removing files from bin. It's just removing them 'once again', so their date of remove is basically "now".
I can't find a way to "remove from bin".
The AppScript DriveApp does not support it, but you can do it with the Drive API v3. As the documentation states, you'd need to use the DELETE HTTP method; alike this you could even skip trashing these files altogether. Here's an example (mine) of how to use Google API with AppScript (that's another API, but at least it's a good starting point). The documentation combined with a rough example should hopefully push you into the right direction.
From the documentation: removeFile(child) does not delete the file, but if a file is removed from all of its parents, it cannot be seen in Drive except by searching for it or using the "All items" view.
Have you tried Drive.Files.remove() instead of DriveApp.removeFile()?
To enable it, in the script editor, you have to click on the + button at "Services". Check here: imgur.com/cVFCAXQ (or, in the old editor navigate to Resources > Advanced Google Services > Drive API).
I have a similar script that seems to work. Notice that it has to find all files and folders because they are treated separately.
// Delete all files from trash older than 1 month
function cleanOldTrash() {
var files = DriveApp.getTrashedFiles();
var folders = DriveApp.getTrashedFolders();
var lastMonth = new Date();
lastMonth.setDate(lastMonth.getDate() - 30);
while (files.hasNext()) {
var file = files.next();
if (file.getLastUpdated() < lastMonth ) {
Drive.Files.remove(file.getId());
}
}
while (folders.hasNext()) {
var folder = folders.next();
if (folder.getLastUpdated() < lastMonth) {
Drive.Files.remove(folder.getId());
}
}
}
I actually do have a problem with this script when files are stored on the trash of Team Drives that I don't have permission to access, but I'll try to get more help with that in a separate question. I'll update this answer if needed.

Acquiring the Google Drive folder my google script is located

With the help of a nice article (https://www.labnol.org/internet/google-drive-tree/21198/), I just setup my first google script in Google Drive.
Quick Question:
How may I get a running script /myFolder1/music/myFirstScript.gs, to determine it's running in /myFolder1/music?
This didn't work. I got the Url but nothing in the log file showed the correct answer.
var files = DriveApp.searchFiles('title contains "GoogleTreeAgenda5"');
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
Logger.log(file.getUrl());
Logger.log(file.getDownloadUrl());
Logger.log(file.getDescription());
Logger.log(file.getOwner());
Logger.log(file.getParents());
Logger.log(file.getParents()[0].getName());
Logger.log("------------------------------");
}
Longer Behind The Scenes Reason:
The file will be modified a bit so that each month I will create a new tree structure off the root with agenda topics and the script will create an html file from the directory tree which is based on topic. Basically it will be an outline creator based on the current location of the script file. So Let's say this month it's in: /myFolder1/music (so in other words it's /myFolder1/music/myFirstScript.gs. The script needs to determine that folder is /myFolder1/music so that I can have it print the tree structure starting from the folder it's located in to an html file..
In the example application provided by the site I noted above, there are 2 options to print the tree from the google script:
1) Tree starting from the root folder
var parentFolder = DriveApp.getRootFolder();
2) Starting from a particular folder (but I can't figure out and will need "Folder_Name" to be determined dynamically from the location where the .gs file is located)
var parent = DriveApp.getFoldersByName("FOLDER_NAME").next();
I've used getScriptId() this will:
Gets the script project's unique id.
This id is also the unique id in the Google Drive. Then from there, create a recurring getParents() until you reach the root folder.
Here is the complete code:
function myFunction() {
var scriptID = ScriptApp.getScriptId();
// Logger.log(scriptID)
// Log the name of every parent folder
var driveFile = DriveApp.getFileById(scriptID);
var parentFolder = driveFile.getParents();
while (parentFolder.hasNext()) {
var folder = parentFolder.next();
Logger.log(folder.getName());
}
}
NOTE:
There is no real or concrete path since a file can have multiple parents. It is also stated here in this related SO post.
Hope this helps.

Google apps script Permissions on created file in shared folder

I have a script which creates a file in a shared Google Drive folder, this is the script:
var spr = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Klantenlijst');
var data = spr.getDataRange().getValues();
var klanNumbers = data; //some var declared before this piece of code
var file = DriveApp.createFile(fileName, JSON.stringify(klanNumbers));
This file needs to be updated frequently, to do so I remove the existing file and create a new one to replace it (with the new data). The problem is that when I try to perform the setTrashed action as a user other than the file owner, this error pops up:
You do not have authorization to perform that action.
Any ideas on how to fix that? :)
Thanks!
EDIT: I can delete the file in drive manually with the other users.
I have seen this article but I totally disagree with the conclusion that the problem is "too localized". Look around on Google and you will find cases with the same problem without a decent solution.
Workaround for this moment:
Rename the file
Move it to another folder
Create the new file in the old folder
I will not delete this post so people can add other ideas here.
You can only trash files that you own. When you delete the file manually (using the GUI to trash the file), it appears that you've trashed the file, but you are not actually setting the trashed flag on it. Rather, you are removing it from view in your own Google Drive, without affecting anyone else. The owner still sees it shared with you, and any other collaborators are unaffected. In fact, you can still see the file if you search for it by its full name, or use one of the alternate views such as the "Recent" file list, or use the file's URL.
To get the same effect from a script, use removeFile().
Here's a utility that will treat a file differently for owners than collaborators, to either trash or remove it.
/**
* Remove the given file from view in the user's Drive.
* If the user is the owner of the file, it will be trashed,
* otherwise it will be removed from all of the users' folders
* and their root. Refer to the comments on the removeFile()
* method:
*
* https://developers.google.com/apps-script/reference/drive/drive-app#removeFile(File)
*
* #param {File} file File object to be trashed or removed.
*/
function deleteOrRemove( file ) {
var myAccess = file.getAccess(Session.getActiveUser());
if (myAccess == DriveApp.Permission.OWNER) {
// If I own the file, trash it.
file.setTrashed(true);
}
else {
// If I don't own the file, remove it.
var parents = file.getParents();
while (parents.hasNext()) {
// Remove the file from the current folder.
parents.next().removeFile(file);
}
// Remove the given file from the root of the user's Drive.
DriveApp.removeFile(file);
}
}
Example:
function test_deleteOrRemove() {
var files = DriveApp.getFilesByName('536998589.mp3');
while (files.hasNext()) {
var file = files.next();
deleteOrRemove( file );
}
}

Implement a folder move function in Google Dirve

I am very new to writing any types of scripts and am trying to write a Google Apps Script to search through folders for a particular string, and if found move the folder to another folder.
I can copy a folder, but not move it since the copied folder has the same ID as the original, and deleting one deletes the other. From what I have been able to figure out I can implement this by deleting the right child from the folder. I've tried this in the APIs explorer and it does what I expect.
The problem is that I can't for the life of me figure out how to implement the example given in the Google Drive SDK page in script.google.com. If I paste in the example code I get a Missing name after . operator error. None of the scripting commands let me delete a child.
Likely this is a simple issue and arises from my trying to learn some JavaScript by doing this project, but I would appreciate any help or advice on how to implement a move function in Google Script.
The specific question is: How do I implement a move folder script? This is what I am trying, but it removes both folders:
while (contents.hasNext()) {
folder = contents.next();
name = folder.getName();
if (name.search("XYZ") != -1) {
moveFolder = folder;
targetFolder.addFolder(moveFolder) moveFolder.setName('DEL_' +
moveFolder.getName());
removeFolder(moveFolder);
}
}
First, let's clear up some confusion. Two Drive-related "Services" are provided for use within Google Apps Script, Drive Services, and Docslist Services. The documentation you've referenced is for the Google Drive SDK, which is not the same thing. If you're programming in Google Apps Script, ignore the SDK documentation.
Next, let's talk about what a folder or file is on Drive, and how that affects the concepts of "copy", "move" and "delete". A file or folder may have a folder as a parent. In fact, it may have multiple parents. If we want to have the same file or folder "copied" to another folder, we just add it as a child to the target folder. At this point, it may look like we have two items with the same ID - but what we actually have is one item with two parents. If we then remove the file or folder from the original folder (disown it, in a way), it will be left with one parent, and this will appear like a "move". The file or folder will not have been "deleted". On the other hand, if instead of removing the parent / child relationship, we DO delete the file or folder, it will appear that we have "deleted both folders", as you have described.
So, your "move" script needs to add a new parent / child relationship, and remove the other.
The Drive starter script that is presented when you open a new script in the editor contains a function called moveFileToFolder().
This function does what you are looking for, except that the thing it's moving is a file. However, the methods that are used for a file have cousins for folders, so you can just do some replacement to end up with moveFolderToFolder():
/**
* This script moves a specific folder into a given folder, and removes the folder
* from all other folders that previously contained it. For more information on
* interacting with files, see
* https://developers.google.com/apps-script/drive/file
*/
function moveFolderToFolder(sourceFolderId, targetFolderId) {
var targetFolder = DriveApp.getFolderById(targetFolderId);
var sourceFolder = DriveApp.getFolderById(sourceFolderId);
var currentFolders = sourceFolder.getParents();
while (currentFolders.hasNext()) {
var currentFolder = currentFolders.next();
currentFolder.removeFolder(sourceFolder);
}
targetFolder.addFolder(sourceFolder);
};
If you want to deal with folder Names, then you need to use getFoldersByName() to collect all matching folders, then iterate using next() into the list. Here's how that function could be modified to use folder names. To simplify things, it assumes that there is just ONE folder with the given name, and throws an exception if that's not the case. Once we have a handle on the folders we're interested in, the balance of the function remains the same as the previous example.
function moveNamedFolderToFolder(sourceFolderName, targetFolderName) {
var matchedFolders = DriveApp.getFoldersByName(sourceFolderName);
if (matchedFolders.hasNext()) {
var sourceFolder = matchedFolders.next();
if (matchedFolders.hasNext()) throw new Error( "Source Folder Name not unique" );
}
matchedFolders= DriveApp.getFoldersByName(targetFolderName);
if (matchedFolders.hasNext()) {
var targetFolder = matchedFolders.next();
if (matchedFolders.hasNext()) throw new Error( "Target Folder Name not unique" );
}
var currentFolders = sourceFolder.getParents();
while (currentFolders.hasNext()) {
var currentFolder = currentFolders.next();
currentFolder.removeFolder(sourceFolder);
}
targetFolder.addFolder(sourceFolder);
};

How do I copy & move a file to a folder in Google Apps Script?

Is there a way to copy and rename a file and move that copy to a particular folder without having a second copy in the root folder? I have used combinations of copy, rename, move in different order, but each time, I still end up with a copy of the renamed file the root drive. Is this by default? It is annoying to say the least.
In the new version of google apps script all you need to acheive your task is the following:
file.makeCopy("new name", folder);
EDIT : I had a look at your original question (before edit) and from there I understood the confusion you made about how files and folders work in Google Drive.
When you make a copy of a file you get a new file in the root folder, when you add this new file to another folder you have to consider that as sticking a label on this file without creating any new copy of it.
You can actually see the file in both the root and the other folder but it is the very same file with 2 different labels! (and you did notice that since you tried to delete it and saw it was deleted in both places)
The only thing you have to do to get the new file in its folder and not shown in the root it to remove the "root label".
That's how Google drive works. And when you think about it and compare to a local hard disk storage it gets logical : when you move a file from one folder to another on the same logical drive you don't move data (ie the bytes on the disk) but simply tell the disk operating system that this file is somewhere else on the map.
So consider Google Drive as a (very) large disk unit with billions on files that you can't move but on which you can stick as many labels as you want ;-) (the most important label being your Google account ID !)
And to play with these labels in the case you describe just try this simple function :
function copyAndMove(file,folder){
var newfile=file.makeCopy('copy of '+file.getName());// here you can define the copy name the way you want...
newfile.addToFolder(folder);// add the copy to the folder
newfile.removeFromFolder(DocsList.getRootFolder());// and remove it from your root folder
}
to test it just use the 2 required parameters : the file object anf the folder object that you can get from many different methods, see the DocsList documentation for details on how to get it if you need to but I guess you already know that ;-)
Yeah, it is a bit odd that Google does not provide a move method. But, considering how drive works and that a file can belong to multiple folders, it makes some sense that you have write your own moves. Here is a simple move function I wrote:
// Moves a file to a new folder by removing all current
// parent folders and then adding the new one.
function moveFileTo(fileObj, folderObj) {
// Attempt the move only if folderObj has a value.
// Otherwise, the file will be left without a folder.
// (Lost files can be found in the "All items" area.)
if (folderObj) {
var folders = fileObj.getParents();
for (var i = 0; i < folders.length; i++) {
fileObj.removeFromFolder(folders[i]);
}
fileObj.addToFolder(folderObj);
return true;
}
return false;
}
Basically, use it like this:
var file = DocsList.getFileById(fileID);
var folder = DocsList.getFolder('Some folder name');
// Make a backup copy.
var file2 = file.makeCopy('BACKUP ' + Utilities.formatDate(new Date(), Session.getTimeZone(), 'yyyy-MM-dd') + '.' + file.getName());
// Move the backup file.
if (moveFileTo(file2, folder)) {
...
I should note that this simple function is exactly that... simple. It assumes you are okay with whacking all parent folders -- owned or shared. This can have unexpected consequences with shared files in various shared folders of various users if you are not careful. It does not appear, however, to remove parent folders that are not shared with the user of this script -- which is good. Anyhow, one obvious alternative to control things better would be to specify the "from" folder as well as the "to" folder.