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