Converted message arrays to Uri arrays
authorPanagiotis Kanavos <pkanavos@gmail.com>
Wed, 22 Feb 2012 11:57:43 +0000 (13:57 +0200)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Wed, 22 Feb 2012 11:57:43 +0000 (13:57 +0200)
30 files changed:
trunk/Pithos.Client.WPF/App.xaml.cs
trunk/Pithos.Client.WPF/AppBootstrapper.cs
trunk/Pithos.Client.WPF/Configuration/PithosSettings.cs
trunk/Pithos.Client.WPF/Preferences/PreferencesView.xaml
trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
trunk/Pithos.Client.WPF/Properties/AssemblyInfo.cs
trunk/Pithos.Client.WPF/Properties/Settings.Designer.cs
trunk/Pithos.Client.WPF/Properties/Settings.settings
trunk/Pithos.Client.WPF/SelectiveSynch/DirectoryRecord.cs
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchChanges.cs
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchView.xaml
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchView.xaml.cs
trunk/Pithos.Client.WPF/SelectiveSynch/SelectiveSynchViewModel.cs
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Client.WPF/app.config
trunk/Pithos.Core.Test/MockSettings.cs
trunk/Pithos.Core/Agents/CollectionExtensions.cs
trunk/Pithos.Core/Agents/PollAgent.cs
trunk/Pithos.Core/FileState.cs
trunk/Pithos.Core/PithosMonitor.cs
trunk/Pithos.Interfaces/IPithosSettings.cs
trunk/Pithos.Interfaces/ObjectInfo.cs
trunk/Pithos.Interfaces/PithosSettingsData.cs
trunk/Pithos.Network/CloudFilesClient.cs
trunk/Pithos.Network/ICloudClient.cs
trunk/Pithos.Setup.x64/Pithos.Setup.x64.vdproj
trunk/Pithos.Setup.x86/Pithos.Setup.x86.vdproj
trunk/Pithos.ShellExtensions.Test/TestPithosSettings.cs
trunk/Pithos.ShellExtensions/ShellSettings.cs
trunk/Pithos.ShellExtensions/TestPithosSettings.cs

index 62e0b0b..98c49ac 100644 (file)
@@ -49,6 +49,7 @@ using System.Net;
 using System.Net.Mail;
 using System.Reflection;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
 using Caliburn.Micro;
@@ -92,6 +93,13 @@ namespace Pithos.Client.WPF
                 return;
             }
             
+            //TODO: Possibly add a delay here?
+            if (e.Args.Contains("startup"))
+            {
+                if (Settings.Default.StartupDelay>TimeSpan.Zero)
+                    Thread.Sleep(Settings.Default.StartupDelay);
+            }
+
             var splashScreen = new SplashScreen("images/logo.png");
             splashScreen.Show(true);
             
index 56d534e..8f1eaf1 100644 (file)
@@ -67,36 +67,36 @@ namespace Pithos.Client.WPF
        {
                CompositionContainer container;
 
-           public AppBootstrapper()
-           {
-            LogManager.GetLog = type => new log4netLogger(type);
-               UpgradeSettings();
-
-           }
-
-           private void UpgradeSettings()
-           {
-            if (Settings.Default.MustUpgrade)
-            {
-                Settings.Default.Upgrade();
-                Settings.Default.MustUpgrade = false;
-                Settings.Default.Save();
-            }
-           }
-
-           /// <summary>
+               public AppBootstrapper()
+               {
+                       LogManager.GetLog = type => new log4netLogger(type);
+                       UpgradeSettings();
+
+               }
+
+               private void UpgradeSettings()
+               {
+                       if (Settings.Default.MustUpgrade)
+                       {
+                               Settings.Default.Upgrade();
+                               Settings.Default.MustUpgrade = false;
+                               Settings.Default.Save();
+                       }
+               }
+
+               /// <summary>
                /// By default, we are configured to use MEF
                /// </summary>
                protected override void Configure() {
-                   var catalog = new AggregateCatalog(
-                       AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
-                       );
+                       var catalog = new AggregateCatalog(
+                               AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
+                               );
 
-            Type[] types = { typeof(PithosMonitor), typeof(CloudFilesClient) };
-            foreach (var type in types)
-            {
-                catalog.Catalogs.Add(new AssemblyCatalog(type.Assembly));
-            }
+                       Type[] types = { typeof(PithosMonitor), typeof(CloudFilesClient) };
+                       foreach (var type in types)
+                       {
+                               catalog.Catalogs.Add(new AssemblyCatalog(type.Assembly));
+                       }
 
                        container = new CompositionContainer(catalog,true);
 
@@ -105,13 +105,14 @@ namespace Pithos.Client.WPF
                        batch.AddExportedValue<IWindowManager>(new WindowManager());
                        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
                        batch.AddExportedValue(container);
-                   batch.AddExportedValue(catalog);
+                       batch.AddExportedValue(catalog);
 
 
                        container.Compose(batch);
-
-            ConventionManager.AddElementConvention<MenuItem>(ItemsControl.ItemsSourceProperty, "DataContext", "Click");
-               ConventionManager.AddElementConvention<IntegerUpDown>(IntegerUpDown.ValueProperty, "Value", "ValueChanged");
+                   
+                       ConventionManager.AddElementConvention<MenuItem>(ItemsControl.ItemsSourceProperty, "DataContext", "Click");
+                       ConventionManager.AddElementConvention<IntegerUpDown>(IntegerUpDown.ValueProperty, "Value", "ValueChanged");
+                   ConventionManager.AddElementConvention<BusyIndicator>(BusyIndicator.IsBusyProperty, "IsBusy", "DataContextChanged");
                }
 
                protected override object GetInstance(Type serviceType, string key)
index aa789e5..3a88d78 100644 (file)
@@ -191,6 +191,18 @@ namespace Pithos.Client.WPF.Configuration
             }
         }
 
