I changed the ownership of one of my google drive folders, but it still consumes from my storage - storage

My google drive storage is running out of space. So, in order to free some space, I created a new google account and transferred the ownership of one of the largest folders in my original drive (~7 GB) to the new account's drive.
The problem is, that after 3 days of waiting, the folder is still consuming the storage of the original account's drive. I made sure that the new account is the owner of the folder, but the problem is still there.
Any ideas?

The problem is that changing the ownership of folder inside google drive does not change it for the subfolders and files, you have to change them separately or write an app script to search for file and subfolders owned by you and change the ownership.
Run the script below as your account, if you are using Google Workspace and you are the admin and need to do it to other accounts, then you need to get a service account first and run the code below.
Note:
This way makes a lot of noise with notifications on both sides, the old owner and the new one.
function ChangeFileOwnership(folder){
// New owner
var new_owner = '<Add new owner email>';
if (folder == null) {
var folderObj = DriveApp.getFolderById('<ID of parent folder>');
return ChangeFileOwnership(folderObj);
}
var fileIt = folder.searchFiles('"me" in owners');
while (fileIt.hasNext()) {
var file = fileIt.next();
Logger.log("Changing ownership of " + file.getName() + " to " + new_owner);
// Set the owner to be the new owner
try {
file.addEditor(new_owner);
}
catch(err){
Logger.log(err.message);
}
try {
file.setOwner(new_owner);
}
catch(err){
Logger.log(err.message);
}
}
// Get all the sub-folders and iterate
var folderIt = folder.getFolders();
while (folderIt.hasNext()) {
fs = ChangeFileOwnership(folderIt.next());
}
}

Related

How to populate Documents folder at build time

