using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Diagnostics.Contracts; using System.IO; using System.Linq; using System.Text; using Pithos.Interfaces; using Pithos.Network; namespace Pithos.Core.Agents { [Export(typeof(Selectives))] public class Selectives { public ConcurrentDictionary> SelectiveUris { get; private set; } public ConcurrentDictionary> SelectivePaths { get; private set; } [Import] public IPithosSettings Settings { get; set; } public Selectives() { SelectiveUris = new ConcurrentDictionary>(); SelectivePaths = new ConcurrentDictionary>(); } readonly ConcurrentDictionary _selectiveEnabled = new ConcurrentDictionary(); /* public void SetIsSelectiveEnabled(AccountInfo account,bool value) { _selectiveEnabled[account.AccountKey]=value; } */ public void SetIsSelectiveEnabled(Uri accountKey,bool value) { _selectiveEnabled[accountKey]=value; } /* public bool IsSelectiveEnabled(AccountInfo account) { bool isEnabled; _selectiveEnabled.TryGetValue(account.AccountKey, out isEnabled); return isEnabled; } */ public bool IsSelectiveEnabled(Uri accountKey) { bool isEnabled; _selectiveEnabled.TryGetValue(accountKey, out isEnabled); return isEnabled; } public void SetSelectedUris(AccountInfo account,List uris) { SelectiveUris[account.AccountKey] = new ConcurrentBag(uris); SelectivePaths[account.AccountKey] = new ConcurrentBag(UrisToFilePaths(account,uris)); } public void AddUri(AccountInfo account,Uri uri) { var accountPath = account.AccountPath; var storageUrl = account.StorageUri.ToString(); var isShared=!uri.ToString().StartsWith(storageUrl); var relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath(); var fullPath=isShared ?Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath) :Path.Combine(accountPath, relativePath.After(account.UserName + '\\')); SelectiveUris[account.AccountKey].Add(uri); SelectivePaths[account.AccountKey].Add(fullPath); } public bool IsSelected(AccountInfo account,ObjectInfo info) { //Shared folders should NOT be synced if selective syncing is disabled var isShared = info.IsShared??false; if (info.StorageUri == null) return true; var selectiveEnabled = IsSelectiveEnabled(account.AccountKey); if (!selectiveEnabled) return !isShared; ConcurrentBag filterUris; return SelectiveUris.TryGetValue(account.AccountKey, out filterUris) /*|| filterUris.Count ==0*/ && filterUris.Any(f => info.Uri.IsAtOrDirectlyBelow(f)); } public bool IsSelected(AccountInfo account,FileSystemInfo info) { /*if (info is DirectoryInfo) return true;*/ return IsSelected(account,info.FullName); } public bool IsSelected(AccountInfo account, string fullPath) { //Shared folders should NOT be synced if selective syncing is disabled var isShared = fullPath.IsSharedTo(account); var selectiveEnabled = IsSelectiveEnabled(account.AccountKey); if (!selectiveEnabled) return !isShared; ConcurrentBag paths; var hasSelectives = SelectivePaths.TryGetValue(account.AccountKey, out paths); var isSelected = hasSelectives && paths.Any(fullPath.IsAtOrDirectlyBelow); return isSelected; } /// /// Return a list of absolute filepaths from a list of Uris /// /// /// private List UrisToFilePaths(AccountInfo account,IEnumerable uris) { if (uris == null) return new List(); var accountPath = account.AccountPath; var storageUrl = account.StorageUri.ToString(); var own = (from uri in uris where uri.ToString().StartsWith(storageUrl) let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath() //Trim the account name select Path.Combine(accountPath, relativePath.After(account.UserName + '\\'))).ToList(); var others = (from uri in uris where !uri.ToString().StartsWith(storageUrl) let relativePath = account.StorageUri.MakeRelativeUri(uri).RelativeUriToFilePath() //Trim the account name select Path.Combine(accountPath, FolderConstants.OthersFolder, relativePath)).ToList(); return own.Union(others).ToList(); } public void Save(AccountInfo account) { Contract.Requires(account!=null); Contract.EndContractBlock(); var selections = SelectiveUris[account.AccountKey]; var accountSettings= Settings.Accounts.First(acc => acc.AccountKey == account.AccountKey); accountSettings.SelectiveFolders.Clear(); accountSettings.SelectiveFolders.AddRange(selections.Select(uri => uri.ToString()).ToArray()); Settings.Save(); } } }