+        public TimeSpan StartupDelay
+        {
+            get { return _settings.StartupDelay; }
+            set
+            {
+                if (value < TimeSpan.Zero)
+                    throw new ArgumentOutOfRangeException();
+                _settings.StartupDelay = value;
+            }
+        }
+
+
         public bool StartOnSystemStartup
         {
             get { return _settings.StartOnSystemStartup; }
index f53d1f6..a88a868 100644 (file)
                     <extToolkit:IntegerUpDown x:Name="Settings_PollingInterval" HorizontalAlignment="Left" Width="100" Margin="5,0" Watermark="Enter seconds" Minimum="10" />                    
                     <TextBlock Text="Hashing Parallelism" Margin="5"/>
                     <extToolkit:IntegerUpDown x:Name="Settings_HashingParallelism" HorizontalAlignment="Left" Width="100" Margin="5,0" Watermark="Enter number of tasks" Minimum="1" />                    
+                    <TextBlock Text="Startup Delay (minutes)" Margin="5"/>
+                    <extToolkit:IntegerUpDown x:Name="StartupDelay" HorizontalAlignment="Left" Width="100" Margin="5,0" Watermark="Enter number of tasks" Minimum="0" />                    
                 </StackPanel>
             </TabItem>
         </TabControl>
index 54e5bb9..fe643b9 100644 (file)
@@ -162,6 +162,18 @@ namespace Pithos.Client.WPF.Preferences
         }
         #endregion
 
+
+        public int StartupDelay
+        {
+            get { return (int) Settings.StartupDelay.TotalMinutes; }
+            set
+            {
+                if (value<0)
+                    throw new ArgumentOutOfRangeException("value","The Startup Delay must be greater or equal to 0");
+                Settings.StartupDelay = TimeSpan.FromMinutes(value);
+                NotifyOfPropertyChange(()=>StartupDelay);
+            }
+        }
        
         #region Commands
         
@@ -173,9 +185,9 @@ namespace Pithos.Client.WPF.Preferences
         public void SelectiveSyncFolders()
         {
             var monitor = Shell.Monitors[CurrentAccount.AccountName];
-            var folders=monitor.GetRootFolders().ToList();
+            
 
-            var model = new SelectiveSynchViewModel(folders,_events,CurrentAccount);
+            var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount);
             if (_windowManager.ShowDialog(model) == true)
             {
                 
index 010aa18..a285c50 100644 (file)
@@ -93,5 +93,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.1.0.0")]
-[assembly: AssemblyFileVersionAttribute("0.1.20220.2042")]
+[assembly: AssemblyVersion("0.7.0.0")]
+[assembly: AssemblyFileVersionAttribute("0.7.20221.2042")]
index 90b5c30..d54d7e2 100644 (file)
@@ -306,5 +306,17 @@ namespace Pithos.Client.WPF.Properties {
                 this["HashingParallelism"] = value;
             }
         }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("00:01:00")]
+        public global::System.TimeSpan StartupDelay {
+            get {
+                return ((global::System.TimeSpan)(this["StartupDelay"]));
+            }
+            set {
+                this["StartupDelay"] = value;
+            }
+        }
     }
 }
index e6e237f..f1229d0 100644 (file)
@@ -77,5 +77,8 @@
     <Setting Name="HashingParallelism" Type="System.Byte" Scope="User">
       <Value Profile="(Default)">1</Value>
     </Setting>
+    <Setting Name="StartupDelay" Type="System.TimeSpan" Scope="User">
+      <Value Profile="(Default)">00:01:00</Value>
+    </Setting>
   </Settings>
 </SettingsFile>
\ No newline at end of file
index dde5904..29bbf05 100644 (file)
@@ -47,20 +47,33 @@ using System.IO;
 using System.Linq;
 using System.Text;
 using Caliburn.Micro;