I have an NativeScript 6.8 Javascript app that downloads newer data files. I'm discovering that on iOS I cannot create files within the app folder. (At least, in release builds; in debug builds I can.) I can change my code to read data files from the Documents folder, but how can I pre-populate the Documents folder at build time with the original data files? I'd rather not copy all the data files at run time.
Or, have I misinterpreted the restriction that files cannot be created in the app folder (or subfolders) in iOS release builds?
Live-updating files on iOS is more involved than one might expect. So, yes, you need to access the live-updated files from the Documents folder, not back the files up to iCloud, and handle numerous timing conditions, such as the live-update running just before what would seem to be the initial copy of the file to the Documents folder (seems unlikely, but I've seen it happen while testing).
I've included the function I developed, below. For context, when I find a file online to be live-updated, I use an appSetting to save the file's date as a string (storing as a value loses precision).
The function isn't perfect, but for now, it gets the job done. I call this from app.js in a NativeScript 6.8 JavaScript project.
/**
* Copy files in app/files folder to Documents folder so they can be updated
*/
async function copyFilesToDocuments() {
let filesCopied = appSettings.getBoolean("copyFilesToDocuments", false);
if (!filesCopied) { // only copy files on first invocation
let filesFolder = fs.knownFolders.currentApp().getFolder("files"); // Folder object
let documentsFolder = fs.knownFolders.documents(); // Folder object
let fileEntities = await filesFolder.getEntities();
for (entity of fileEntities) {
let sourceFile = fs.File.fromPath(entity.path);
let targetFilePath = fs.path.join(documentsFolder.path, entity.name);
let targetDate = parseInt(appSettings.getString(entity.name, "0"), 10); // live-update date or 0
if (fs.Folder.exists(targetFilePath) && targetDate > global.dataDate ) { // if file has been live-updated
console.log("app.js copyFilesToDocuments: file '" + entity.name + "' skipped to avoid overwrite. ");
continue; // don't overwrite newer file
}
appSettings.remove(entity.name); // remove any live-update timestamp
let targetFile = fs.File.fromPath(targetFilePath);
let content = await sourceFile.read();
try {
await targetFile.write(content);
if (platform.isIOS) {
// Prevent file from being backed up to iCloud
// See https://stackoverflow.com/questions/58363089/using-nsurlisexcludedfrombackupkey-in-nativescript
// See https://stackoverflow.com/questions/26080120/cfurlcopyresourcepropertyforkey-failed-because-passed-url-no-scheme
NSURL.fileURLWithPath(targetFilePath).setResourceValueForKeyError(true, NSURLIsExcludedFromBackupKey);
}
// console.log("app.js copyFilesToDocuments file copied: " + entity.name);
} catch(e) {
console.warn("app.js copyFilesToDocuments error: " + e);
//TODO: app will fail at this point with some files not found :-(
} // end catch
} // end for
appSettings.setBoolean("copyFilesToDocuments", true);
} // end files not yet copied
} // end copyFilesToDocuments

Is it possible to insert an image into a Google Sheets spreadsheet using a formula and Drive file path?

Google Drive files are shared out via a unique (and random) URL when uploaded. Is there a way to upload an image via a Sheets formula that uses the file path of the image, NOT the sharing URL?
Instead of using: https://drive.google.com/file/(sharing link)
The formula would use something like: Drive/Test/img.png or Drive/Test/img.gif
I have noticed that within the help for the IMAGE function in Google Sheets it explicitly states that you cannot use images hosted at drive.google.com but I'd like to know if there's another way to accomplish this.
Unfortunately this isn’t possible. As Google Drive supports the existence of multiple files with the same name in the same folder, a file path isn’t enough to uniquely identify a file and so the file ID is required regardless of whether it’s ‘file path’ is unique or not.
If you want to get a specific image in a specific folder, you will have to explore your drive as multiple folders and multiple files can have the same name.
function listOfFilesOfFolder() {
var myFolder = 'yourFolder';
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('yourSheet');
sh.clear();
sh.appendRow(["name", "date", "URL", "id", "type"]);
var folders = DriveApp.getFoldersByName(myFolder)
var foldersnext = folders.next();
var data = [];
var files = foldersnext.getFiles();
while (files.hasNext()) {
var file = files.next();
data = [
file.getName(),
file.getLastUpdated(),
file.getUrl(),
file.getId(),
file.getMimeType()
];
sh.appendRow(data);
}
sh.getRange('F1').setFormula(`={"image";arrayformula(if(D2:D="",,if(left(E2:E,5)="image",IMAGE("https://docs.google.com/uc?export=view&id="&D2:D),)))}`)
}

Roxy Fileman and Virtual Directorys

I have a solution with 2 projects in, one called "admin", the other say "work" (an Umbraco instance)
- Work has an images folder which contains the images for the site
banners/thumnails etc.
- Admin allows an admin user to add new stories, with images, using TinyMCE
and the fileman plug in.
So in IIS I created a virtual folder in Admin which points to the images folder in work, however when I try and browse the folder in fileman it repeats lots of sub directoriers and doesnt display any images.And I cannot upload any images either, it just gives me an error.
The Files_Root entry is as follows within the conf.json file.
"FILES_ROOT": ".//images//",
So how do I get this virtual folder to work with fileman?
I stumbled upon this problem as well - when the FILES_ROOT points to a virtual folder in IIS, the Fileman component chokes when trying to retrieve the list of files, and when uploading, and maybe some other places. The requests don't pass the folder location properly when it references a virtual directory. If you put a network sniffer on it, you'll see the requests sent to fileman/asp_net/main.ashx and the responses that come back with the error "The given path's format is not supported."
I've reported the bug to the author via the website, but I have also discovered that if you replace the virtual directory with a SYMLINK, everything seems to work.
If you have IIS access, you probably have command line access to create the symlink, which can be done as:
mklink /j "{virtual location within your website}" "{physical location}"
Both locations should be full paths, including drive letters and the "virtual" location should be in your website root.
So far, I have not seen an problems referencing files this way instead of with a virtual directory, other than that my site backups started including the files in the symlink, since the O/S sees that as a physical folder within the site now.
I hope this helps!!
Probably not good for every situation (maybe not even for the user that asked the question), but figured I would share in case it might help someone trying to get virtual directories mapped to network shares working. I needed to modify the ListDirTree function in file fileman/asp_net/main.ashx
protected void ListDirTree(string type)
{
string filesRoot = GetFilesRoot();
DirectoryInfo d = new DirectoryInfo( filesRoot );
if ( !d.Exists )
throw new Exception( "Invalid files root directory. Check your configuration: " + filesRoot );
ArrayList dirs = ListDirs( d.FullName );
dirs.Insert( 0, d.FullName );
string localPath = _context.Server.MapPath( "~/" );
bool isLocal = filesRoot.Contains( ":" );
_r.Write( "[" );
for ( int i = 0; i < dirs.Count; i++ )
{
string dir = (string)dirs[i];
string lPath;
//If it is a local path, leave it as it was
if ( isLocal )
lPath = dir.Replace( localPath, "" ).Replace( "\\", "/" );
else
//Otherwise probably a virtual directory, put the original files_root location back
lPath = dir.Replace( filesRoot, GetSetting( "FILES_ROOT" ) ).Replace( "\\", "/" );
_r.Write( "{\"p\":\"/" + lPath + "\",\"f\":\"" + GetFiles( dir, type ).Count.ToString() + "\",\"d\":\"" + Directory.GetDirectories( dir ).Length.ToString() + "\"}" );
if ( i < dirs.Count - 1 )
_r.Write( "," );
}
_r.Write( "]" );
}

Save spreadsheet in a Specific Folder of GDrive

I need help with this Google AdWords script: https://developers.google.com/adwords/scripts/docs/solutions/keyword-performance.
Every time I run this script in Google AdWords account (for my PPC campaign), it creates report (spreadsheet) and save it on my google drive.
I would like to save spreadsheet file to specific subfolder on my google drive (for example Report/Campaign01). I found the article which describes how to save spreadsheet to specific folder. But I don't know how edit this script and use it. Article describing this function is here:
http://www.freeadwordsscripts.com/2014/07/save-file-or-spreadsheet-in-specific.html
Can you help me solve the problem?
Assuming your folder and file names are unique, use can save to a folder this way
function myFunction() {
var folderIterator = DriveApp.getFoldersByName("YOUR_FOLDER_NAME");
while ( folderIterator.hasNext() ) {
var folder = folderIterator.next();
folder_count++;
var spreadsheet = SpreadsheetApp.create("YOUR_SPREADSHEET_NAME");
// INSERT YOUR SPREADSHEET LOGIC HERE.
// YOU CAN CREATE YOUR SHEET HOWEVER YOU WANT,
// SO LONG AS YOU HAVE YOUR ACTIVE SPREADSHEET OBJECT.
// EITHER WAY, IT WILL SAVE TO YOUR ROOT DIRECTORY.
// THIS LOGIC MOVES YOUR FILE BY ID FROM ROOT TO YOUR SELECTED FOLDER.
var files = DriveApp.getRootFolder().getFilesByName("YOUR_SPREADSHEET_NAME");
while ( files.hasNext() ) {
var file = files.next();
if ( spreadsheet.getId() == file.getId() ) {
Logger.log("Found File! Moving...");
folder.addFile(file);
DriveApp.getRootFolder().removeFile(file);
} else {
Logger.log("Wrong File, id[%s]" , file.getId());
}
}
}
}

TFS 2010 API: Get old name/location of renamed/moved item

I'm writing an application that pulls changesets from TFS and exports a csv file that describes the latest changes for use in a script to push those changes into ClearCase. The "latest" doesn't necessarily mean the latest, however. If a file was added and then edited, I only need to know that the file was added, and get the latest version so that my script knows how to properly handle it. Most of this is fairly straight-forward. I'm getting hung up on files that have been renamed or moved, as I do not want to show that item as being deleted, and another item added. To uphold the integrity of ClearCase, I need to have in the CSV file that the item is moved or renamed, along with the old location and the new location.
So, the issue I'm having is tracing a renamed (or moved) file back to the previous name or location so that I can correlate it to the new location/name. Where in the API can I get this information?
Here is your answer:
http://social.msdn.microsoft.com/Forums/en/tfsgeneral/thread/f9c7e7b4-b05f-4d3e-b8ea-cfbd316ef737
Using QueryHistory you can find out that an item was renamed, then using its previous changeset (previous to the one that says it was renamed) you can find its previous name.
You will need to use VersionControlServer.QueryHistory in a manner similar to the following method. Pay particular attention to SlotMode which must be false in order for renames to be followed.
private static void PrintNames(VersionControlServer vcs, Change change)
{
//The key here is to be sure Slot Mode is enabled.
IEnumerable<Changeset> queryHistory =
vcs.QueryHistory(
new QueryHistoryParameters(change.Item.ServerItem, RecursionType.None)
{
IncludeChanges = true,
SlotMode = false,
VersionEnd = new ChangesetVersionSpec(change.Item.ChangesetId)
});
string name = string.Empty;
var changes = queryHistory.SelectMany(changeset => changeset.Changes);
foreach (var chng in changes)
{
if (name != chng.Item.ServerItem)
{
name = chng.Item.ServerItem;
Console.WriteLine(name);
}
}
}
EDIT: Moved the other solution up. What follows worked when I was testing against a pure Rename change but broke when I tired against a Rename and Edit change.
This is probably the most efficient way to get the previous name. While it works (TFS2013 API against as TFS2012 install), it look like a bug to me.
private static string GetPreviousServerItem(VersionControlServer vcs, Item item)
{
Change[] changes = vcs.GetChangesForChangeset(
item.ChangesetId,
includeDownloadInfo: false,
pageSize: int.MaxValue,
lastItem: new ItemSpec(item.ServerItem, RecursionType.None));
string previousServerItem = changes.Single().Item.ServerItem;
//Yep, this passes
Trace.Assert(item.ServerItem != previousServerItem);
return previousServerItem;
}
it would be used like:
if (change.ChangeType.HasFlag(ChangeType.Rename))
{
string oldServerPath = GetPreviousServerItem(vcs, change.Item);
// ...
}

Resources