Selective Sync now shows both server AND local folders
authorpkanavos <pkanavos@gmail.com>
Thu, 3 May 2012 17:59:06 +0000 (20:59 +0300)
committerpkanavos <pkanavos@gmail.com>
Thu, 3 May 2012 18:45:08 +0000 (21:45 +0300)
trunk/Pithos.Client.WPF.Test/NodeTest.cs
trunk/Pithos.Client.WPF/Pithos.Client.WPF.csproj
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
trunk/Pithos.Client.WPF/Utils/EnumerableExtensions.cs
trunk/Pithos.Client.WPF/Utils/SelectiveExtensions.cs [new file with mode: 0644]
trunk/Pithos.Core/Pithos.Core.csproj

index 3842eeb..55d487e 100644 (file)
@@ -219,7 +219,7 @@ namespace Pithos.Client.WPF.Test
                                  new ObjectInfo {Account = account, Container = container, Name = "File03"}
                              };
 
-            var tree = source.ToTree();
+            var tree = source.  ToTree();
             var allNodes = (from DirectoryRecord root in tree
                             from DirectoryRecord record in root
                             select record).ToList();
@@ -286,5 +286,15 @@ namespace Pithos.Client.WPF.Test
                             select record).ToList();
             Assert.That(allNodes.Count,Is.EqualTo(9));
         }
+
+        [Test]
+        public void TestUri()
+        {
+            var storageUri = new Uri("http://pithos.okeanos.grnet.gr/v1/pkanavos@gmail.com");
+            var uri = new Uri(storageUri, "pithos");
+            
+            var expected = new Uri("http://pithos.okeanos.grnet.gr/v1/pkanavos@gmail.com/pithos");
+            Assert.That(uri, Is.EqualTo(expected));
+        }
     }
 }
index 6b3da27..dd09bff 100644 (file)
     <Compile Include="Services\StatusService.cs" />
     <Compile Include="Utils\EnumerableExtensions.cs" />
     <Compile Include="Utils\Node.cs" />
+    <Compile Include="Utils\SelectiveExtensions.cs" />
     <Compile Include="Wpf32Window.cs" />
     <Page Include="FileProperties\ConflictsView.xaml">
       <SubType>Designer</SubType>
index b332064..abfe6d9 100644 (file)
@@ -69,7 +69,7 @@ namespace Pithos.Client.WPF.SelectiveSynch
         private ObservableCollection<ObjectInfo> _checks;\r
         //private readonly PithosMonitor _monitor;\r
         private bool _isBusy=true;\r
-        private string _apiKey;\r
+        private readonly string _apiKey;\r
 \r
         public ObservableCollection<ObjectInfo> Checks\r
         {\r
@@ -103,6 +103,9 @@ namespace Pithos.Client.WPF.SelectiveSynch
             var client = new CloudFilesClient(AccountName,_apiKey){AuthenticationUrl=Account.ServerUrl,UsePithos=true};\r
             client.Authenticate();\r
             \r
+            //NEED to get the local folders here as well,\r
+            // and combine them with the cloud folders\r
+\r
 \r
             var dirs = from container in client.ListContainers(AccountName)  \r
                        where container.Name != "trash"\r
@@ -115,6 +118,8 @@ namespace Pithos.Client.WPF.SelectiveSynch
                                   };\r
             var ownFolders = dirs.ToList();\r
 \r
+\r
+\r
             var accountNodes=from account in client.ListSharingAccounts()\r
                              select new DirectoryRecord\r
                              {\r
@@ -143,6 +148,13 @@ namespace Pithos.Client.WPF.SelectiveSynch
                                    Directories = ownFolders.ToList()\r
                                };\r
 \r