+using Pithos.Core.Agents;
+using Pithos.Interfaces;
 
 namespace Pithos.Client.WPF.SelectiveSynch
 {
     public class DirectoryRecord : PropertyChangedBase,IEnumerable<DirectoryRecord>
     {
-        public DirectoryInfo Info { get; set; }
+        private ObjectInfo _objectInfo;
+        public ObjectInfo ObjectInfo
+        {
+            get { return _objectInfo; }
+            set
+            {                
+                _objectInfo = value;
+                Uri = value.Uri;
+            }
+        }
 
+        public Uri Uri { get; set; }
+        //public DirectoryInfo LocalInfo { get; set; }
 
         DirectoryRecord _parent;
 
         public bool Added { get; set; }
         public bool Removed { get; set; }
 
-        private bool? _isChecked;
+        private bool? _isChecked=true;
         #region IsChecked
 
         /// <summary>
@@ -88,7 +101,7 @@ namespace Pithos.Client.WPF.SelectiveSynch
             Removed = !(_isChecked??true);
 
             if (updateChildren && _isChecked.HasValue)
-                this.Directories.ForEach(c => c.SetIsChecked(_isChecked, true, false));
+                this.Directories.Apply(c => c.SetIsChecked(_isChecked, true, false));
 
             if (updateParent && _parent != null)
                 _parent.VerifyCheckState();
@@ -99,9 +112,9 @@ namespace Pithos.Client.WPF.SelectiveSynch
         void VerifyCheckState()
         {
             bool? state = null;
-            for (int i = 0; i < this.Directories.Count; ++i)
+            for (var i = 0; i < this.Directories.Count(); ++i)
             {
-                bool? current = this.Directories[i].IsChecked;
+                bool? current = this.Directories.ElementAt(i).IsChecked;
                 if (i == 0)
                 {
                     state = current;
@@ -120,7 +133,7 @@ namespace Pithos.Client.WPF.SelectiveSynch
 
         public bool IsInitiallySelected { get; private set; }
 
-        readonly Lazy<List<DirectoryRecord>> _directories = new Lazy<List<DirectoryRecord>>();
+        /*readonly Lazy<List<DirectoryRecord>> _directories = new Lazy<List<DirectoryRecord>>();
 
         public List<DirectoryRecord> Directories
         {
@@ -128,16 +141,48 @@ namespace Pithos.Client.WPF.SelectiveSynch
             {
                 return _directories.Value;
             }
+        }*/
+
+        private IEnumerable<DirectoryRecord> _directories=new List<DirectoryRecord>();
+        public IEnumerable<DirectoryRecord> Directories
+        {
+            get { return _directories; }
+            set { _directories = value; }
         }
 
-        public DirectoryRecord(string ignorePath)
+        public DirectoryRecord()
         {
-            _directories = new Lazy<List<DirectoryRecord>>(() => 
+            
+/*
+             _directories = new Lazy<List<DirectoryRecord>>(() => 
+                new List<DirectoryRecord>());
+*/
+/*
+             _directories = new Lazy<List<DirectoryRecord>>(() => 
                 (from directory in Info.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
                 where !directory.FullName.StartsWith(ignorePath)
                 select new DirectoryRecord(ignorePath) { Info = directory }).ToList());
+*/
         }
 
+        private string _displayName;
+        public string DisplayName
+        {
+            get
+            {
+                if (ObjectInfo != null)
+                    return ObjectInfo.Name;
+                return _displayName;
+            }
+            set { _displayName = value; }
+        }
+
+        public DirectoryRecord(string rootPath,ObjectInfo info)
+        {
+            var relativePath = info.RelativeUrlToFilePath(info.Account);
+            //LocalInfo = new DirectoryInfo(Path.Combine(rootPath, relativePath));
+            ObjectInfo = info;
+        }
 
 
 /*
index acf53aa..4801079 100644 (file)
@@ -49,8 +49,9 @@ namespace Pithos.Client.WPF.SelectiveSynch
 {
     public class SelectiveSynchChanges
     {
+        public Uri[] Uris { get; set; }
         public AccountSettings Account { get; set; }
-        public string[] Added { get; set; }
-        public string[] Removed { get; set; }
+        public Uri[] Added { get; set; }
+        public Uri[] Removed { get; set; }
     }
 }
index 645e31f..dd3d6db 100644 (file)
@@ -1,31 +1,44 @@
 ï»¿<Window x:Class="Pithos.Client.WPF.SelectiveSynch.SelectiveSynchView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-        xmlns:local="clr-namespace:Pithos.Client.WPF.SelectiveSynch" Title="Selective Synch" Height="300" Width="300" >
-    <Window.Resources>        
-        
-        <Style x:Key="TreeItemStyle" TargetType="TreeViewItem">
-            <Setter Property="IsExpanded" Value="True" />
-            <Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" />
-            <Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
-            <Setter Property="local:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
-            <Setter Property="local:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />
-        </Style>
-
-        <HierarchicalDataTemplate x:Key="CheckboxStyle" DataType="{x:Type local:DirectoryRecord}"
+        xmlns:local="clr-namespace:Pithos.Client.WPF.SelectiveSynch"
+        xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
+        xmlns:Converters="clr-namespace:Pithos.Client.WPF.Converters" 
+        Title="Selective Synch" Height="300" Width="300" 
+        ShowInTaskbar="true"
+        WindowStartupLocation="CenterScreen"
+        Icon="/Pithos.Client.WPF;component/Images/PithosTaskbar.png"
+        Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}">
+    <Window.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="..\PithosStyles.xaml" />
+            </ResourceDictionary.MergedDictionaries>
+            <Converters:NullToVisibilityConverter x:Key="NullToVisible" />
+            <Style x:Key="TreeItemStyle" TargetType="TreeViewItem">
+                <Setter Property="IsExpanded" Value="True" />
+                <Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" />
+                <Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
+                <Setter Property="local:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
+                <Setter Property="local:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />
+            </Style>
+            <HierarchicalDataTemplate x:Key="CheckboxStyle" DataType="{x:Type local:DirectoryRecord}"
                                     ItemsSource="{Binding Directories}" >
-            <StackPanel Orientation="Horizontal">
-                <CheckBox
+                <StackPanel Orientation="Horizontal">
+                    <CheckBox
             Focusable="False" 
             IsChecked="{Binding IsChecked}" 
             VerticalAlignment="Center"
             />
-                <ContentPresenter 
-            Content="{Binding Info.Name, Mode=OneTime}" 
+                    <ContentPresenter 
+            Content="{Binding DisplayName, Mode=OneTime}" 
             Margin="2,0"
             />
-            </StackPanel>
-        </HierarchicalDataTemplate>
+                </StackPanel>
+            </HierarchicalDataTemplate>
+
+        </ResourceDictionary>
+
 
     </Window.Resources>
     <Grid>
             <RowDefinition Height="*"/>
             <RowDefinition Height="Auto"/>
         </Grid.RowDefinitions>
-        <TreeView Grid.Row="0" Name="PithosDirectory" 
+        <extToolkit:BusyIndicator Name="IsBusy" Grid.Row="0" BusyContent="Retrieving folders ..." DisplayAfter="0">
+            <TreeView  Name="RootNodes" 
                   ItemContainerStyle="{StaticResource TreeItemStyle}" 
                   ItemTemplate="{StaticResource CheckboxStyle}">
-        </TreeView>
+            </TreeView>
+        </extToolkit:BusyIndicator>
         <StackPanel Grid.Row="1">
             <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right">
-                <Button Name="SaveChanges" Content="OK" Margin="5,5,10,5" />
-                <Button Name="RejectChanges" Content="Cancel" Margin="5,5,10,5" />                
+                <Button Name="SaveChanges" Content="OK" Margin="5,5,10,5"  Style="{StaticResource ButtonStyle}"/>
+                <Button Name="RejectChanges" Content="Cancel" Margin="5,5,10,5"  Style="{StaticResource ButtonStyle}"/>                
             </StackPanel>
         </StackPanel>
     </Grid>
index c4039bb..0bc26f1 100644 (file)
@@ -60,7 +60,7 @@ namespace Pithos.Client.WPF.SelectiveSynch
     public partial class SelectiveSynchView : Window
     {
         public SelectiveSynchView()
-        {
+        {            
             InitializeComponent();
         }
     }
index 988eff0..2539edb 100644 (file)
@@ -46,8 +46,11 @@ using System.Collections.Specialized;
 using System.IO;
 using System.Linq;
 using System.Text;
+using System.Threading.Tasks;
 using Caliburn.Micro;
 using Pithos.Client.WPF.Properties;
+using Pithos.Core;
+using Pithos.Core.Agents;
 using Pithos.Interfaces;
 using Pithos.Network;
 
@@ -55,24 +58,9 @@ namespace Pithos.Client.WPF.SelectiveSynch
 {
     class SelectiveSynchViewModel:Screen
     {
+        private const string DirectoryType = "application/directory";
         private IEventAggregator _events ;
 
-        private string _rootPath;
-        private string _cachePath;
-        public string RootPath
-        {
-            get { return _rootPath; }
-            set
-            {
-                _rootPath = value;
-                _cachePath = Path.Combine(_rootPath, FolderConstants.CacheFolder);
-                _pithosDirectory = new ObservableCollection<DirectoryRecord>{
-                        new DirectoryRecord(_cachePath) {Info = new DirectoryInfo(value)}};
-                NotifyOfPropertyChange(() => RootPath);
-                NotifyOfPropertyChange(()=>PithosDirectory);
-            }
-        }
-
         private string _title;
         public string Title
         {
@@ -86,48 +74,119 @@ namespace Pithos.Client.WPF.SelectiveSynch
 
         public AccountSettings Account { get; set; }
 
-        private ObservableCollection<DirectoryRecord> _pithosDirectory;
-        public ObservableCollection<DirectoryRecord> PithosDirectory
+        private readonly ObservableCollection<DirectoryRecord> _rootNodes=new ObservableCollection<DirectoryRecord>();
+        public ObservableCollection<DirectoryRecord> RootNodes
         {
-            get { return _pithosDirectory; }
+            get { return _rootNodes; }
         }
 
-        private ObservableCollection<DirectoryInfo> _checks;
-        public ObservableCollection<DirectoryInfo> Checks
+        private ObservableCollection<ObjectInfo> _checks;
+        private PithosMonitor _monitor;
+        private bool _isBusy=true;
+
+        public ObservableCollection<ObjectInfo> Checks
         {
             get { return _checks; }
         }
 
         public void GetChecks()
         {
-            var root = PithosDirectory[0];            
-            _checks = new ObservableCollection<DirectoryInfo>(
+            var root = RootNodes[0];            
+            _checks = new ObservableCollection<ObjectInfo>(
                 from record in root
                 where record.IsChecked==true
-                select record.Info);
+                select record.ObjectInfo);
             NotifyOfPropertyChange(() => Checks);
         }
 
-        public SelectiveSynchViewModel(IEnumerable<string> folders, IEventAggregator events, AccountSettings account)
+        public SelectiveSynchViewModel(PithosMonitor monitor, IEventAggregator events, AccountSettings account)
         {
             Account = account;
             AccountName = account.AccountName;
             Title = account.AccountName;
-            RootPath = account.RootPath;
+            _monitor = monitor;
+            _events = events;
+            TaskEx.Run(LoadRootNode);
+        }
+
+        private void LoadRootNode()
+        {
+            var client = _monitor.CloudClient;
+
+            var dirs = from container in client.ListContainers(_monitor.UserName)
+                       select new DirectoryRecord
+                                  {
+                                      DisplayName = container.Name,
+                                      Directories = (from dir in client.ListObjects(_monitor.UserName, container.Name, "")
+                                                     where dir.Content_Type == DirectoryType
+                                                     select new DirectoryRecord { DisplayName = dir.Name, ObjectInfo = dir }).ToList()
+                                  };
+            var ownFolders = dirs.ToList();
+
+            var accounts = client.ListSharingAccounts();
+
+            var accountNodes=from account in client.ListSharingAccounts()
+                             select new DirectoryRecord
+                             {
+                                DisplayName=account.name,
+                                Directories=(from container in client.ListContainers(account.name)
+                                            select new DirectoryRecord
+                                                        {
+                                                            DisplayName=container.Name,
+                                                            Directories=(from folder in client.ListObjects(account.name,container.Name,"")
+                                                                        where folder.Content_Type==DirectoryType
+                                                                        select new DirectoryRecord{DisplayName=folder.Name,ObjectInfo=folder}).ToList()
+                                                        }).ToList()
+                             };                                                          
+
+            var othersNode = new DirectoryRecord
+                                 {
+                                     DisplayName = "Others",
+                                     Directories=accountNodes.ToList()
+                                 };
+
+            
+            var rootItem = new DirectoryRecord
+                               {
+                                   DisplayName = AccountName ,
+                                   Directories = ownFolders.ToList()
+                               };
+            
+
+            SetInitialSelections(Account);
+            
+            Execute.OnUIThread(()=>
+                                   {
+                                       this.RootNodes.Add(rootItem);
+                                       this.RootNodes.Add(othersNode);
+                                       IsBusy = false;
+                                   });
+        }
 
-            SetInitialSelections(account);
+        public bool IsBusy
+        {
+            get {
+                return _isBusy;
+            }
+            set {
+                _isBusy = value;
+                NotifyOfPropertyChange(()=>IsBusy);
+            }
         }
 
         private void SetInitialSelections(AccountSettings account)
         {
             var selections = account.SelectiveFolders;
+
             if (selections.Count == 0)
                 return;
-            var root = PithosDirectory[0];
-            var selects= from record in root
-                             where selections.Contains(record.Info.FullName)
-                             select record;
-            selects.Apply(record=>record.IsChecked=true);            
+            
+            var selects = from rootRecord in RootNodes
+                          from record in rootRecord
+                          where record.ObjectInfo!=null &&  selections.Contains(record.ObjectInfo.Name)
+                          select record;
+
+            selects.Apply(record=>record.IsChecked=true);
         }
 
         protected string AccountName { get; set; }
@@ -137,16 +196,22 @@ namespace Pithos.Client.WPF.SelectiveSynch
             var selections = GetSelectedFolderNames();
 
             SaveSettings(selections);
-            var root = PithosDirectory[0];
             
-            var added= (from record in root
-                         where record.Added
-                         select record.Info.FullName.ToLower()).ToArray();
-            var removed= (from record in root
-                         where record.Removed
-                         select record.Info.FullName.ToLower()).ToArray();            
-
-            _events.Publish(new SelectiveSynchChanges{Account=Account,Added=added,Removed=removed});
+            //RootNodes is an ObservableCollection, it can't be enumerated iterativelly
+            
+            var added= (from root in RootNodes
+                        from record in root
+                         where record.Added && record.Uri != null
+                         select record.Uri).ToArray();
+            var removed = (from root in RootNodes
+                            from record in root
+                          where record.Removed && record.Uri != null
+                         select record.Uri).ToArray();
+            var uris = (from root in RootNodes
+                        from record in root
+                        where record.IsChecked==true && record.Uri != null
+                        select record.Uri).ToArray();
+            _events.Publish(new SelectiveSynchChanges{Account=Account,Uris=uris,Added=added,Removed=removed});
             
 
             
@@ -164,10 +229,12 @@ namespace Pithos.Client.WPF.SelectiveSynch
 
         private string[] GetSelectedFolderNames()
         {
-            var root = PithosDirectory[0];
-            var selections = from record in root
-                         where record.IsChecked == true
-                         select record.Info.FullName;
+
+            var selections = from node in RootNodes
+                             from childNode in node
+                             where childNode.ObjectInfo != null
+                                   && childNode.IsChecked == true
+                             select node.ObjectInfo.Uri.ToString();
             return selections.ToArray();
         }
 
index 98e4627..493d5bc 100644 (file)
@@ -796,8 +796,7 @@ namespace Pithos.Client.WPF {
                        PithosMonitor monitor;
                        if (_monitors.TryGetValue(accountName, out monitor))
                        {
-                               monitor.AddSelectivePaths(message.Added);
-                               monitor.RemoveSelectivePaths(message.Removed);
+                               monitor.SetSelectivePaths(message.Uris,message.Added,message.Removed);
 
                        }
                        
index c0902e3..cf18a8f 100644 (file)
@@ -84,6 +84,9 @@
       <setting name="HashingParallelism" serializeAs="String">
         <value>1</value>
       </setting>
+      <setting name="StartupDelay" serializeAs="String">
+        <value>00:01:00</value>
+      </setting>
     </Pithos.Client.WPF.Properties.Settings>
   </userSettings>
   <connectionStrings>
index 0257e77..b8fc5b8 100644 (file)
@@ -38,6 +38,7 @@ namespace Pithos.Core.Test
         public bool ExtensionsActivated { get; set; }
 
         public int PollingInterval { get; set; }
+        public TimeSpan StartupDelay { get; set; }
 
         public byte HashingParallelism { get; set; }
 
index 3d215e7..4138953 100644 (file)
@@ -40,6 +40,7 @@
  */\r
 #endregion\r
 using System.Collections.Concurrent;\r
+using Pithos.Interfaces;\r
 \r
 namespace Pithos.Core.Agents\r
 {\r
@@ -81,5 +82,19 @@ namespace Pithos.Core.Agents
 \r
             queue.AddFromEnumerable(temp);\r
         }\r
+\r
+\r
+        public static IEnumerable<ObjectInfo> FilterBelow(this IEnumerable<ObjectInfo> infos,List<Uri> filterUris  )\r
+        {\r
+            if (filterUris == null)\r
+                return infos;\r
+            if (filterUris.Count == 0)\r
+                return infos;\r
+            var filteredUris = from info in infos\r
+                                  where !filterUris.Any(s => info.Uri.ToString()\r
+                                      .StartsWith(s.ToString()))\r
+                                  select info;\r
+            return filteredUris;\r
+        }\r
     }\r
 }\r
index cb4b3bc..b1e1d0e 100644 (file)
@@ -189,6 +189,7 @@ namespace Pithos.Core.Agents
 \r
                 try\r
                 {\r
+                    //Wait for any deletions to finish\r
                     await NetworkAgent.GetDeleteAwaiter();\r
                     //Get the poll time now. We may miss some deletions but it's better to keep a file that was deleted\r
                     //than delete a file that was created while we were executing the poll                    \r
@@ -242,12 +243,16 @@ namespace Pithos.Core.Agents
 \r
                         var differencer = _differencer.PostSnapshot(accountInfo, cleanRemotes);\r
 \r
-                        ProcessDeletedFiles(accountInfo, differencer.Deleted, pollTime);\r
+                        ProcessDeletedFiles(accountInfo, differencer.Deleted.FilterBelow(SelectiveUris), pollTime);\r
+\r
+                        // @@@ NEED To add previous state here as well, To compare with previous hash\r
+\r
+                        \r
 \r
                         //Create a list of actions from the remote files\r
-                        var allActions = ChangesToActions(accountInfo, differencer.Changed)\r
+                        var allActions = ChangesToActions(accountInfo, differencer.Changed.FilterBelow(SelectiveUris))\r
                                         .Union(\r
-                                        CreatesToActions(accountInfo, differencer.Created));\r
+                                        CreatesToActions(accountInfo, differencer.Created.FilterBelow(SelectiveUris)));\r
 \r
                         //And remove those that are already being processed by the agent\r
                         var distinctActions = allActions\r
@@ -275,6 +280,7 @@ namespace Pithos.Core.Agents
         }\r
 \r
         AccountsDifferencer _differencer = new AccountsDifferencer();\r
+        private List<Uri> _selectiveUris=new List<Uri>();\r
 \r
         /// <summary>\r
         /// Deletes local files that are not found in the list of cloud files\r
@@ -451,5 +457,17 @@ namespace Pithos.Core.Agents
                 Directory.CreateDirectory(path);\r
             }\r
         }\r
+\r
+        public void SetSyncUris(string[] uris)\r
+        {\r
+            var selectiveUris = uris.Select(uri => new Uri(uri));\r
+            SelectiveUris=selectiveUris.ToList();\r
+        }\r
+\r
+        protected List<Uri> SelectiveUris\r
+        {\r
+            get { return _selectiveUris;}\r
+            set { _selectiveUris = value; }\r
+        }\r
     }\r
 }\r
