Fix #2121, manual changes to the API Key were not passed to the appropriate PithosMon...
authorPanagiotis Kanavos <pkanavos@gmail.com>
Thu, 1 Mar 2012 10:32:18 +0000 (12:32 +0200)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Thu, 1 Mar 2012 10:32:18 +0000 (12:32 +0200)
General cleanup

trunk/Pithos.Client.WPF/Preferences/AccountViewModel.cs
trunk/Pithos.Client.WPF/Preferences/AddAccountViewModel.cs
trunk/Pithos.Client.WPF/Preferences/PreferencesViewModel.cs
trunk/Pithos.Client.WPF/Properties/Resources.Designer.cs
trunk/Pithos.Client.WPF/Properties/Resources.resx
trunk/Pithos.Client.WPF/Shell/ShellViewModel.cs
trunk/Pithos.Core/PithosMonitor.cs

index 24f02ec..c7d3e50 100644 (file)
@@ -45,7 +45,7 @@ using Pithos.Interfaces;
 namespace Pithos.Client.WPF.Preferences
 {
     /// <summary>
-    /// ViewModel wrapper for an account
+    /// ViewModel wrapper for a settings Account object with change notifications
     /// </summary>
     public class AccountViewModel:PropertyChangedBase
     {
@@ -120,6 +120,7 @@ namespace Pithos.Client.WPF.Preferences
             set 
             {
                 _account.ApiKey = value;
+                IsExpired = false;
                 NotifyOfPropertyChange(() => ApiKey);
             }
         }
index 9fa0155..9f02a55 100644 (file)
 #endregion
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
-using System.Windows.Controls;
 using System.Windows.Forms;
-using Caliburn.Micro;
 using Pithos.Client.WPF.Properties;
-using Pithos.Core;
 using Pithos.Network;
 using MessageBox = System.Windows.MessageBox;
 using Screen = Caliburn.Micro.Screen;
@@ -178,7 +170,7 @@ namespace Pithos.Client.WPF.Preferences
 
         public void SelectAccount()
         {
-            using (var dlg = new FolderBrowserDialog{Description="Please select a folder to store local files. Pithos will create a new folder called Okeanos under the folder you specify."})
+            using (var dlg = new FolderBrowserDialog{Description=Resources.AddAccountViewModel_SelectAccount_Please_select_a_folder})
             {
                 //Ask the user to select a folder
                 //Note: We need a parent window here, which we retrieve with GetView            
@@ -219,7 +211,7 @@ namespace Pithos.Client.WPF.Preferences
             {
                 ClearBusy();
                 
-                (this.GetView() as Window).Activate();
+                ((Window) GetView()).Activate();
             }
 
         }
@@ -310,24 +302,14 @@ namespace Pithos.Client.WPF.Preferences
             {
                 SetBusy("Validating Credentials", "");
                 var client = new CloudFilesClient(AccountName, Token) { AuthenticationUrl = CurrentServer,/*Proxy=Proxy */};                
-                var containers = await TaskEx.Run(() =>
-                                                      {
-                                                          client.Authenticate();
-                                                          return client.ListContainers(AccountName);
-                                                      });
+                await TaskEx.Run(() =>
+                                     {
+                                         client.Authenticate();
+                                         return client.ListContainers(AccountName);
+                                     });
                 HasValidCredentials = true;
                 ValidationMessage = "Credentials Validated";
             }
-/*
-            catch (AggregateException exc)
-            {
-                exc.Handle(ex=>
-                               {
-                                   HasValidCredentials = false;
-                                   MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);                                                   
-                               });
-            }
-*/
             catch
             {
                 HasValidCredentials = false;
index 7017cf7..1b8a400 100644 (file)
  */
 #endregion
 
-// </copyright>
-// -----------------------------------------------------------------------
 
 using System.Collections.Concurrent;
 using System.ComponentModel.Composition;
 using System.Diagnostics;
 using System.IO;
-using System.Net;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Forms;
 using Caliburn.Micro;
 using Pithos.Client.WPF.Configuration;
+using Pithos.Client.WPF.Properties;
 using Pithos.Client.WPF.SelectiveSynch;
 using Pithos.Core;
 using Pithos.Interfaces;
@@ -63,12 +61,17 @@ using Screen = Caliburn.Micro.Screen;
 namespace Pithos.Client.WPF.Preferences
 {
     /// <summary>
-    /// TODO: Update summary.
+    /// The preferences screen displays user and account settings and updates the PithosMonitor
+    /// classes when account settings change.
     /// </summary>
+    /// <remarks>
+    /// The class is a single ViewModel for all Preferences tabs. It can be broken in separate
+    /// ViewModels, one for each tab.
+    /// </remarks>
     [Export]
     public class PreferencesViewModel : Screen
     {
-        private IEventAggregator _events;
+        private readonly IEventAggregator _events;
 
         //Logging in the Pithos client is provided by log4net
         private static readonly log4net.ILog Log = log4net.LogManager.GetLogger("Pithos");
@@ -102,10 +105,14 @@ namespace Pithos.Client.WPF.Preferences
 
         public PreferencesViewModel(IWindowManager windowManager, IEventAggregator events, ShellViewModel shell, PithosSettings settings, string currentTab)
         {
+            // ReSharper disable DoNotCallOverridableMethodsInConstructor
+            //Caliburn.Micro uses DisplayName for the view's title
+            DisplayName = "Pithos Preferences";
+            // ReSharper restore DoNotCallOverridableMethodsInConstructor
+
             _windowManager = windowManager;
             _events = events;
 
-            DisplayName = "Pithos Preferences";
             Shell = shell;
             
             Settings=settings;
@@ -193,7 +200,7 @@ namespace Pithos.Client.WPF.Preferences
             set
             {
                 if (value<0)
-                    throw new ArgumentOutOfRangeException("value","The Startup Delay must be greater or equal to 0");
+                    throw new ArgumentOutOfRangeException("value",Resources.PreferencesViewModel_StartupDelay_Greater_or_equal_to_0);
                 Settings.StartupDelay = TimeSpan.FromMinutes(value);
                 NotifyOfPropertyChange(()=>StartupDelay);
             }
@@ -222,17 +229,14 @@ namespace Pithos.Client.WPF.Preferences
         {
             _events.Publish(new Notification { Title = "Authorization failed", Message = "Your API Key has probably expired. You will be directed to a page where you can renew it", Level = TraceLevel.Error });
 
-            //var userName = CurrentAccount.AccountName;
             try
             {
 
                 var credentials = await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
-
+                //The server will return credentials for a different account, not just the current account
+                //We need to find the correct account first
                 var account = Accounts.First(act => act.AccountName == credentials.UserName);
-                //The server may return credentials for a different account
-                var monitor =  Shell.Monitors[account.AccountName];
-                account.ApiKey = credentials.Password;
-                monitor.ApiKey = credentials.Password;
+                account.ApiKey = credentials.Password;                
                 account.IsExpired = false;
                 Settings.Save();
                 TaskEx.Delay(10000).ContinueWith(_ =>Shell.MonitorAccount(account.Account));
@@ -334,9 +338,9 @@ namespace Pithos.Client.WPF.Preferences
                                         IsActive=wizard.IsAccountActive
                                     };
                Settings.Accounts.Add(newAccount);
-               var accountVM = new AccountViewModel(newAccount);
-               (Accounts as IProducerConsumerCollection<AccountViewModel>).TryAdd(accountVM);
-               CurrentAccount = accountVM;
+               var accountVm = new AccountViewModel(newAccount);
+               (Accounts as IProducerConsumerCollection<AccountViewModel>).TryAdd(accountVm);
+               CurrentAccount = accountVm;
                NotifyOfPropertyChange(() => Accounts);
                NotifyOfPropertyChange(() => Settings);   
            }
@@ -441,8 +445,8 @@ namespace Pithos.Client.WPF.Preferences
         }*/
 
         private AccountViewModel _currentAccount;
-        private IWindowManager _windowManager;
-        private string _shortcutPath;
+        private readonly IWindowManager _windowManager;
+        private readonly string _shortcutPath;
 
 
         
@@ -517,8 +521,7 @@ namespace Pithos.Client.WPF.Preferences
                     Directory.Delete(oldPath, true);
 
                     //We also need to change the path of the existing file states
-                    if (monitor != null)
-                        monitor.MoveFileStates(oldPath, newPath);
+                    monitor.MoveFileStates(oldPath, newPath);
                 }
             }
             //Replace the old rootpath with the new
index 9aa9704..4fb647f 100644 (file)
@@ -1,7 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.235
+//     Runtime Version:4.0.30319.488
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -59,5 +59,23 @@ namespace Pithos.Client.WPF.Properties {
                 resourceCulture = value;
             }
         }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Please select a folder to store local files. Pithos will create a new folder called Okeanos under the folder you specify..
+        /// </summary>
+        internal static string AddAccountViewModel_SelectAccount_Please_select_a_folder {
+            get {
+                return ResourceManager.GetString("AddAccountViewModel_SelectAccount_Please_select_a_folder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Startup Delay must be greater or equal to 0.
+        /// </summary>
+        internal static string PreferencesViewModel_StartupDelay_Greater_or_equal_to_0 {
+            get {
+                return ResourceManager.GetString("PreferencesViewModel_StartupDelay_Greater_or_equal_to_0", resourceCulture);
+            }
+        }
     }
 }
index af7dbeb..2a4f799 100644 (file)
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
+       <data name="PreferencesViewModel_StartupDelay_Greater_or_equal_to_0">
+               <value xml:space="preserve">The Startup Delay must be greater or equal to 0</value>
+       </data>
+       <data name="AddAccountViewModel_SelectAccount_Please_select_a_folder">
+               <value xml:space="preserve">Please select a folder to store local files. Pithos will create a new folder called Okeanos under the folder you specify.</value>
+       </data>
 </root>
\ No newline at end of file
index 1aba5f5..b593617 100644 (file)
@@ -232,16 +232,22 @@ namespace Pithos.Client.WPF {
                                if (_monitors.TryGetValue(accountName, out monitor))
                                {
                                        //If the account is active
-                                       if (account.IsActive)
-                                               //Start the monitor. It's OK to start an already started monitor,
-                                               //it will just ignore the call                        
-                                               StartMonitor(monitor).Wait();                        
-                                       else
-                                       {
-                                               //If the account is inactive
-                                               //Stop and remove the monitor
-                                               RemoveMonitor(accountName);
-                                       }
+                    if (account.IsActive)
+                    {
+                        //The Api Key may have changed throuth the Preferences dialog
+                        monitor.ApiKey = account.ApiKey;
+                                               Debug.Assert(monitor.StatusNotification == this,"An existing monitor should already have a StatusNotification service object");
+                        monitor.RootPath = account.RootPath;
+                        //Start the monitor. It's OK to start an already started monitor,
+                        //it will just ignore the call                        
+                        StartMonitor(monitor).Wait();
+                    }
+                    else
+                    {
+                        //If the account is inactive
+                        //Stop and remove the monitor
+                        RemoveMonitor(accountName);
+                    }
                                        return;
                                }
 
index a3fc17c..2495b10 100644 (file)
  */
 #endregion
 using System;
-using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.ComponentModel.Composition;
-using System.Diagnostics;
 using System.Diagnostics.Contracts;
 using System.IO;
 using System.Linq;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Security.Cryptography;
-using System.ServiceModel.Description;
-using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
-using Castle.ActiveRecord.Queries;
-using Microsoft.WindowsAPICodePack.Net;
 using Pithos.Core.Agents;
 using Pithos.Interfaces;
-using System.ServiceModel;
 using Pithos.Network;
 using log4net;
 
@@ -211,11 +201,11 @@ namespace Pithos.Core
                     return;
             }
             _cancellationSource = new CancellationTokenSource();
-            
 
-            CloudClient=new CloudFilesClient(UserName,ApiKey);
-            CloudClient.UsePithos = true;
-            CloudClient.AuthenticationUrl = this.AuthenticationUrl;            
+
+            CloudClient = new CloudFilesClient(UserName, ApiKey)
+                              {UsePithos = true, AuthenticationUrl = AuthenticationUrl};
+
 
             _accountInfo = CloudClient.Authenticate();            
             _accountInfo.SiteUri = AuthenticationUrl;
@@ -259,11 +249,11 @@ namespace Pithos.Core
             var pithosContainers = new List<string>{ FolderConstants.TrashContainer,FolderConstants.PithosContainer};
             foreach (var container in pithosContainers)
             {                
-                var info=CloudClient.GetContainerInfo(this.UserName, container);
+                var info=CloudClient.GetContainerInfo(UserName, container);
                 if (info == ContainerInfo.Empty)
                 {
-                    CloudClient.CreateContainer(this.UserName, container);
-                    info = CloudClient.GetContainerInfo(this.UserName, container);
+                    CloudClient.CreateContainer(UserName, container);
+                    info = CloudClient.GetContainerInfo(UserName, container);
                 }
                 _blockSize = info.BlockSize;
                 _blockHash = info.BlockHash;
@@ -276,8 +266,8 @@ namespace Pithos.Core
 
         private void IndexLocalFiles()
         {
-            StatusNotification.NotifyChange("Indexing Local Files",TraceLevel.Info);
-            using (log4net.ThreadContext.Stacks["Monitor"].Push("Indexing local files"))
+            StatusNotification.NotifyChange("Indexing Local Files");
+            using (ThreadContext.Stacks["Monitor"].Push("Indexing local files"))
             {
                 Log.Info("START");
                 try
@@ -359,6 +349,8 @@ namespace Pithos.Core
 
             public override int GetHashCode(CloudAction obj)
             {
+                if (obj == null)
+                    return 0;
                 var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode();
                 var hash2 = (obj.CloudFile == null) ? int.MaxValue : (obj.CloudFile.Hash ?? obj.CloudFile.Name??"").GetHashCode();
                 var hash3 = obj.Action.GetHashCode();
@@ -366,8 +358,6 @@ namespace Pithos.Core
             }
         }        
 
-        private Timer timer;
-
         private void StartNetworkAgent()
         {
 
@@ -385,7 +375,7 @@ namespace Pithos.Core
         }
 
         //Make sure a hidden cache folder exists to store partial downloads
-        private static string CreateHiddenFolder(string rootPath, string folderName)
+        private static void CreateHiddenFolder(string rootPath, string folderName)
         {
             if (String.IsNullOrWhiteSpace(rootPath))
                 throw new ArgumentNullException("rootPath");
@@ -412,7 +402,6 @@ namespace Pithos.Core
                     Log.InfoFormat("Reset cache folder to hidden: {0}", folder);
                 }                                
             }
-            return folder;
         }
 
        
@@ -435,9 +424,6 @@ namespace Pithos.Core
             if (FileAgent!=null)
                 FileAgent.Stop();
             FileAgent = null;
-            if (timer != null)
-                timer.Dispose();
-            timer = null;            
         }
 
 
@@ -545,7 +531,7 @@ namespace Pithos.Core
                 //Create the root URL for the target account
                 var oldName = UserName;
                 var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
-                var nameIndex=absoluteUri.IndexOf(oldName);
+                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
                 var root=absoluteUri.Substring(0, nameIndex);
 
                 accountInfo = new AccountInfo
@@ -560,7 +546,7 @@ namespace Pithos.Core
             }
             else
             {
-                accountName = this.UserName;
+                accountName = UserName;
                 container = parts[0];
                 relativeUrl = String.Join("/", parts.Splice(1));
             }
@@ -591,7 +577,7 @@ namespace Pithos.Core
                 //Create the root URL for the target account
                 var oldName = UserName;
                 var absoluteUri =  _accountInfo.StorageUri.AbsoluteUri;
-                var nameIndex=absoluteUri.IndexOf(oldName);
+                var nameIndex=absoluteUri.IndexOf(oldName, StringComparison.Ordinal);
                 var root=absoluteUri.Substring(0, nameIndex);
 
                 accountInfo = new AccountInfo