+            var localFolders = SelectiveExtensions.LocalFolders(AccountName, Account.RootPath,client.StorageUrl.AbsoluteUri);\r
+\r
+            AppendToTree(localFolders, rootItem);\r
+            \r
+            //For each local folder that doesn't exist in the server nodes \r
+            //find the best matching parent and add the folder below it.\r
+\r
             Execute.OnUIThread(() =>\r
                                    {\r
                                        RootNodes.Add(rootItem);\r
@@ -154,6 +166,38 @@ namespace Pithos.Client.WPF.SelectiveSynch
             IsBusy = false;\r
         }\r
 \r
+        private static void AppendToTree(IEnumerable<DirectoryRecord> localFolders, DirectoryRecord rootItem)\r
+        {\r
+            foreach (var folder in localFolders)\r
+            {\r
+                var items = from root in rootItem\r
+                            from child in root\r
+                            select child;\r
+                //If this folder is not included in the server folders\r
+                if (items.Any(dir => dir.Uri == folder.Uri)) \r
+                    continue;\r
+\r
+                //we need to add it\r
+                //Find the best parent\r
+\r
+                //One way to do this, is to break the the Uri to its parts\r
+                //and try to find a parent using progressively fewer parts\r
+                var parts = folder.Uri.AbsoluteUri.Split('/');\r
+                for (var i = parts.Length - 1; i > 2; i--)\r
+                {\r
+                    var parentUrl = String.Join("/", parts.Splice(0, i));\r
+                    var parentUri = new Uri(parentUrl);\r
+\r
+                    var parent = items.FirstOrDefault(dir => dir.Uri == parentUri);\r
+                    if (parent != null)\r
+                    {\r
+                        parent.Directories.Add(folder);\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
         public bool IsBusy\r
         {\r
             get {\r
index 5e62743..200ea58 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Text;
@@ -79,125 +80,8 @@ namespace Pithos.Client.WPF.Utils
             return nodes;
         }
 
-        public static List<DirectoryRecord> ToTree(this IEnumerable<ObjectInfo> enumerable)
-        {
-            //Order the items to ensure that children always come after their parents
-            var orderedItems=enumerable.OrderBy(o=>o.Uri.ToString());
-            //Each item is stored in lookups
-            var lookups = new Dictionary<string,DirectoryRecord>();
-            
-            //RootNodes contains only the root nodes
-            var rootNodes = new List<DirectoryRecord>();            
-
-            foreach (var item in orderedItems)
-            {
-                var path = item.Uri.ToString();
-                //Calculate the parent path
-                var parentPath = GetParentPath(path);
-                var parentName = GetParentPath(item.Name);
-                DirectoryRecord parent;                
-
 
-                //First ensure that the parent items exist
 
-                var parts = item.Name.Split('/');
-
-                if (item.IsDirectory)
-                {
-                    AddParentNodes(lookups, rootNodes, parts, item);
-
-                    //Store each item using its current path
-                    var newNode = new DirectoryRecord {DisplayName = parts.Last(), ObjectInfo = item};
-                    AddNode(rootNodes, lookups, newNode);
-                }
-                else
-                {
-                    //Dont't add files
-                    //But check to ensure that we DO have it's parent on record
-                    //If it exist
-                    if (lookups.TryGetValue(parentPath, out parent))
-                    {
-                        //Just continue
-                        continue;
-                    }
-                    //If the item is directly below its parent container, there is no path to add
-                    if (String.IsNullOrWhiteSpace(parentName))
-                        continue;
-                    //Otherwise we need to add it, because it is missing from the list
-                    //Store each item using its current path
-                    //Since this is not a directory, we won't add the item itself
-                    AddParentNodes(lookups, rootNodes, parts, item);
-                }
-            }
-            return rootNodes;
-        }
-
-        private static void AddParentNodes(Dictionary<string, DirectoryRecord> lookups, List<DirectoryRecord> rootNodes, string[] parts, ObjectInfo item)
-        {
-            for (int i = 0; i < parts.Length - 1; i++)
-            {
-                var nodeName = String.Join("/", parts, 0, i + 1);
-                var storageUri = GetStorageUri(item);
-                var nodeKey = String.Format("{0}/{1}/{2}/{3}", storageUri, item.Account,item.Container, nodeName);
-                //If the node was already addeds, skip
-                if (lookups.ContainsKey(nodeKey))
-                    continue;
-                var newNode = new DirectoryRecord
-                                  {
-                                      DisplayName = parts[i],
-                                      ObjectInfo = new ObjectInfo
-                                                       {
-                                                           Account = item.Account,
-                                                           Container = item.Container,
-                                                           Name = nodeName,
-                                                           StorageUri=item.StorageUri,
-                                                           Content_Type = "application/directory"
-                                                       }
-                                  };
-                AddNode(rootNodes, lookups, newNode);
-            }
-        }
-
-        private static string GetStorageUri(ObjectInfo item)
-        {
-            var storageParts = item.StorageUri.ToString().Split('/');
-            var accountUri = String.Join("/", storageParts, 0, storageParts.Length - 1);
-            return accountUri;
-        }
-
-        private static void AddNode(List<DirectoryRecord> rootNodes, Dictionary<string, DirectoryRecord> lookups, DirectoryRecord newNode)
-        {
-            DirectoryRecord parent;
-            var path = newNode.ObjectInfo.Uri.ToString();
-            var parentPath = GetParentPath(path);
-            lookups[path] = newNode;
-
-            //If the record is a directory, we need to add it no matter what
-
-            //If it is a file, we need to check that its parent node exists
-            //If the parent node doesn't exist, we need to add a node for it.
-            //We need to add nodes for all parents recursively,in case they don't exist
-
-            //Does a parent item exist? 
-            if (lookups.TryGetValue(parentPath, out parent))
-            {
-                //If so, add the current item under its parent
-                parent.Directories.Add(newNode);
-                parent.Directories.Sort((x, y) => String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString()));
-            }
-            else
-                //Otherwise add it to the list of root nodes
-                rootNodes.Add(newNode);
-        }
-
-        private static string GetParentPath(string path)
-        {            
-            var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
-            if (lastIndex < 0)
-                return null;
-            var parentPath = path.Substring(0, lastIndex);
-            return parentPath;
-        }
 
         static readonly Regex PascalCaseRegex = new Regex("[a-z][A-Z]", RegexOptions.Compiled);        
         public static string Name(this  Enum value)
diff --git a/trunk/Pithos.Client.WPF/Utils/SelectiveExtensions.cs b/trunk/Pithos.Client.WPF/Utils/SelectiveExtensions.cs
new file mode 100644 (file)
index 0000000..96f8afa
--- /dev/null
@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Pithos.Client.WPF.SelectiveSynch;
+using Pithos.Interfaces;
+using Pithos.Network;
+
+namespace Pithos.Client.WPF.Utils
+{
+    public static class SelectiveExtensions
+    {
+        public static List<DirectoryRecord> LocalFolders(string accountName, string accountPath,string storageUrl)
+        {
+            var storageUri = storageUrl.EndsWith("/")
+                                 ? new Uri(storageUrl)
+                                 : new Uri(storageUrl + "/");
+
+            var cacheFolder = Path.Combine(accountPath, FolderConstants.CacheFolder);
+
+            var dir = new DirectoryInfo(accountPath);
+            var orderedItems = from directory in dir.EnumerateDirectories("*", SearchOption.AllDirectories)
+                                where !directory.FullName.StartsWith(cacheFolder,StringComparison.InvariantCultureIgnoreCase)
+                                orderby directory.FullName
+                                let relativeUrl=directory.WithProperCapitalization().AsRelativeUrlTo(accountPath)
+                                let dirUri = new Uri(storageUri, relativeUrl)    
+                                select new DirectoryRecord { DisplayName = directory.Name,Uri=dirUri};
+
+
+            return orderedItems.ToList();
+
+/*
+            //Order the items to ensure that children always come after their parents
+            var lookups = new Dictionary<string, DirectoryRecord>();
+
+            //RootNodes contains only the root nodes
+            var rootNodes = new List<DirectoryRecord>();
+
+            foreach (var newNode in orderedItems)
+            {
+                AddNode(rootNodes, lookups, newNode);
+            }
+            return rootNodes;
+*/
+        }
+        public static List<DirectoryRecord> ToTree(this IEnumerable<ObjectInfo> enumerable)
+        {
+            //Order the items to ensure that children always come after their parents
+            var orderedItems = enumerable.OrderBy(o => o.Uri.ToString());
+            //Each item is stored in lookups
+            var lookups = new Dictionary<string, DirectoryRecord>();
+
+            //RootNodes contains only the root nodes
+            var rootNodes = new List<DirectoryRecord>();
+
+            foreach (var item in orderedItems)
+            {
+                var path = item.Uri.ToString();
+                //Calculate the parent path
+                var parentPath = GetParentPath(path);
+                var parentName = GetParentPath(item.Name);
+                DirectoryRecord parent;
+
+
+                //First ensure that the parent items exist
+
+                var parts = item.Name.Split('/');
+
+                if (item.IsDirectory)
+                {
+                    AddParentNodes(lookups, rootNodes, parts, item);
+
+                    //Store each item using its current path
+                    var newNode = new DirectoryRecord { DisplayName = parts.Last(), ObjectInfo = item };
+                    AddNode(rootNodes, lookups, newNode);
+                }
+                else
+                {
+                    //Dont't add files
+                    //But check to ensure that we DO have it's parent on record
+                    //If it exist
+                    if (lookups.TryGetValue(parentPath, out parent))
+                    {
+                        //Just continue
+                        continue;
+                    }
+                    //If the item is directly below its parent container, there is no path to add
+                    if (String.IsNullOrWhiteSpace(parentName))
+                        continue;
+                    //Otherwise we need to add it, because it is missing from the list
+                    //Store each item using its current path
+                    //Since this is not a directory, we won't add the item itself
+                    AddParentNodes(lookups, rootNodes, parts, item);
+                }
+            }
+            return rootNodes;
+        }
+
+        private static void AddParentNodes(Dictionary<string, DirectoryRecord> lookups, List<DirectoryRecord> rootNodes, string[] parts, ObjectInfo item)
+        {
+            for (int i = 0; i < parts.Length - 1; i++)
+            {
+                var nodeName = String.Join("/", parts, 0, i + 1);
+                var storageUri = GetStorageUri(item);
+                var nodeKey = String.Format("{0}/{1}/{2}/{3}", storageUri, item.Account, item.Container, nodeName);
+                //If the node was already addeds, skip
+                if (lookups.ContainsKey(nodeKey))
+                    continue;
+                var newNode = new DirectoryRecord
+                {
+                    DisplayName = parts[i],
+                    ObjectInfo = new ObjectInfo
+                    {
+                        Account = item.Account,
+                        Container = item.Container,
+                        Name = nodeName,
+                        StorageUri = item.StorageUri,
+                        Content_Type = "application/directory"
+                    }
+                };
+                AddNode(rootNodes, lookups, newNode);
+            }
+        }
+
+        private static string GetStorageUri(ObjectInfo item)
+        {
+            var storageParts = item.StorageUri.ToString().Split('/');
+            var accountUri = String.Join("/", storageParts, 0, storageParts.Length - 1);
+            return accountUri;
+        }
+
+        private static void AddNode(List<DirectoryRecord> rootNodes, Dictionary<string, DirectoryRecord> lookups, DirectoryRecord newNode)
+        {
+            DirectoryRecord parent;
+            var path = newNode.Uri.ToString();
+            var parentPath = GetParentPath(path);
+            lookups[path] = newNode;
+
+            //If the record is a directory, we need to add it no matter what
+
+            //If it is a file, we need to check that its parent node exists
+            //If the parent node doesn't exist, we need to add a node for it.
+            //We need to add nodes for all parents recursively,in case they don't exist
+
+            //Does a parent item exist? 
+            if (lookups.TryGetValue(parentPath, out parent))
+            {
+                //If so, add the current item under its parent
+                parent.Directories.Add(newNode);
+                parent.Directories.Sort((x, y) => String.CompareOrdinal(x.Uri.ToString(), y.Uri.ToString()));
+            }
+            else
+                //Otherwise add it to the list of root nodes
+                rootNodes.Add(newNode);
+        }
+
+        private static string GetParentPath(string path)
+        {
+            var lastIndex = path.LastIndexOf("/", StringComparison.Ordinal);
+            if (lastIndex < 0)
+                return null;
+            var parentPath = path.Substring(0, lastIndex);
+            return parentPath;
+        }
+
+    }
+}
index 7594eb7..613b632 100644 (file)
     <Compile Include="Agents\SnapshotDifferencer.cs" />
     <Compile Include="Agents\Uploader.cs" />
     <Compile Include="Agents\WorkflowAgent.cs" />
-    <Compile Include="CodeFile1.cs" />
     <Compile Include="DynamicDictionary.cs" />
     <Compile Include="EnumerableExtensions.cs" />
     <Compile Include="FileHashMap.cs" />