index 5e05c35..4a764c5 100644 (file)
@@ -44,6 +44,8 @@ using System.IO;
 using System.Threading.Tasks;
 using Castle.ActiveRecord;
 using Castle.ActiveRecord.Framework;
+using Castle.ActiveRecord.Queries;
+using NHibernate.Criterion;
 using Pithos.Core.Agents;
 using Pithos.Interfaces;
 using Pithos.Network;
@@ -417,6 +419,26 @@ namespace Pithos.Core
                         throw;
                 }
         }
+
+        public static void RemovePaths(IEnumerable<string> removed)
+        {
+            
+            var disjunction = new Disjunction();
+
+            foreach (var path in removed)
+            {
+                disjunction.Add(Restrictions.On<FileState>(s => s.FilePath).IsLike(path, MatchMode.Start));
+            }
+
+            
+            
+            var query=QueryOver.Of<FileState>().Where(disjunction);
+            var aq = new ProjectionQuery<FileState,Guid>(query.DetachedCriteria,
+                        Projections.ProjectionList().Add(Projections.Id()));
+            var ids=aq.Execute();
+            FileState.DeleteAll(ids);
+                
+        }
     }
 
     [ActiveRecord("Tags")]
index 9d0d7b7..6c18da1 100644 (file)
@@ -238,6 +238,13 @@ namespace Pithos.Core
             
             StatusKeeper.StartProcessing(_cancellationSource.Token);
             IndexLocalFiles();
