public JobOutcome Execute(IJobProcessorServices context, IJob job) { try { Inventor.InventorServer mInv = context.InventorObject as InventorServer; #region validate execution rules //pick up this job's context mConnection = context.Connection; Autodesk.Connectivity.WebServicesTools.WebServiceManager mWsMgr = mConnection.WebServiceManager; long mEntId = Convert.ToInt64(job.Params["EntityId"]); string mEntClsId = job.Params["EntityClassId"]; // only run the job for files; handle the scenario, that an item lifecycle transition accidently submitted the job if (mEntClsId != "FILE") { context.Log(null, "This job type is for files only."); return(JobOutcome.Failure); } // only run the job for ipt and iam file types, List <string> mFileExtensions = new List <string> { ".ipt", ".iam", "idw", "dwg" }; ACW.File mFile = mWsMgr.DocumentService.GetFileById(mEntId); if (!mFileExtensions.Any(n => mFile.Name.EndsWith(n))) { context.Log(null, "Skipped Job execution as file type did not match iLogic enabled files (ipt, iam, idw/dwg"); return(JobOutcome.Success); } //run iLogic for Inventor DWG file types/skip AutoCAD DWG files ACW.PropDef[] mPropDefs = mWsMgr.PropertyService.GetPropertyDefinitionsByEntityClassId("FILE"); ACW.PropDef mPropDef = null; ACW.PropInst mPropInst = null; if (mFile.Name.EndsWith(".dwg")) { mPropDef = mPropDefs.Where(n => n.SysName == "Provider").FirstOrDefault(); mPropInst = (mWsMgr.PropertyService.GetPropertiesByEntityIds("FILE", new long[] { mFile.Id })).Where(n => n.PropDefId == mPropDef.Id).FirstOrDefault(); if (mPropInst.Val.ToString() != "Inventor DWG") { context.Log(null, "Skipped Job execution as DWG type did not match Inventor DWG"); return(JobOutcome.Success); } } ApplicationAddIns mInvSrvAddIns = mInv.ApplicationAddIns; ApplicationAddIn iLogicAddIn = mInvSrvAddIns.ItemById["{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"]; if (iLogicAddIn != null && iLogicAddIn.Activated != true) { iLogicAddIn.Activate(); } dynamic mAutomation = iLogicAddIn.Automation; if (mAutomation == null) { Trace.WriteLine("iLogic-AddIn automation is not available; exiting job processing"); context.Log(null, "iLogic-AddIn automation is not available"); return(JobOutcome.Failure); } #endregion validate execution rules #region VaultInventorServer IPJ activation //override InventorServer default project settings by your Vault specific ones Inventor.DesignProjectManager mInvIpjManager; Inventor.DesignProject mInvDfltProject, mInvVltProject; String mIpjPath = ""; String mWfPath = ""; String mIpjLocalPath = ""; ACW.File mIpj; VDF.Vault.Currency.Entities.FileIteration mIpjFileIter = null; //validate ipj setting, a single, enforced ipj is expected if (mWsMgr.DocumentService.GetEnforceWorkingFolder() && mWsMgr.DocumentService.GetEnforceInventorProjectFile()) { mIpjPath = mWsMgr.DocumentService.GetInventorProjectFileLocation(); mWfPath = mWsMgr.DocumentService.GetRequiredWorkingFolderLocation(); //Set mWfPath to alternate temporary working folder if needed, e.g. to delete all files after job execution } else { context.Log(null, "Job requires both settings enabled: 'Enforce Workingfolder' and 'Enforce Inventor Project'."); return(JobOutcome.Failure); } //download and activate the Inventor Project file in VaultInventorServer mIpj = (mWsMgr.DocumentService.FindLatestFilesByPaths(new string[] { mIpjPath })).FirstOrDefault(); try { String[] mIpjFullFileName = mIpjPath.Split(new string[] { "/" }, StringSplitOptions.None); String mIpjFileName = mIpjFullFileName.LastOrDefault(); //define download settings for the project file VDF.Vault.Settings.AcquireFilesSettings mAcqrIpjSettings = new VDF.Vault.Settings.AcquireFilesSettings(mConnection); mAcqrIpjSettings.LocalPath = new VDF.Currency.FolderPathAbsolute(mWfPath); mIpjFileIter = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mIpj); mAcqrIpjSettings.AddFileToAcquire(mIpjFileIter, VDF.Vault.Settings.AcquireFilesSettings.AcquisitionOption.Download); //download project file and get local path VDF.Vault.Results.AcquireFilesResults mDownLoadResult; VDF.Vault.Results.FileAcquisitionResult fileAcquisitionResult; mDownLoadResult = mConnection.FileManager.AcquireFiles(mAcqrIpjSettings); fileAcquisitionResult = mDownLoadResult.FileResults.FirstOrDefault(); mIpjLocalPath = fileAcquisitionResult.LocalPath.FullPath; //activate this Vault's ipj mInvIpjManager = mInv.DesignProjectManager; mInvDfltProject = mInvIpjManager.ActiveDesignProject; mInvVltProject = mInvIpjManager.DesignProjects.AddExisting(mIpjLocalPath); mInvVltProject.Activate(); //[Optionally:] get Inventor Design Data settings and download all related files --------- } catch { context.Log(null, "Job was not able to activate Inventor project file. - Note: The ipj must not be checked out by another user."); return(JobOutcome.Failure); } #endregion VaultInventorServer IPJ activation #region download source file(s) //build download options including DefaultAcquisitionOptions VDF.Vault.Currency.Entities.FileIteration mFileIteration = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mFile); VDF.Vault.Currency.Entities.FileIteration mNewFileIteration = null; VDF.Vault.Settings.AcquireFilesSettings mAcqrFlsSettings; VDF.Vault.Results.AcquireFilesResults mAcqrFlsResults2; VDF.Vault.Results.FileAcquisitionResult mFileAcqsResult2; string mLocalFileFullName = "", mExt = ""; if (mFileIteration.IsCheckedOut == true && mFileIteration.IsCheckedOutToCurrentUser == false) { //exit the job, as the job user is not able to edit the file reserved to another user mInvDfltProject.Activate(); context.Log(null, "Job stopped execution as the source file to process is checked-out by another user."); return(JobOutcome.Failure); } //download only if (mFileIteration.IsCheckedOut == true && mFileIteration.IsCheckedOutToCurrentUser == true) { mAcqrFlsSettings = CreateAcquireSettings(false); mAcqrFlsSettings.AddFileToAcquire(mFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption); mAcqrFlsResults2 = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings); mNewFileIteration = mFileIteration; mFileAcqsResult2 = mAcqrFlsResults2.FileResults.Where(n => n.File.EntityName == mFileIteration.EntityName).FirstOrDefault(); mLocalFileFullName = mFileAcqsResult2.LocalPath.FullPath; mExt = System.IO.Path.GetExtension(mLocalFileFullName); } //checkout and download if (mFileIteration.IsCheckedOut == false) { try { mAcqrFlsSettings = CreateAcquireSettings(true); //checkout (don't checkout related children) mAcqrFlsSettings.AddFileToAcquire(mFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption); mAcqrFlsResults2 = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings); mFileAcqsResult2 = mAcqrFlsResults2.FileResults.Where(n => n.File.EntityName == mFileIteration.EntityName).FirstOrDefault(); mNewFileIteration = mFileAcqsResult2.NewFileIteration; mAcqrFlsSettings = null; mAcqrFlsSettings = CreateAcquireSettings(false);//download (include related children) mAcqrFlsSettings.AddFileToAcquire(mNewFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption); mAcqrFlsResults2 = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings); mLocalFileFullName = mFileAcqsResult2.LocalPath.FullPath; mExt = System.IO.Path.GetExtension(mLocalFileFullName); } catch (Exception) { mInvDfltProject.Activate(); context.Log(null, "Job stopped execution as the source file to process did not download or check-out."); return(JobOutcome.Failure); } } #endregion download source file(s) #region capture dependencies //we need to return all relationships during later check-in List <ACW.FileAssocParam> mFileAssocParams = new List <ACW.FileAssocParam>(); ACW.FileAssocArray mFileAssocArray = mWsMgr.DocumentService.GetLatestFileAssociationsByMasterIds(new long[] { mFile.MasterId }, ACW.FileAssociationTypeEnum.None, false, ACW.FileAssociationTypeEnum.All, false, false, false, true).FirstOrDefault(); if (mFileAssocArray.FileAssocs != null) { foreach (ACW.FileAssoc item in mFileAssocArray.FileAssocs) { ACW.FileAssocParam mFileAssocParam = new ACW.FileAssocParam(); mFileAssocParam.CldFileId = item.CldFile.Id; mFileAssocParam.ExpectedVaultPath = item.ExpectedVaultPath; mFileAssocParam.RefId = item.RefId; mFileAssocParam.Source = item.Source; mFileAssocParam.Typ = item.Typ; mFileAssocParams.Add(mFileAssocParam); } } #endregion capture dependencies #region iLogic Configuration //avoid unplanned rule execution triggered by the document itself mAutomation.RulesOnEventsEnabled = false; mAutomation.RulesEnabled = false; //set the iLogic Advanced Configuration Settings dynamic mFileOptions = mAutomation.FileOptions; mFileOptions.AddinDirectory = mSettings.iLogicAddinDLLs; //add the job extension app path and configured external rule directories to the FileOptions.ExternalRuleDirectories for iLogic List <string> mExtRuleDirs = new List <string>(); mExtRuleDirs.Add(mAppPath); mExtRuleDirs.AddRange(mSettings.ExternalRuleDirectories.Split(',').ToList <string>()); mFileOptions.ExternalRuleDirectories = mExtRuleDirs.ToArray(); //enable iLogic logging dynamic mLogCtrl = mAutomation.LogControl; switch (mSettings.iLogicLogLevel) { case "None": mLogCtrl.Level = 0; break; case "Trace": mLogCtrl.Level = 1; break; case "Debug": mLogCtrl.Level = 2; break; case "Info": mLogCtrl.Level = 3; break; case "Warn": mLogCtrl.Level = 4; break; case "Error": mLogCtrl.Level = 5; break; case "Fatal": mLogCtrl.Level = 6; break; default: mLogCtrl.Level = 5; break; } //enable iLogic to save a log file for each job Id. string mILogicLogFileFullName = ""; if (mLogCtrl.Level != 0) { string mLogName = job.Id + "_" + mFile.Name + "_iLogicSampleJob.log"; System.IO.DirectoryInfo mLogDirInfo = new System.IO.DirectoryInfo(mSettings.iLogicLogDir); if (mLogDirInfo.Exists == false) { mLogDirInfo = System.IO.Directory.CreateDirectory(mSettings.iLogicLogDir); } mILogicLogFileFullName = System.IO.Path.Combine(mLogDirInfo.FullName, mLogName); } //read rule execution settings string mVaultRule = mSettings.VaultRuleFullFileName; string mExtRule = mSettings.ExternalRuleName; string mExtRuleFullName = null; string mIntRulesOption = mSettings.InternalRulesOption; if (mVaultRule != "") { ACW.File mRuleFile = mWsMgr.DocumentService.FindLatestFilesByPaths(new string[] { mVaultRule }).FirstOrDefault(); //build download options including DefaultAcquisitionOptions VDF.Vault.Currency.Entities.FileIteration mRuleFileIter = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mRuleFile); VDF.Vault.Settings.AcquireFilesSettings mAcqrRuleSettings = CreateAcquireSettings(false); mAcqrRuleSettings.AddFileToAcquire(mRuleFileIter, mAcqrRuleSettings.DefaultAcquisitionOption); //download VDF.Vault.Results.AcquireFilesResults mAcqrRuleResults = this.mConnection.FileManager.AcquireFiles(mAcqrRuleSettings); //pick-up the new file iteration in case of check-out VDF.Vault.Results.FileAcquisitionResult mRuleAcqResult = mAcqrRuleResults.FileResults.Where(n => n.File.EntityName == mRuleFileIter.EntityName).FirstOrDefault(); if (mRuleAcqResult.LocalPath != null) { mExtRuleFullName = mRuleAcqResult.LocalPath.FullPath; System.IO.FileInfo fileInfo = new System.IO.FileInfo(mExtRuleFullName); if (fileInfo.Exists == false) { context.Log(null, "Job downloaded rule file but exited due to missing rule file: " + mExtRuleFullName + "."); mConnection.FileManager.UndoCheckoutFile(mNewFileIteration); return(JobOutcome.Failure); } else { mExtRule = fileInfo.Name; if (!mExtRuleDirs.Any(n => fileInfo.DirectoryName.Equals(n))) { context.Log(null, "Job downloaded rule file but exited due to missing iLogic External Rule Directory configuration: Add the path" + fileInfo.DirectoryName + " to the list of External Rule Directories."); mConnection.FileManager.UndoCheckoutFile(mNewFileIteration); return(JobOutcome.Failure); } } } else { context.Log(null, "Job could not download configured rule file and exited. Compare the 'VaultRuleFullFileName' setting and available rule in Vault."); return(JobOutcome.Failure); } } #endregion iLogic Configuration #region Run iLogic Rule(s) //Open Inventor Document Document mDoc = mInv.Documents.Open(mLocalFileFullName); //use case - apply external rule with arguments; additional Vault UDP, status or any information might fill rule arguments if (mExtRule != "") { //required rule arguments to continue Vault interaction within the rule (iLogic-Vault library) NameValueMap ruleArguments = mInv.TransientObjects.CreateNameValueMap(); ruleArguments.Add("ServerName", mConnection.Server); ruleArguments.Add("VaultName", mConnection.Vault); ruleArguments.Add("UserId", mConnection.UserID); ruleArguments.Add("Ticket", mConnection.Ticket); //additional rule arguments to build rule conditions evaluating Vault lifecycle information, properties, etc. if (mSettings.PropagateProps == "True") { ACW.PropInst[] mSourcePropInsts = mWsMgr.PropertyService.GetPropertiesByEntityIds("FILE", new long[] { mFileIteration.EntityIterationId }); string mPropDispName; string mThumbnailDispName = mPropDefs.Where(n => n.SysName == "Thumbnail").FirstOrDefault().DispName; foreach (ACW.PropInst item in mSourcePropInsts) { mPropDispName = mPropDefs.Where(n => n.Id == item.PropDefId).FirstOrDefault().DispName; //filter thumbnail property, as iLogic RuleArguments will fail reading it. if (mPropDispName != mThumbnailDispName) { ruleArguments.Add(mPropDispName, item.Val); } } } //call external rule with arguments; return value = 0 in case of successful execution mRuleSuccess = mAutomation.RunExternalRuleWithArguments(mDoc, mExtRule, ruleArguments); if (mRuleSuccess != 0) { context.Log(null, "Job failed due to failure in external rule: " + mExtRule + "."); mDoc.Close(true); mConnection.FileManager.UndoCheckoutFile(mNewFileIteration); mLogCtrl.SaveLogAs(mILogicLogFileFullName); return(JobOutcome.Failure); } else { mAllRulesTextWrp = "External Rule: " + mExtRule; } mDoc.Save2(false); } //use case - run all, all active or filtered document rules dynamic mDocRules = mAutomation.Rules(mDoc); List <dynamic> mRulesToExec = new List <dynamic>(); switch (mSettings.InternalRulesOption) { case "None": break; case "Active": if (mDocRules != null) { foreach (dynamic rule in mDocRules) { if (rule.IsActive == true) { mRulesToExec.Add(rule); } } } break; case "All": if (mDocRules != null) { foreach (dynamic rule in mDocRules) { mRulesToExec.Add(rule); } } break; default: foreach (dynamic rule in mDocRules) { if (rule.Name.Contains(mSettings.InternalRulesOption)) { mRulesToExec.Add(rule); } } break; } if (mRulesToExec.Count >= 1) { foreach (dynamic rule in mRulesToExec) { mRuleSuccess = mAutomation.RunRule(mDoc, rule.Name); if (mRuleSuccess != 0) { context.Log(null, "Job failed due to failure in internal rule: " + rule.Name + "."); mDoc.Close(true); mConnection.FileManager.UndoCheckoutFile(mNewFileIteration); mLogCtrl.SaveLogAs(mILogicLogFileFullName); return(JobOutcome.Failure); } else { mAllRules.Add(rule.Name); } } } mDoc.Save2(false); mDoc.Close(true); mLogCtrl.SaveLogAs(mILogicLogFileFullName); if (mAllRules.Count > 0) { mAllRulesTextWrp += "\n\r Internal Rule(s):"; foreach (string name in mAllRules) { mAllRulesTextWrp += "\r\n " + name; } } #endregion Run iLogic Rules #region Check-in result // checkin new file version VDF.Currency.FilePathAbsolute vdfPath = new VDF.Currency.FilePathAbsolute(mLocalFileFullName); FileIteration mUploadedFile = null; try { if (mFileAssocParams.Count > 0) { mUploadedFile = mConnection.FileManager.CheckinFile(mNewFileIteration, "Created by Custom Job executing iLogic : " + mAllRulesTextWrp, false, mFileAssocParams.ToArray(), null, true, null, mFileIteration.FileClassification, false, vdfPath); } else { mUploadedFile = mConnection.FileManager.CheckinFile(mNewFileIteration, "Created by Custom Job executing iLogic : " + mAllRulesTextWrp, false, null, null, false, null, mFileIteration.FileClassification, false, vdfPath); } } catch { context.Log(null, "Job could not check-in updated file: " + mUploadedFile.EntityName + "."); return(JobOutcome.Failure); } #endregion check-in result #region reset mInvDfltProject.Activate(); //delete temporary working folder if imlemented here #endregion reset return(JobOutcome.Success); } catch (Exception ex) { context.Log(ex, "Job failed by unhandled exception: " + ex.ToString() + " "); return(JobOutcome.Failure); } }
private List </*Tuple<ADSK.File, string, bool, bool>*/ VaultEagleLib.Model.DataStructures.DownloadItem> FindFilesChangedSinceLastSync(VDF.Vault.Currency.Connections.Connection connection, bool useLastSyncTime, DateTime lastSyncTime, string vaultRoot, int retries, NotifyIcon trayIcon, VaultEagleLib.SynchronizationItem[] items, Option <MCADCommon.LogCommon.DisposableFileLogger> logger) { string lastSyncTag = lastSyncTime.ToUniversalTime().ToString("MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture); logger.IfSomeDo(l => l.Trace("Fetching files with date modified after: " + lastSyncTag + ".")); long modifiedId = connection.WebServiceManager.PropertyService.GetPropertyDefinitionsByEntityClassId("FILE").First(p => p.DispName == "Date Modified").Id; SrchCond filesCreatedAfterLastSyncTime = new SrchCond { SrchTxt = lastSyncTag, SrchRule = SearchRuleType.Must, SrchOper = 7, PropDefId = modifiedId, PropTyp = PropertySearchType.SingleProperty }; // logger.Trace("Fetched: " + filesAndFolders.Count + " files before filtering."); //List<Tuple<ADSK.File, string, bool, bool>> fileAndPath = new List<Tuple<ADSK.File, string, bool, bool>>(); List <VaultEagleLib.Model.DataStructures.DownloadItem> filesToDownload = new List <VaultEagleLib.Model.DataStructures.DownloadItem>(); List <ADSK.File> addedFiles = new List <ADSK.File>(); items = VaultEagleLib.SynchronizationItem.UpdateListWithTactonItems(items); List <string> Checked = new List <string>(); int i = 0; trayIcon.Text = "0 of " + items.Count() + " download items to iterate over."; foreach (VaultEagleLib.SynchronizationItem item in items) { if (Checked.Contains(item.SearchPath.ToLower())) { continue; } try { Option <Folder> folder = Option.None; Option <string> fileName = Option.None; if (!System.IO.Path.HasExtension(item.SearchPath)) { try { folder = connection.WebServiceManager.DocumentService.GetFolderByPath(item.SearchPath).AsOption(); } catch { } } else { try { if (item.SearchPath.Contains('.')) { int k = item.SearchPath.LastIndexOf('/'); if (k > 0 && connection.WebServiceManager.DocumentService.FindFoldersByPaths(new string[] { item.SearchPath.Substring(0, k) }).Count() > 0) { folder = connection.WebServiceManager.DocumentService.GetFolderByPath(item.SearchPath.Substring(0, k)).AsOption(); fileName = item.SearchPath.Substring(k + 1).AsOption(); } } } catch { } } if (folder.IsSome && folder.Get().Id > 0) { List <Tuple <FileFolder, Option <string> > > FileFolderAndComponentName = new List <Tuple <FileFolder, Option <string> > >(); List <FileFolder> filesAndFolders = new List <FileFolder>(); List <Folder> folders = new List <Folder>(); SrchStatus status = null; string bookmark = string.Empty; bool singleFile = false; while (status == null || filesAndFolders.Count < status.TotalHits) { FileFolder[] results; ADSK.File[] files = connection.WebServiceManager.DocumentService.GetLatestFilesByFolderId(folder.Get().Id, false).Where(f => f.Name.Equals(fileName.Get(), StringComparison.InvariantCultureIgnoreCase)).ToArray(); if (fileName.IsSome && files.Count() > 0) { singleFile = true; ADSK.File file = files.First(); ADSK.FileFolder fileFolder = new FileFolder(); fileFolder.File = file; fileFolder.Folder = folder.Get(); results = new FileFolder[] { fileFolder }; } else if (item.ComponentName.IsSome) { logger.IfSomeDo(l => l.Info("Could not find file: " + fileName + " for component: " + item.ComponentName.Get())); break; } else if (item.Mirrors.Count() > 0 || !useLastSyncTime) { results = connection.WebServiceManager.DocumentService.FindFileFoldersBySearchConditions(new SrchCond[] { }, null, new long[] { folder.Get().Id }, item.Recursive, true, ref bookmark, out status); } else { results = connection.WebServiceManager.DocumentService.FindFileFoldersBySearchConditions(new SrchCond[] { filesCreatedAfterLastSyncTime }, null, new long[] { folder.Get().Id }, item.Recursive, true, ref bookmark, out status); } List <FileFolder> allChildren = new List <FileFolder>(); //**********************************************************************************************/ if (item.GetChildren) { foreach (FileFolder ff in results) { foreach (ADSK.File childFile in MCADCommon.VaultCommon.FileOperations.GetAllChildren(ff.File.MasterId, new List <ADSK.File>(), connection)) { FileFolder child = new FileFolder(); child.File = childFile; child.Folder = connection.WebServiceManager.DocumentService.GetFolderById(childFile.FolderId); allChildren.Add(child); Checked.Add((child.Folder.FullName + "/" + child.File.Name).ToLower()); } } } //***************************************************************************************************/ if (results != null) { filesAndFolders.AddRange(results); FileFolderAndComponentName.AddRange(results.Select(r => new Tuple <FileFolder, Option <string> >(r, item.ComponentName))); } if (allChildren.Count > 0) { filesAndFolders.AddRange(allChildren); FileFolderAndComponentName.AddRange(allChildren.Select(r => new Tuple <FileFolder, Option <string> >(r, item.ComponentName))); } Checked.Add(item.SearchPath.ToLower()); if (singleFile) { break; } } status = null; if (item.PatternsToSynchronize.Contains("/") || item.Mirrors.Count() > 0) { while (status == null || folders.Count < status.TotalHits) { Folder[] folderResults = connection.WebServiceManager.DocumentService.FindFoldersBySearchConditions(new SrchCond[] { }, null, new long[] { folder.Get().Id }, item.Recursive, ref bookmark, out status); if (folderResults != null) { folders.AddRange(folderResults); } } } FileFolderAndComponentName = FileFolderAndComponentName.OrderBy(f => f.Item1.Folder.FullName.Length).ToList(); FileFolderAndComponentName = FileFolderAndComponentName.Where(f => !f.Item1.File.Hidden).ToList(); filesToDownload.AddRange(item.GetFilesAndPathsForItem(connection, FileFolderAndComponentName, addedFiles, vaultRoot, item.GetChildren, retries)); if (item.PatternsToSynchronize.Contains("/")) { filesToDownload.AddRange(item.GetFoldersAndPathsForItem(folders, vaultRoot)); } if (item.Mirrors.Count() > 0) { item.AddMirrorFolders(folders); } i++; trayIcon.Text = i + " of " + items.Count() + " download items checked."; // Console.WriteLine(i); } else { logger.IfSomeDo(l => l.Error("Incorrect input path: " + item.SearchPath + ".")); } } catch (Exception ex) { logger.IfSomeDo(l => l.Error("Error with synchronization item: " + ex.Message + ".")); } } //List<Tuple<ADSK.File, string, bool, bool>> filesAndPathsToDl = new List<Tuple<ADSK.File, string, bool, bool>>(); List <VaultEagleLib.Model.DataStructures.DownloadItem> filesToDl = new List <VaultEagleLib.Model.DataStructures.DownloadItem>(); /* filesAndPathsToDl = fileAndPath.Where(f => f.Item1 != null).ToList(); * filesAndPathsToDl = filesAndPathsToDl.DistinctBy(f => f.Item1.MasterId).ToList(); * filesAndPathsToDl.AddRange(fileAndPath.Where(f => f.Item1 == null).ToList()); */ filesToDl = filesToDownload.Where(f => f is VaultEagleLib.Model.DataStructures.DownloadFile).ToList(); filesToDl = filesToDl.DistinctBy(f => ((VaultEagleLib.Model.DataStructures.DownloadFile)f).File.MasterId).ToList(); filesToDl.AddRange(filesToDownload.Where(f => !(f is VaultEagleLib.Model.DataStructures.DownloadFile))); return /*removeExcludedPaths*/ (filesToDl);//filesAndPathsToDl; }