/// <summary> /// Remove the specified download. /// </summary> private void RemoveDownload(KfsFileDownload f) { InodeTree.Remove(f.Version.Inode); OrderTree.Remove(f.OrderID); if (DoneTree.ContainsKey(f.OrderID)) DoneTree.Remove(f.OrderID); Share.UnregisterFileTransfer(f); }
/// <summary> /// Add the file download to the list of errors, unless 'reason' is null. /// </summary> public void ReportError(String reason, KfsFileDownload f) { if (reason != null) { f.Error = new KfsTransferError(TransferErrorType.Download, f, reason); Share.OnTransferError(f.Error); } }
/// <summary> /// Move a file in the share. /// </summary> public void MoveDownloadedFile(KfsFileDownload f) { try { // Get the corresponding server file. KfsServerFile s = Share.ServerView.GetObjectByInode(f.Version.Inode) as KfsServerFile; // The file has been deleted on the server. if (s == null) throw new Exception("cannot open file, it has been deleted on the server"); // Update the local status and check whether the move is safe. s.UpdateLocalStatus(); if (s.CurrentLocalStatus == LocalStatus.Error) throw new Exception("cannot open file: " + s.LocalError); if (s.CurrentLocalStatus == LocalStatus.Modified) throw new Exception("cannot update file: local copy has been modified"); // Create the missing parent directories, if possible. Share.AddMissingLocalDirectories(s.Parent.RelativePath); // Move the file at its proper location. if (File.Exists(s.FullPath)) File.SetAttributes(s.FullPath, FileAttributes.Normal); if (new FileInfo(f.CachePath).Length < 10 * 1024 * 1024) File.Copy(f.CachePath, s.FullPath, true); else if (!Misc.CopyFile(f.CachePath, s.FullPath, false, true, false, true, true)) throw new Exception("Unable to copy " + s.Name); // Update the downloaded version. s.UpdateDownloadVersion(f.Version, true); // Update the local status of the downloaded file. s.UpdateLocalStatus(); // Open the file for the user. if (f.OpenWhenDownloadedFlag) Misc.OpenFileInWorkerThread(s.FullPath); } catch (Exception ex) { ReportError(ex.Message, f); } finally { RemoveDownload(f); } }
/// <summary> /// Queue the download of the specified file version. The method checks /// if the file is already being downloaded. If the file has already been /// downloaded, the file is added to the DoneTree immediately. /// </summary> public void QueueDownload(KfsServerFileVersion version, bool openFlag) { // The download is already queued. if (InodeTree.ContainsKey(version.Inode)) { if (openFlag) InodeTree[version.Inode].OpenWhenDownloadedFlag = true; return; } // Queue the file download. UInt64 orderID = Share.TransferOrderID++; String relPath = Share.ServerView.GetObjectByInode(version.Inode).RelativePath; KfsFileDownload f = new KfsFileDownload(Share, orderID, relPath, version, openFlag); InodeTree[f.Version.Inode] = f; OrderTree[f.OrderID] = f; Share.RegisterFileTransfer(f); // The file is already in the cache. if (HasFullVersion(version)) { f.Status = FileTransferStatus.Batched; OnFileDownloadCompleted(f.OrderID); } // The file is empty. Create it immediately. else if (version.Size == 0) { Directory.CreateDirectory(Share.CacheDirPath); File.Create(VersionCachePath(version)).Close(); f.Status = FileTransferStatus.Batched; OnFileDownloadCompleted(f.OrderID); } }
/// <summary> /// Move a file in the share. /// </summary> public void MoveDownloadedFile(KfsFileDownload f) { try { // Get the corresponding server file. KfsServerFile s = Share.ServerView.GetObjectByInode(f.Version.Inode) as KfsServerFile; // The file has been deleted on the server. if (s == null) throw new Exception("cannot open file, it has been deleted on the server"); // Update the local status and check whether the move is safe. s.UpdateLocalStatus(); if (s.CurrentLocalStatus == LocalStatus.Error) throw new Exception("cannot open file: " + s.LocalError); if (s.CurrentLocalStatus == LocalStatus.Modified) throw new Exception("cannot update file: local copy has been modified"); // Create the missing parent directories, if possible. Share.AddMissingLocalDirectories(s.Parent.RelativePath); // Get the file information. UInt64 observedID, observedSize; DateTime observedDate; FileStream stream = null; try { stream = new FileStream(f.CachePath, FileMode.Open, FileAccess.Read); KfsPath.GetLowLevelFileInfo(stream, out observedID, out observedSize, out observedDate); } finally { if (stream != null) stream.Close(); } // Move the file at its proper location. File.Delete(s.FullPath); File.Move(f.CachePath, s.FullPath); // Update the downloaded version and the persistent status. s.UpdateDownloadVersion(f.Version, true); s.UpdatePersistentStatus(LocalStatus.Unmodified, observedDate, observedID, observedSize, f.Version.Hash); // Open the file for the user. if (f.OpenWhenDownloadedFlag) Misc.OpenFileInWorkerThread(s.FullPath); } catch (Exception ex) { ReportError(ex.Message, f); } finally { RemoveDownload(f); } }