+            //Extract the URIs from the string collection
+            var settings = Settings.Accounts.First(s => s.AccountName == _accountInfo.UserName);
+            var selectiveUrls=new string[settings.SelectiveFolders.Count];
+            settings.SelectiveFolders.CopyTo(selectiveUrls,0);
+
+            SetSelectivePaths(selectiveUrls,null,null);
+            
             StartWatcherAgent();
 
             StartNetworkAgent();
@@ -468,28 +475,36 @@ namespace Pithos.Core
             StatusKeeper.ChangeRoots(oldPath, newPath);
         }
 
-        public void AddSelectivePaths(string[] added)
+        public void SetSelectivePaths(string[] uris,string[] added, string[] removed)
         {
-           /* FileAgent.SelectivePaths.AddRange(added);
-            NetworkAgent.SyncPaths(added);*/
+            //Convert the uris to paths
+            var selectivePaths = (from string selectiveUrl in uris
+                                    select new Uri(selectiveUrl)
+                                    .MakeRelativeUri(_accountInfo.StorageUri)
+                                    .RelativeUriToFilePath());
+
+            FileAgent.SelectivePaths=selectivePaths.ToList();
+            PollAgent.SetSyncUris(uris);
+            RemoveSelectivePaths(removed);
+
         }
 
-        public void RemoveSelectivePaths(string[] removed)
+        /// <summary>
+        /// Delete the folders that were removed from synchronization
+        /// </summary>
+        /// <param name="removed"></param>
+        private void RemoveSelectivePaths(IEnumerable<string> removed)
         {
-            FileAgent.SelectivePaths.RemoveAll(removed.Contains);
+            if (removed == null)
+                return;
+
             foreach (var removedPath in removed.Where(Directory.Exists))
             {
                 Directory.Delete(removedPath,true);
             }
-        }
 
