/// <summary> /// Helper method for AddExternalFiles(). 'curLoc' must end with a /// delimiter when non-empty. /// </summary> private void AddExternalFilesRecursive(String curLoc, String[] srcArray, List<String> copySrc, List<String> copyDst, SortedSet<String> uploadFileSet, SortedSet<String> uploadDirSet, bool topLevelFlag, ref GateConfirmActions defaultActions) { // Pass every source. foreach (String srcFullPath in srcArray) { // Extract the source path information. String srcName = KfsPath.BaseName(srcFullPath); String destRelPath = curLoc + srcName; String destFullPath = Share.MakeAbsolute(destRelPath); // Get the local and destination path types. GatePathType srcType = GetExternalPathType(srcFullPath); GatePathType destType = GetInternalPathType(destRelPath); // The information is stale, abort. if (srcType == GatePathType.None) throw new GateSyncException(); if (destType == GatePathType.Stale) throw new GateSyncException(); // There is a type conflict. Skip the source. if (destType != GatePathType.None && srcType != destType) { String prompt = "The file or directory " + destRelPath + " conflicts with a file or directory on the server."; ShowChoiceDialog(prompt, "sc", ref defaultActions.typeConflictAction); continue; } // The file is being transferred. Skip it. if (Share.IsTransferringFile(destRelPath)) { String prompt = "The file " + destRelPath + " is already being transferred."; ShowChoiceDialog(prompt, "sc", ref defaultActions.inTransferAction); continue; } // The source is a file. if (srcType == GatePathType.File) { KfsServerFile f = Share.ServerView.GetObjectByPath(destRelPath) as KfsServerFile; // The destination does not exist. if (f == null || f.IsGhost()) { // Void. } // Someone is already uploading the file. Skip the source or // clobber the destination. else if (!f.UploaderSet.IsEmpty) { String prompt = "The file " + destRelPath + " is being uploaded by another user."; String res = ShowChoiceDialog(prompt, "swc", ref defaultActions.otherUploadAction); if (res == "s") continue; } // The destination already exists. Skip the source or overwrite // the destination. else if (topLevelFlag && destType == GatePathType.File) { String prompt = "The file " + destRelPath + " already exists."; String res = ShowChoiceDialog(prompt, "swc", ref defaultActions.fileExistsAction); if (res == "s") continue; } // FIXME move this to another thread, eventually. // LB: not sure this is a good idea: there are sync issues. // ADJ: Using the Shell to do the copy seems good enough for now. // Copy the file in the share. if (File.Exists(destFullPath)) File.SetAttributes(destFullPath, FileAttributes.Normal); copySrc.Add(srcFullPath); copyDst.Add(destFullPath); // Add the file to the file set. uploadFileSet.Add(destRelPath); } // The source is a directory. else { // The destination directory does not exist. if (destType == GatePathType.None) { // Create the destination directory. Directory.CreateDirectory(destFullPath); } // The directory already exists. else if (topLevelFlag) { // Skip or overwrite the directory. String prompt = "This folder already contains a folder named '" + destRelPath + "'." + Environment.NewLine + "If the files in the existing folder have the same name as files in the folder you are adding, they will be replaced. Do you still want to add this folder?"; String res = ShowChoiceDialog(prompt, "swc", ref defaultActions.dirExistsAction); if (res == "s") continue; } // Add the directory to the directory set. uploadDirSet.Add(destRelPath); // Add the files and directories contained in the source directory. String[] subArray = Directory.GetFileSystemEntries(srcFullPath); AddExternalFilesRecursive(destRelPath + "/", subArray, copySrc, copyDst, uploadFileSet, uploadDirSet, false, ref defaultActions); } } }
/// <summary> /// Add external files to the share. /// </summary> /// <param name="destRelPath">Relative path to the destination directory</param> /// <param name="toAdd">Explicit list of the items to add. Pass null to prompt the user for files or a directory.</param> /// <param name="addDir">True to prompt for a directory instead of files.</param> public void AddExternalFiles(String destRelPath, string[] toAdd, bool addDir, GateConfirmActions defaultActions) { GateEntry("AddExternalFiles"); // Disallow all user operations until the pipeline stabilized. Share.DisallowUserOp("AddExternalFiles() called", AllowedOpStatus.None); try { // Get the sets of directories and files to add. SortedSet<String> fileSet = new SortedSet<String>(); SortedSet<String> dirSet = new SortedSet<String>(); List<String> copySrc = new List<string>(); List<String> copyDst = new List<string>(); // Make sure the destination still exists. if (GetInternalPathType(destRelPath) != GatePathType.Dir) throw new GateSyncException(); String[] srcArray = null; if (toAdd == null) { if (addDir) { // Prompt the user for the directories to add. srcArray = ShowSelectFolderDialog(Share.MakeAbsolute(destRelPath)); } else { // Prompt the user for the files to add. srcArray = ShowSelectMultiFileDialog(Share.MakeAbsolute(destRelPath)); } } else { srcArray = toAdd; } // If someting in srcArray is a parent folder of destRelPath, deny the Add. foreach (string p in srcArray) { if (Directory.Exists(p) && KfsPath.GetWindowsFilePath(Share.MakeAbsolute(destRelPath), true).StartsWith(p)) { throw new GateIllegalException("Cannot add " + Path.GetFileName(p) + ": The destination folder is a subfolder of the source folder."); } } // Add the missing local directories. Share.AddMissingLocalDirectories(destRelPath); // Add the missing server directories. dirSet.Add(destRelPath); // Handle the sources selected. AddExternalFilesRecursive(KfsPath.AddTrailingSlash(destRelPath), srcArray, copySrc, copyDst, fileSet, dirSet, true, ref defaultActions); if (!Misc.CopyFiles(copySrc, copyDst, true, true, false, false, false, true)) return; // Add the files and directories. AddFilesCommon(fileSet, dirSet); } catch (Exception ex) { HandleException(ex); } GateExit("AddExternalFiles"); }
/// <summary> /// Handle the result of the SKURL query. /// </summary private void HandleSkurlQueryResult(KasQuery query) { if (!CheckCtx(KwmCoreKwsOpStep.KasSkurl)) return; try { AnpMsg res = query.Res; AppKfs appKfs = (AppKfs)m_kws.AppTree[KAnpType.KANP_NS_KFS]; // Handle failures. if (res.Type != KAnpType.KANP_RES_KWS_UURL) throw Misc.HandleUnexpectedKAnpReply("get SKURL", res); // Get the SKURL. string skurl = res.Elements[0].String; // Get the date. DateTime attachDate = Base.KDateToDateTimeUTC(res.Elements[1].UInt64); if (m_attachFile.Count > 0) { string attachDest = GetAttachmentDirectory(attachDate); string workDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); string attachDir = Path.Combine(workDir, attachDest); string sourceDir = ""; List<string> externalFiles = new List<string>(); try { // Create the directory structure we are going to upload // on the KCD. Directory.CreateDirectory(attachDir); // This assumes that all files provided by Outlook will // come from the same directory, which is a more than reasonable // assumption considering that it's programmed to do just that. sourceDir = Path.GetDirectoryName(m_attachFile[0]); // Move the Outlook attachments inside that structure. foreach (string externalFile in m_attachFile) { string ef = Path.Combine(attachDir, Path.GetFileName(externalFile)); File.Move(externalFile, ef); } // Check if the directory where Outlook put its attachments is // empty and if so delete it. if (sourceDir != null) { if (Directory.GetFiles(sourceDir).Length == 0) Directory.Delete(sourceDir); } string[] dirs = Directory.GetDirectories(workDir, "*", SearchOption.TopDirectoryOnly); // The "Attachments" directory will already exists and it's no big deal // so make sure we don't get a prompt about it. GateConfirmActions confirmActions = new GateConfirmActions(); confirmActions.dirExistsAction = "o"; appKfs.Share.Gate.AddExternalFiles("", dirs, false, confirmActions); Logging.Log(2, "About to notify user of a file upload"); Wm.UiBroker.NotifyUser(new AttachManagementNotificationItem(m_kws, m_outlookRequest.Cmd)); } finally { // We can remove our work directory now. Directory.Delete(workDir, true); } } // Send the reply. AnpMsg rep = m_outlookRequest.MakeReply(OAnpType.OANP_RES_GET_SKURL); rep.AddString(skurl); m_outlookRequest.SendReply(rep); // We're done. CleanUpOnDone(true); } catch (Exception ex) { HandleMiscFailure(ex); } }