SankeySheets/libraries/cUseful/DriveUtils.js
2016-09-22 11:11:10 +01:00

425 lines
12 KiB
JavaScript

/**
* Utils contains useful functions for working with drive
* you must provide run DriveUtils.setService(yourdriveapp) before using
* @namespace
*/
var DriveUtils = (function (ns) {
var ENUMS = {
MIMES: {
SOURCE:"application/vnd.google-apps.script+json",
SCRIPT:"application/vnd.google-apps.script",
FOLDER:"application/vnd.google-apps.folder",
AUDIO:"application/vnd.google-apps.audio",
DOCUMENT:"application/vnd.google-apps.document",
DRAWING:"application/vnd.google-apps.drawing",
FILE:"application/vnd.google-apps.file",
FORM:"application/vnd.google-apps.form",
PHOTO:"application/vnd.google-apps.photo",
PRESENTATION:"application/vnd.google-apps.presentation",
SITES:"application/vnd.google-apps.sites",
FUSIONTABLE:"application/vnd.google-apps.fusiontable",
SPREADSHEET:"application/vnd.google-apps.spreadsheet",
UNKNOWN:"application/vnd.google-apps.unknown",
VIDEO:"application/vnd.google-apps.video",
gadget:"application/xml",
xml:"text/xml",
json:"application/json"
}
};
ns.getShortMime = function (mimeType) {
var f = Object.keys(ENUMS.MIMES).filter(function(k) {
return ENUMS.MIMES[k] === mimeType;
});
return f.length ? f[0].toLowerCase() : mimeType.toLowerCase();
};
// for handling advanced services
ns.ads = (function (ads) {
/**
* get files by name
* @param {string} parentId the parentId
* @param {string} name the name
* @param {string} optMime the mime type
* @param {string} optFields the fields to return
*/
ads.getFilesByName = function (parentId, name , optMime, optFields) {
return ads.getChildItems (parentId, optMime , optFields || "items/id" , "title='" + name + "'" + " and mimeType!='" + ENUMS.MIMES.FOLDER + "'" );
};
ads.getFoldersByName = function (parentId, name , optFields) {
return ads.getChildFolders (parentId, optFields || "items/id" , "title='" + name + "'");
};
ads.getChildFiles = function (parentId, optMime, optFields , optExtraQueries) {
return ads.getChildItems (parentId, optMime , optFields || "items/id" , "mimeType!='" + ENUMS.MIMES.FOLDER + "'" );
};
/**
* get child folders
* @param {string} parentId the id of the parent
* @param {string} optFields the fields to return
* @param {Array.string} optExtraQueries
*/
ads.getChildFolders = function (parentId, optFields, optExtraQueries) {
return ads.getChildItems(parentId , ENUMS.MIMES.FOLDER , optFields || "items/id", optExtraQueries) ;
};
/**
* get child items
* @param {string} parentId the id of the parent
* @param {ENUM.MIMES} optMime the mime type
* @param {string} optFields the fields to return
* @param {Array.string} optExtraQueries
*/
ads.getChildItems = function (parentId,mime,optFields,optExtraQueries) {
// add the folder filter
var q= mime ? ["mimeType='" + mime + "'"] : [];
// dont include anything deleted
q.push("trashed=false");
//plus any extra queries
if(optExtraQueries) {
var e = Array.isArray(optExtraQueries) ? optExtraQueries : [optExtraQueries];
Array.prototype.push.apply (q,e);
}
var options= {};
if (optFields) {
options.fields = optFields;
}
if(options.fields && options.fields.indexOf("nextPageToken") === -1) options.fields = (options.fields ? options.fields + "," : "") + "nextPageToken";
options.q = q.join(" and ");
var items =[] , pageToken;
do {
var result = Utils.expBackoff(function() {
return ns.service.Children.list(parentId,options);
},{ logAttempts:false});
pageToken = result.nextPageToken;
Array.prototype.push.apply(items , result.items);
options.pageToken = pageToken;
} while (pageToken);
return items;
};
/**
* return a folder id from a path like /abc/def/ghi
* @param {string} path the path
* @param {boolean} [create=false] create it
* @return {object} {id:'xxxx'} or null
*/
ads.getFolderFromPath = function (path) {
return (path || "/").split("/").reduce ( function(prev,current) {
if (prev && current) {
// this gets the folder with the name of the current fragment
var fldrs = ads.getFoldersByName(prev.id,current);
return fldrs.length ? fldrs[0] : null;
}
else {
return current ? null : prev;
}
},ns.rootFolder);
};
return ads;
})({});
/**
* to keep this namespace dependency free
* this must be run to set the driveappservice before it can be used
* @param {driveapp} dap the driveapp
* @return {DriveUtils} self
*/
ns.setService = function (dap) {
ns.service = dap;
if (ns.isDriveApp()) {
ns.rootFolder = Utils.expBackoff ( function () {
return ns.service.getRootFolder();
});
ns.rootFolderId = ns.rootFolder.getId();
}
else {
ns.rootFolder = ns.getFolderById ('root');
ns.rootFolderId = ns.rootFolder.id;
}
return ns;
};
/**
* whether we are using driveapp
* @return {bool} whether we are using driveapp
*/
ns.isDriveApp = function () {
ns.checkService();
return typeof ns.service.continueFolderIterator === 'function';
};
ns.checkService = function () {
if(!ns.service) {
throw 'please do a DriveUtils.setService (yourdriveapp) to inialie namespace';
}
};
ns.getFolders = function (parent) {
if (ns.isDriveApp()) {
return parent.getFolders();
}
else {
return ns.ads.getChildFolders (parent.id);
}
};
ns.getFiles = function (parent,mime) {
if (ns.isDriveApp()) {
return mime ? ns.service.getFilesByType (mime) : parent.getFiles();
}
else {
return ns.ads.getChildFiles (parent.id, mime);
}
};
ns.getFileById = function (id) {
try {
return Utils.expBackoff ( function () {
if (!ns.isDriveApp()) {
return ns.service.Files.get(id,{fields:"id,title"});
}
else {
return ns.service.getFileById(id);
}
},{logAttempts:false});
}
catch (err) {
return null;
}
}
ns.getFolderById = function (path) {
try {
return Utils.expBackoff ( function () {
if (!ns.isDriveApp()) {
return ns.service.Files.get(path,{fields:"id,title"});
}
else {
return ns.service.getFolderById (path);
}
},{logAttempts:false});
}
catch (err) {
return null;
}
}
/**
* get all the files as an array from a folder path
* @param {string} path the path to the start folder
* @param {string} [mime] the mime type
* @param {boolean} [recurse=false] whether to recurse
* @return {[files]} an array of files
*/
ns.getPileOfFiles = function ( path , mime , recurse ) {
var pile, startFolder;
// first check if the path is an id or a path
startFolder = ns.getFolderById (path) || ns.getFolderFromPath (path) ;
if (!startFolder) {
throw 'folder path/id ' + path + ' not found';
}
// if opened successfully, then get all the files
if (startFolder) {
pile = (recurse ? recurseFolders ( startFolder,mime ) : pileFiles (startFolder,mime));
}
return pile;
/**
* get all the files in this and child folders
* @param {folder} folder where to start
* @param {string} [mime] the mime type
* @param {[files]} [pile] the growing pike of files
* @return {[files]} the growing pike of files
*/
function recurseFolders (folder, mime, pile) {
// get the folders from the next level
var it = ns.getFolders(folder);
if (ns.isDriveApp () ) {
while (it.hasNext()) {
pile = recurseFolders (it.next() , mime , pile);
}
}
else {
it.forEach(function(d) {
pile = recurseFolders (d , mime , pile)
});
}
// collect from this folder
return pileFiles(folder, mime, pile);
}
/**
* get all the files in this folder
* @param {folder} folder where to start
* @param {string} [mime] the mime type
* @param {[files]} [pile] the growing pike of files
* @return {[files]} the growing pike of files
*/
function pileFiles (folder, mime , pile) {
var pile = pile || [];
Array.prototype.push.apply (pile, getFiles(folder,mime));
return pile;
}
/**
* get all the files in a gven folder
* @param {folder} folder where to start
* @param {string} [mime] the mime type
* @return {[files]} the files
*/
function getFiles (folder,mime) {
var files= [];
var it = ns.getFiles (folder , mime) ;
folderPath = ns.getPathFromFolder (folder);
if (ns.isDriveApp()) {
while (it.hasNext()) {
var file = it.next();
var fileName = file.getName();
files.push({
file:file,
folder:folder,
path:folderPath + fileName,
fileName:fileName,
id:file.getId()
});
}
}
else {
it.forEach(function(d) {
// need to get the file name
var fileName = ns.getFileById(d.id).title;
files.push({
file:d,
folder:folder,
path:folderPath + fileName,
fileName:fileName,
id:d.id
});
})
}
return files;
}
};
/**
* get the files from a path like /abc/def/hgh/filename
* @param {string} path the path
* @return {FileIterator} a fileiterator
*/
ns.getFilesFromPath = function (path) {
// get the filename and the path seperately
var s = path.split("/");
if (!s.length) {
return null;
}
var filename = s[s.length-1];
// the folder
var folder = ns.getFolderFromPath (
"/" + (s.length > 1 ? s.slice(0,s.length-1).join("/") : "")
);
if (ns.isDriveApp() ) {
return Utils.expBackoff ( function () {
return folder.getFilesByName (filename);
});
}
else {
return ns.ads.getFilesByName (folder.id , filename);
}
};
/**
* get a folder from a path like /abc/def/hgh
* @param {string} path the path
* @return {Folder} a folder
*/
ns.getFolderFromPath = function (path) {
// the drivapp way
if (ns.isDriveApp()) {
return (path || "/").split("/").reduce (
function(prev,current) {
if (prev && current) {
var fldrs = Utils.expBackoff ( function () {
return prev.getFoldersByName(current);
});
return fldrs.hasNext() ? fldrs.next() : null;
}
else {
return current ? null : prev;
}
},ns.rootFolder);
}
// the advanced service way
else {
return ns.ads.getFolderFromPath (path);
}
};
/**
* get a path like /abc/def/hgh from a folder
* @param {Folder} folder the folder
* @return {string} a path
*/
ns.getPathFromFolder = function ( folder ,optPath) {
ns.checkService();
if (!folder) return '';
var path = optPath || '/';
// we're done if we hit the root folder
return folder.getId() === ns.rootFolderId ? path : ns.getPathFromFolder (
folder.getParents().next() , '/' + folder.getName() + path
);
};
return ns;
}) (DriveUtils || {});