-        public IEnumerable<ObjectInfo> GetRootFolders()
-        {
-            var dirs = from container in CloudClient.ListContainers(UserName)
-                       from dir in CloudClient.ListObjects(UserName, container.Name, "")
-                       where dir.Content_Type=="application/directory"                       
-                       select dir;
-            return dirs;
+            //Ensure we remove any file state below the deleted folders
+            FileState.RemovePaths(removed);
         }
 
         public ObjectInfo GetObjectInfo(string filePath)
index d6d2158..7ba4429 100644 (file)
@@ -76,6 +76,7 @@ namespace Pithos.Interfaces
         bool ExtensionsActivated { get; set; }
 
         int PollingInterval { get; set; }
+        TimeSpan StartupDelay { get; set; }
         byte HashingParallelism { get; set; }
 
         void Save();
index 205686c..d9f49a7 100644 (file)
@@ -127,10 +127,22 @@ namespace Pithos.Interfaces
 
         public Stream Stream { get; set; }
 
+
+        public Uri StorageUri { get; set; }
+
         public string Account { get; set; }
 
         public string Container { get; set; }
 
+        public Uri Uri
+        {
+            get
+            {
+                var relativeUrl=String.Format("{0}/{1}/{2}",Account, Container,Name);
+                return new Uri(StorageUri,relativeUrl);
+            }
+        }
+
         public string ContendDisposition { get; set; }
 
         public string ContentEncoding { get; set; }
