/// <summary> /// TODO /// </summary> /// <param name="FileData"></param> /// <returns></returns> public async Task <long> UploadNewFile(UploadFileData FileData) { var itemLength = new FileInfo(FileData.File.Name).Length; var totalBytes = Utility.BytesToString(itemLength); var filename = Path.GetFileName(FileData.File.Name); var fileUpload = new FileUpload(); fileUpload.AllowDuplicate = false; fileUpload.ParentId = FileData.ParentItem.Id; fileUpload.FileName = filename; fileUpload.StreamOpener = () => new FileStream(FileData.File.Name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true); fileUpload.Progress = (long position) => { FileData.PauseEvent.WaitOne(); FileData.Form.Activity = Progress.GetActivityProgress( FileData.File.Name, position, itemLength, FileData.TotalProgress + position, FileData.TotalSize, FileData.TimestampStartOne, FileData.TimestampStartTotal ); FileData.Form.SetProgressValue(FileData.TotalProgress + position, FileData.TotalSize); return(position); }; var cs = new CancellationTokenSource(); var token = cs.Token; fileUpload.CancellationToken = token; FileData.Form.Canceled += (object sender, EventArgs e) => { cs.Cancel(true); }; var result = await amazon.Files.UploadNew(fileUpload); foreach (var node in result.metadata) { CacheStorage.AddItem(FSItem.FromNode(Path.Combine(FileData.ParentItem.Path, filename), node)); if (node.size != null) { FileData.TotalProgress += node.size.Value; } } return(FileData.TotalProgress /*+ node.Length*/); }
/// <summary> /// TODO /// </summary> /// <param name="item"></param> /// <param name="newParentNode"></param> /// <returns></returns> public async Task <bool> MoveFile(FSItem item, FSItem newParentNode) { if (newParentNode == null) { return(false); // TODO: throw an exception } if (!newParentNode.IsDir) { return(false); // TODO: throw an exception } await amazon.Nodes.Move(item.Id, newParentNode.Id, item.IsDir); CacheStorage.RemoveItem(item); CacheStorage.RemoveItems(newParentNode.Path); return(true); }
/// <summary> /// TODO /// </summary> /// <param name="itemPath"></param> /// <param name="CacheBypass"></param> /// <returns></returns> public async Task <FSItem> FetchNode(string itemPath, bool CacheBypass = false) { FSItem item = null; if (!CacheBypass) { item = CacheStorage.GetItemByPath(itemPath); } if (item != null) { return(item); } if (itemPath == string.Empty) { itemPath = "\\"; } AmazonNode node; // try as a directory node = await amazon.Nodes.GetNodeByPath(itemPath, true); if (node == null) { // try as a file node = await amazon.Nodes.GetNodeByPath(itemPath, false); if (node == null) { return(null); } } item = FSItem.FromNode(itemPath, node); CacheStorage.AddItem(item); return(item); }
public override bool UIKeyPressed(KeyInfo key) { if (key == null) { throw new ArgumentNullException("key"); } UserWants = UserAction.None; try { switch (key.VirtualKeyCode) { case KeyCode.Enter: if (key.Is()) { //Far.Api.ShowError("Not implemented", new NotImplementedException("Not implemented: "+ CurrentFile.Name)); FarFile file = CurrentFile; if (file == null) { break; } UserWants = UserAction.Enter; if (file.IsDirectory && !IgnoreDirectoryFlag) { break; } var cancellation = new CancellationTokenSource(); var _cancel = cancellation.Token; //var ptask = new ProgressTask("test", "test-title", _cancel); //var form = ptask.ShowDialog(); //Thread.Sleep(3000); //cancellation.Cancel(); //form.Complete(); UIOpenFile(file); return(true); } if (key.IsShift()) { UIAttributes(); return(true); } break; case KeyCode.F1: if (key.Is()) { UIHelp(); return(true); } break; case KeyCode.F3: if (key.Is()) { if (CurrentFile == null) { UIExploreLocation(null); //UIViewAll(); return(true); } /* * if (CurrentFile.IsDirectory) * { * Explorer.CanExploreLocation = true; * break; * } * * Explorer.CanExploreLocation = false; */ break; } if (key.IsShift()) { //ShowMenu(); return(true); } break; /* * case KeyCode.F5: * * if (key.Is()) * { * if (CurrentFile == null) * { * //UIViewAll(); * return true; * } * * Log.Source.TraceInformation("Tried to copy this file: {0}\\{1}", CurrentLocation, CurrentFile.Name); * * Log.Source.TraceInformation("Far.Api.Panel2.IsPlugin = {0}", Far.Api.Panel2.IsPlugin ? "true" : "false"); * Log.Source.TraceInformation("Far.Api.Panel2.CurrentFile = {0}", Far.Api.Panel2.CurrentFile); * Log.Source.TraceInformation("Far.Api.Panel2.CurrentDirectory = {0}", Far.Api.Panel2.CurrentDirectory); * * if (Far.Api.Panel2.IsPlugin) * { * // How to copy files to plugins?? * return true; * } * * if (Far.Api.Panel2.CurrentDirectory == null) * { * // how can it be? * return true; * } * * var item = ((CurrentFile.Data as Hashtable)["fsitem"] as FSItem); * var path = Path.Combine(Far.Api.Panel2.CurrentDirectory, item.Name); * * var form = new Tools.ProgressForm(); * form.Activity = "Downloading..."; * form.Title = "Amazon Cloud Drive - File Download Progress"; * form.CanCancel = true; * form.SetProgressValue(0, item.Length); * form.Canceled += (object sender, EventArgs e) => * { * form.Close(); * }; * * Task task = (Explorer as ACDExplorer).Client.DownloadFile(item, path, form); * var cs = new CancellationTokenSource(); * var token = cs.Token; * / * * token.Register(() => * { * form.Close(); * });* / * var _task = Task.Factory.StartNew(() => * { * form.Show(); * }, token); * task.Wait(); * * break; * } * * if (key.IsShift()) * { * //ShowMenu(); * return true; * } * * break; */ case KeyCode.PageDown: if (key.IsCtrl()) { UIOpenFileMembers(); return(true); } break; case KeyCode.A: if (key.IsCtrl()) { UIAttributes(); return(true); } break; case KeyCode.G: if (key.IsCtrl()) { UIApply(); return(true); } break; case KeyCode.M: if (key.IsCtrlShift()) { UIMode(); return(true); } break; case KeyCode.S: //! Mantis#2635 Ignore if auto-completion menu is opened if (key.IsCtrl() && Far.Api.Window.Kind != WindowKind.Menu) { SaveData(); return(true); } break; case KeyCode.R: if (key.IsCtrl()) { CacheStorage.RemoveItems(Far.Api.Panel.CurrentDirectory); } break; } // base return(base.UIKeyPressed(key)); } finally { UserWants = UserAction.None; } }
/// <summary> /// TODO /// </summary> /// <param name="item"></param> /// <param name="newName"></param> /// <returns></returns> public async Task <bool> RenameFile(FSItem item, string newName) { if (!Utility.IsValidPathname(newName)) { return(false); // TODO: throw an exception } // 1. Is newName a folder? // var newParentNode = await FetchNode(newName); // if (newParentNode != null) // { // return await MoveFile(item, newParentNode); // } // 2. Is newName a file in the same dir? var destination = Path.GetDirectoryName(newName); // 2.1 Is destination empty? (means that the file is in the current folder) if (destination == "") { CacheStorage.RemoveItems(item.Dir); // invalidate parent path await amazon.Nodes.Rename(item.Id, newName, item.IsDir); return(true); } // 2.1.1 If destination (destination) node does not exist or is not a directory, we should fail var destinationNode = await FetchNode(destination); if (destinationNode == null || !destinationNode.IsDir) { return(false); // TODO: throw exception } // 2.2 Is destination the same as the directory name of the item? var filename = Path.GetFileName(newName); if (filename == "") { filename = item.Name; } if (destination == item.Dir) { // cannot rename to myself if (filename == item.Name) { return(true); } CacheStorage.RemoveItems(item.Dir); // invalidate parent path await amazon.Nodes.Rename(item.Id, filename, item.IsDir); return(true); } // 3. Is newName is another folder AND filename? (the only remaining option) // Here we have 2 problems (because of no way to move and rename atomically): // 1) If we first rename and then move, then it might happen so that there is a file with the same name in the current folder // 2) Similar problem can be if first move and then rename // Solution? We have it. // 1) We should first rename to something unique (say, filename.randomstr.ext) and most likely we will not get a conflict // 2) We move the file with this unique name // 3) We _try_ to rename back to the original name // 4) If we fail, we add (2), (3), (n) to the filename (i.e.: filename (n).ext) // 5) If we still fail, we at least have the same file with the randomstr in the filename var filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename); var extension = Path.GetExtension(filename); var randomString = Utility.RandomString(8); var tmpFilename = string.Format("{0}.{1}.{2}", filenameWithoutExtension, randomString, extension); // 3.1 Rename to a temporary name await amazon.Nodes.Rename(item.Id, tmpFilename, item.IsDir); // 3.2 Move to the new destination await amazon.Nodes.Move(item.Id, destinationNode.Id, item.IsDir); // 3.3 Rename back to the original name await amazon.Nodes.Rename(item.Id, filename, item.IsDir); // TODO: catch exceptions and try to rename again CacheStorage.RemoveItems(item.Dir); // invalidate parent path CacheStorage.RemoveItems(destinationNode.Path); // invalidate new parent path return(true); }
/// <summary> /// TODO /// </summary> /// <param name="filePath"></param> /// <param name="parent"></param> /// <param name="allowExisting"></param> /// <returns></returns> public async Task <FSItem> CreateDirectory(string filePath, FSItem parent = null, bool allowExisting = true) { if (filePath == "\\" || filePath == ".." || filePath == ".") { return(null); } var dir = Path.GetDirectoryName(filePath); if (dir == ".." || dir == ".") { return(null); } if (parent == null) { parent = await FetchNode(dir); if (parent == null) { return(null); } } var name = Path.GetFileName(filePath); AmazonNode node = null; try { node = await amazon.Nodes.CreateFolder(parent.Id, name); } catch (Azi.Tools.HttpWebException x) { if (x.StatusCode == System.Net.HttpStatusCode.Conflict) { if (!allowExisting) { throw; } } else { throw; } } if (node == null) // in case of duplicate; other cases are re-thrown { node = await amazon.Nodes.GetNodeByPath(filePath, true); } if (node == null) { throw new InvalidOperationException("Could not retrieve node information " + filePath); } var item = FSItem.FromNode(filePath, node); CacheStorage.AddItem(item); return(item); }