/// <summary> /// Button Clean Library to clear library from the Hash column /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BtnClean_Click(object sender, RoutedEventArgs e) { //We update the UI this.IsEnabled = false; string libName = Cb_doclib.Text; //We create the context object and call the column supression method SPOLogic spo = new SPOLogic(Context); bool didClean = spo.cleanLibraryFromProcessing(libName); if (didClean) { MessageBox.Show("Library is clean"); } //We reactivate the UI this.IsEnabled = true; }
/// <summary> /// BackgroundWorker Work event: /// Retrive user info to retrive the SPO Site lists /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void bw_Dowork(object sender, DoWorkEventArgs e) { //We try to connect to the SharePoint Online site and retrieve the libraries try { using (var ctx = new ClientContext(SiteUrl)) { SharePointOnlineCredentials credentials = new SharePointOnlineCredentials(UserName, PassWord); ctx.Credentials = credentials; Web web = ctx.Web; ctx.Load(web, w => w.ServerRelativeUrl); this.Context = ctx; SPOLogic Context = new SPOLogic(ctx); //We check if the SPO site is a OneDrive Url, and process accordingly if (SiteUrl.Contains("/personal/")) { List odlists = ctx.Web.Lists.GetByTitle("Documents"); ctx.Load(odlists); ctx.ExecuteQuery(); this.ODLibrary = odlists; } //Else we have a SPO Site Url, and process accordingly else { ListCollection lists = Context.getLists(); this.Lists = lists; } } } catch (Exception ex) { MessageBox.Show(ex.Message); bw.CancelAsync(); e.Cancel = true; } }
/// <summary> /// BackgroundWorker Work event: /// Copy file and folders from the path selected to the target SharePoint Online library /// </summary> /// <param name="sender">Btn_Copy</param> /// <param name="e">OnClick()</param> private void bw_Dowork(object sender, DoWorkEventArgs e) { //[RESULT/LOG] We instanciate the repporting object Reporting repport = new Reporting(this.DocLib, this.Context.Web.ServerRelativeUrl); //[LOG:Verbose] We create the log object and log Local Path formating CopyLog log = new CopyLog(CopyLog.Status.Verbose, "Local path formating", LocalPath, ""); repport.writeLog(log); try { //We ensure the localpath endwith "/" for further formating actions if (!this.LocalPath.EndsWith("/") || !this.LocalPath.EndsWith("\\")) { this.LocalPath = this.LocalPath + "\\"; } //[LOG:OK] Local Path formating : Log success log.ActionStatus = CopyLog.Status.OK; repport.writeLog(log); //[LOG:Verbose] Local file retrieve log.update(CopyLog.Status.Verbose, "Local file retrieve", LocalPath, ""); repport.writeLog(log); //We retrive the list of DirectoryInfo and FileInfo List <FileInfo> files = FileLogic.getFiles(LocalPath); List <DirectoryInfo> folders = FileLogic.getSourceFolders(LocalPath); //[LOG:OK] Local file retrieve log.ActionStatus = CopyLog.Status.OK; repport.writeLog(log); //We instanciate the SPOLogic object to interact with SharePoint Online SPOLogic ctx = new SPOLogic(Context); //[LOG:Verbose] Checking library log.update(CopyLog.Status.Verbose, "Checking library", LocalPath, ""); repport.writeLog(log); //We enable Folder creation for the SharePoint Online library and ensure the Hash column exist bw.ReportProgress(0, "Checking Library"); List list = ctx.setLibraryReadyForPRocessing(this.DocLib); //[LOG:OK] Checking library log.ActionStatus = CopyLog.Status.OK; repport.writeLog(log); //[LOG:Verbose] Online ListItem retrieve log.update(CopyLog.Status.Verbose, "Online ListItem retrieve", LocalPath, ""); repport.writeLog(log); // We retrieve all listitems in the library bw.ReportProgress(0, "Retrieving ListItems"); List <ListItem> onlineListItem = ctx.GetAllDocumentsInaLibrary(this.DocLib); //[LOG:OK] Online ListItem retrieve log.ActionStatus = CopyLog.Status.OK; repport.writeLog(log); #region Folder Creation //[LOG:Title] Folder creation beggins log.update("[Starting Folder Creation process]"); repport.writeLog(log); var rootFolder = list.RootFolder; Context.Load(rootFolder); Context.ExecuteQuery(); //We set the index to display progression int i = 0; int count = 0; foreach (DirectoryInfo folder in folders) { //Progression display i++; double percentage = (double)i / folders.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Checking folders - {advancement}%\n{i}/{folders.Count}"); //We check for pending cancellation if (bw.CancellationPending == true) { //[LOG:CANCEL] Cancellation log log.update("[Process Cancelled]"); repport.writeLog(log); //We cancel the backgroundWorker and return e.Cancel = true; return; } //If no cancellation, we launch the copy folder process else { //[LOG:Verbose] Folder Creation log.update(CopyLog.Status.Verbose, "Folder creation", folder.FullName, ""); repport.writeLog(log); //We process the folder CopyStatus copyStatus = ctx.copyFolderToSPO(folder, list, LocalPath, onlineListItem); //[LOG:OK] Folder Creation log.ActionStatus = CopyLog.Status.OK; if (copyStatus != null) { //[LOG:OK] Folder Creation update path log.ItemPath = copyStatus.Path; log.Comment = copyStatus.Comment; repport.writeLog(log); //[RESULT] Folder Creation repport.writeResult(copyStatus); } else { //We skip writing result for the rootfolder repport.writeLog(log); } } } i = 0; count = 0; foreach (FoldersToProcess folder in ctx.FoldersToUpload) { //Progression display i++; double percentage = (double)i / folders.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Batching folders upload - {advancement}%\n{i}/{folders.Count}"); count++; var myFolder = rootFolder.Folders.Add(folder.ItemUrls.ServerRelativeUrl); if (count >= this.BatchRequestSize) { bw.ReportProgress(advancement, "Uploading folders batch"); Context.RequestTimeout = -1; Context.ExecuteQuery(); count = 0; } } bw.ReportProgress(0, "Finalising folders upload"); Context.RequestTimeout = -1; Context.ExecuteQuery(); i = 0; count = 0; foreach (FoldersToProcess folder in ctx.FoldersToUpload) { //Progression display i++; double percentage = (double)i / folders.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Batching folders metadata - {advancement}%\n{i}/{folders.Count}"); //We update metadate ListItem listitemFolder = Context.Web.GetListItem(folder.ItemUrls.ServerRelativeUrl); listitemFolder["Created"] = folder.Created; listitemFolder["Modified"] = folder.Modified; listitemFolder.Update(); count++; if (count >= this.BatchRequestSize) { bw.ReportProgress(advancement, "Uploading folders metadata batch"); Context.RequestTimeout = -1; Context.ExecuteQuery(); count = 0; } } bw.ReportProgress(0, "Finalising folders Metadata"); Context.RequestTimeout = -1; Context.ExecuteQuery(); #endregion #region FileCopy //[LOG:Title] File upload beggins log.update("[Starting File Upload process]"); repport.writeLog(log); //We reset the progression index i = 0; foreach (FileInfo file in files) { //Progression display i++; double percentage = (double)i / files.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Checking files - {advancement}%\n{i}/{files.Count}"); //Check if Cancellation is pending if (bw.CancellationPending == true) { //[LOG:CANCEL] Cancellation log log.update("[Process Cancelled]"); repport.writeLog(log); //We cancel the backgroundWorker and return e.Cancel = true; return; } //If no cancellation, we launch the copy file process else { //[LOG:Verbose] File Upload log.update(CopyLog.Status.Verbose, "File upload", file.FullName, ""); repport.writeLog(log); //We copy the file CopyStatus copyStatus = ctx.copyFileToSPO(file, list, LocalPath, onlineListItem); //[LOG:OK] File Upload log.ActionStatus = CopyLog.Status.OK; log.ItemPath = copyStatus.Path; log.Comment = copyStatus.Comment; //[RESULT/LOG: OK] File Upload repport.writeLog(log); repport.writeResult(copyStatus); } } #endregion #region Item Deletion //We handle the delete old items checkbox feature if (this.DeleteOldItems == true) { //[LOG:Verbose] Online ListItem retrieve log.update(CopyLog.Status.Verbose, "Online ListItem retrieve", LocalPath, ""); repport.writeLog(log); // We retrieve all listitems in the library and divide files and folders bw.ReportProgress(0, "Retrieving ListItems"); onlineListItem = ctx.GetAllDocumentsInaLibrary(this.DocLib); List <ListItem> onlineFiles = ctx.GetOnlyFiles(onlineListItem); List <ListItem> onlineFolders = ctx.GetOnlyFolders(onlineListItem); //[LOG:OK] Online ListItem retrieve log.ActionStatus = CopyLog.Status.OK; repport.writeLog(log); //[LOG:Title] File deletion beggins log.update("[Starting File Deletion process]"); repport.writeLog(log); #region File Deletion //We retrieve all the formated urls from local source files List <ItemURLs> itemsUrls = new List <ItemURLs>(); foreach (FileInfo file in files) { ItemURLs itemUrl = ctx.formatUrl(file, list, LocalPath); itemsUrls.Add(itemUrl); } //We reset the progression index i = 0; count = 0; foreach (ListItem onlineFile in onlineFiles) { //Progression display i++; double percentage = (double)i / onlineFiles.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Checking old files - {advancement}%\n{i}/{onlineFiles.Count}"); //Check if Cancellation is pending if (bw.CancellationPending == true) { //[LOG:CANCEL] Cancellation log log.update("[Process Cancelled]"); repport.writeLog(log); //We cancel the backgroundWorker and return e.Cancel = true; return; } //If no cancellation, we launch the file deletion process else { //[LOG:Verbose] File Deletion log.update(CopyLog.Status.Verbose, "File deletion", (string)onlineFile["FileLeafRef"], ""); repport.writeLog(log); //Attempt to delete the file if necessary CopyStatus copystat = ctx.CheckItemToDelete(itemsUrls, list, LocalPath, onlineFile); if (copystat.Status == CopyStatus.ItemStatus.Deleted) { count++; ListItem item = list.GetItemById((Int32)onlineFile["ID"]); item.DeleteObject(); } if (count >= this.BatchRequestSize) { count = 0; Context.ExecuteQuery(); } //[LOG:OK] File Deletion log.ActionStatus = CopyLog.Status.OK; log.ItemPath = copystat.Path; log.Comment = copystat.Comment; //[RESULT/LOG: OK] File Deletion repport.writeLog(log); repport.writeResult(copystat); } } bw.ReportProgress(0, "Deleting old files"); Context.RequestTimeout = -1; Context.ExecuteQuery(); #endregion #region Folder Deletion //Folder deletion //We retrieve all the formated urls from local source folders List <ItemURLs> folderUrls = new List <ItemURLs>(); foreach (DirectoryInfo folder in folders) { ItemURLs itemUrl = ctx.formatUrl(folder, list, LocalPath); folderUrls.Add(itemUrl); } //We reset the progression index i = 0; count = 0; foreach (ListItem onlineFolder in onlineFolders) { //Progression display i++; Double percentage = (double)i / onlineFolders.Count; int advancement = Convert.ToInt32(percentage * 100); bw.ReportProgress(advancement, $"Checking old folders - {advancement}%\n{i}/{onlineFolders.Count}"); //Check if Cancellation is pending if (bw.CancellationPending == true) { //[LOG:CANCEL] Cancellation log log.update("[Process Cancelled]"); repport.writeLog(log); //We cancel the backgroundWorker and return e.Cancel = true; return; } //If no cancellation, we launch the folder deletion process else { //[LOG:Verbose] Folder Deletion log.update(CopyLog.Status.Verbose, "Folder deletion", (string)onlineFolder["FileLeafRef"], ""); repport.writeLog(log); //Attempt to delete the file if necessary CopyStatus copystat = ctx.CheckItemToDelete(folderUrls, list, LocalPath, onlineFolder); //Change the item type to folder for result purpose copystat.Type = CopyStatus.ItemType.Folder; int pathRootFolderCount = FileLogic.isRootFolder(list.RootFolder.ServerRelativeUrl); int pathFolderCount = FileLogic.isRootFolder(copystat.Path); if ((pathFolderCount - pathRootFolderCount) == 1 && copystat.Status == CopyStatus.ItemStatus.Deleted) { count++; ListItem item = list.GetItemById((Int32)onlineFolder["ID"]); item.DeleteObject(); } if (count >= this.BatchRequestSize) { Context.RequestTimeout = -1; try { Context.ExecuteQuery(); } catch (Exception ex) { if (!ex.Message.Contains("Item does not exist. It may have been deleted by another user.")) { throw ex; } } } //[LOG:OK] Folder Deletion log.ActionStatus = CopyLog.Status.OK; log.ItemPath = copystat.Path; log.Comment = copystat.Comment; //[RESULT/LOG: OK] Folder Deletion repport.writeLog(log); repport.writeResult(copystat); } } bw.ReportProgress(0, "Deleting old folders"); Context.RequestTimeout = -1; try { Context.ExecuteQuery(); } catch (Exception ex) { if (!ex.Message.Contains("Item does not exist. It may have been deleted by another user.")) { throw ex; } } #endregion } #endregion } catch (Exception ex) { //We cancel the backgroundWorker if an exception is not handled so far MessageBox.Show(ex.Message); bw.CancelAsync(); e.Cancel = true; //[LOG:ERROR] Error log log.ActionStatus = CopyLog.Status.Error; log.Comment = ex.Message; repport.writeLog(log); //[RESULT:ERROR] Error result CopyStatus copyError = new CopyStatus { Comment = ex.Message, Name = log.ItemPath, Path = log.ItemPath, Status = CopyStatus.ItemStatus.Error }; repport.writeResult(copyError); } }