@@ -223,6 +235,8 @@ namespace Pithos.Interfaces
             Last_Modified = DateTime.MinValue
         };
 
+        
+
         public string RelativeUrlToFilePath(string currentAccount)
         {
             if (Name==null)
index af6297a..9d50916 100644 (file)
@@ -69,6 +69,7 @@ namespace Pithos.Interfaces
         public string ProxyDomain { get; set; }
         public bool ProxyAuthentication { get; set; }
         public bool ExtensionsActivated { get; set; }
+        public TimeSpan StartupDelay { get; set; }
         public int PollingInterval { get; set; }
         public byte HashingParallelism { get; set; }
 
@@ -98,6 +99,7 @@ namespace Pithos.Interfaces
             ProxyAuthentication = other.ProxyAuthentication;
             ExtensionsActivated = other.ExtensionsActivated;
             PollingInterval = other.PollingInterval;
+            StartupDelay = other.StartupDelay;
         }
 
         public virtual void Save()
index 7dac20f..3433984 100644 (file)
@@ -613,6 +613,7 @@ namespace Pithos.Network
                     {
                         info.Container = container;
                         info.Account = account;
+                        info.StorageUri = this.StorageUrl;
                     }
                     if (Log.IsDebugEnabled) Log.DebugFormat("START");
                     return infos;
@@ -652,6 +653,9 @@ namespace Pithos.Network
                     foreach (var info in infos)
                     {
                         info.Account = account;
+                        if (info.Container == null)
+                            info.Container = container;
+                        info.StorageUri = this.StorageUrl;
                     }
                     if (Log.IsDebugEnabled) Log.DebugFormat("END");
                     return infos;
index 1def501..a772eed 100644 (file)
@@ -105,6 +105,7 @@ namespace Pithos.Network
         void UpdateMetadata(ObjectInfo objectInfo);
 
         void UpdateMetadata(ContainerInfo Container);
+        IList<ShareAccountInfo> ListSharingAccounts(DateTime? since=null);
     }
 
 
@@ -183,6 +184,11 @@ namespace Pithos.Network
             return ;
         }
 
+        public IList<ShareAccountInfo> ListSharingAccounts(DateTime? since = new DateTime?())
+        {
+            return default(IList<ShareAccountInfo>);
+        }
+
 
         public IList<ObjectInfo> ListObjects(string account, string container, DateTime? since = null)
         {
index 4c8a722..d8a70eb 100644 (file)
                 {
                     "{9EF0B969-E518-4E46-987F-47570745A589}:_FE8EA18DF1CB49179367FE453762E9B5"
                     {
-                    "Name" = "8:GRNet"
+                    "Name" = "8:GRNET"
                     "AlwaysCreate" = "11:FALSE"
                     "Condition" = "8:"
                     "Transitive" = "11:FALSE"
         {
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:Pithos"
-        "ProductCode" = "8:{0558EE1F-65D8-4046-BAF8-EA9325EA6DC1}"
-        "PackageCode" = "8:{16F5A9E8-D797-4CD0-AC72-FA6C6AAAAE62}"
+        "ProductCode" = "8:{97C4606C-02B7-4E94-900F-D2654110B39B}"
+        "PackageCode" = "8:{07D12433-2FB8-4BCF-839A-02AD31A2C208}"
         "UpgradeCode" = "8:{205365D1-28AA-4322-A46C-FCB37502C6EF}"
         "AspNetVersion" = "8:4.0.30319.0"
         "RestartWWWService" = "11:FALSE"
         "RemovePreviousVersions" = "11:TRUE"
         "DetectNewerInstalledVersion" = "11:TRUE"
         "InstallAllUsers" = "11:FALSE"
-        "ProductVersion" = "8:1.0.0"
+        "ProductVersion" = "8:0.7.0"
         "Manufacturer" = "8:GRNET"
         "ARPHELPTELEPHONE" = "8:"
         "ARPHELPLINK" = "8:http://code.grnet.gr/projects/pithos-ms-client"
index c02cc8c..cb26cf6 100644 (file)
                 {
                     "{9EF0B969-E518-4E46-987F-47570745A589}:_9ED8CC47C48243A0B5686A7CE582CDA3"
                     {
-                    "Name" = "8:GRNet"
+                    "Name" = "8:GRNET"
                     "AlwaysCreate" = "11:FALSE"
                     "Condition" = "8:"
                     "Transitive" = "11:FALSE"
         {
         "Name" = "8:Microsoft Visual Studio"
         "ProductName" = "8:Pithos"
-        "ProductCode" = "8:{0558EE1F-65D8-4046-BAF8-EA9325EA6DC1}"
-        "PackageCode" = "8:{AD4F4E20-3B8F-470F-95FC-E409BC75DA20}"
+        "ProductCode" = "8:{4CB9D42B-6B18-4E6F-9DCE-4D7E57E562C2}"
+        "PackageCode" = "8:{FDC63D9F-C81B-45F7-8C6E-16DB523137E2}"
         "UpgradeCode" = "8:{205365D1-28AA-4322-A46C-FCB37502C6EF}"
         "AspNetVersion" = "8:4.0.30319.0"
         "RestartWWWService" = "11:FALSE"
         "RemovePreviousVersions" = "11:TRUE"
         "DetectNewerInstalledVersion" = "11:TRUE"
         "InstallAllUsers" = "11:FALSE"
-        "ProductVersion" = "8:1.0.0"
+        "ProductVersion" = "8:0.7.0"
         "Manufacturer" = "8:GRNET"
         "ARPHELPTELEPHONE" = "8:"
         "ARPHELPLINK" = "8:http://code.grnet.gr/projects/pithos-ms-client"
index 02ba4b2..5c80757 100644 (file)
@@ -56,6 +56,8 @@ namespace Pithos.ShellExtensions.Test
 
         public byte HashingParallelism{get; set; }
 
+        public TimeSpan StartupDelay { get; set; }
+
         public void Save()
         {
             
index 90f12bd..ca6b972 100644 (file)
@@ -172,6 +172,12 @@ namespace Pithos.ShellExtensions
             set { _settings.Value.PollingInterval = value; }
         }
 
+        public TimeSpan StartupDelay
+        {
+            get { return _settings.Value.StartupDelay; }
+            set { _settings.Value.StartupDelay = value; }
+        }
+
         public byte HashingParallelism
         {
             get { return _settings.Value.HashingParallelism; }
index 18b8a31..61355bb 100644 (file)
@@ -94,7 +94,7 @@ namespace Pithos.ShellExtensions.Test
         public int PollingInterval { get; set; }
 
         public byte HashingParallelism { get; set; }
-
+        public TimeSpan StartupDelay { get; set; }
 
         public bool ProxyAuthentication { get; set; }
         public void Save()