</Compile>
<Compile Include="FileProperties\NewContainerViewModel.cs" />
<Compile Include="PithosException.cs" />
+ <Compile Include="Preferences\AccountViewModel.cs" />
<Compile Include="Preferences\AddAccountView.xaml.cs">
<DependentUpon>AddAccountView.xaml</DependentUpon>
</Compile>
--- /dev/null
+#region
+/* -----------------------------------------------------------------------
+ * <copyright file="AccountViewModel.cs" company="GRNet">
+ *
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either expressed
+ * or implied, of GRNET S.A.
+ * </copyright>
+ * -----------------------------------------------------------------------
+ */
+#endregion
+using Caliburn.Micro;
+using Pithos.Interfaces;
+
+namespace Pithos.Client.WPF.Preferences
+{
+ /// <summary>
+ /// ViewModel wrapper for an account
+ /// </summary>
+ public class AccountViewModel:PropertyChangedBase
+ {
+
+ private readonly AccountSettings _account;
+
+ public AccountSettings Account
+ {
+ get { return _account; }
+ }
+
+ public AccountViewModel(AccountSettings account)
+ {
+ _account = account;
+ }
+
+
+ public string AccountName
+ {
+ get {
+ return _account.AccountName;
+ }
+ set {
+ _account.AccountName = value;
+ NotifyOfPropertyChange(()=>AccountName);
+ }
+ }
+
+ public string RootPath
+ {
+ get { return _account.RootPath; }
+ set
+ {
+ _account.RootPath = value;
+ NotifyOfPropertyChange(()=>RootPath);
+ }
+ }
+
+ public bool IsActive
+ {
+ get { return _account.IsActive; }
+ set
+ {
+ _account.IsActive = value;
+ NotifyOfPropertyChange(()=>IsActive);
+ }
+ }
+
+ public bool IsExpired
+ {
+ get { return _account.IsExpired; }
+ set
+ {
+ _account.IsExpired = value;
+ NotifyOfPropertyChange(()=>IsExpired);
+ }
+ }
+
+ public string ServerUrl
+ {
+ get { return _account.ServerUrl; }
+ set
+ {
+ _account.ServerUrl = value;
+ NotifyOfPropertyChange(()=>ServerUrl);
+ }
+ }
+
+ public string ApiKey
+ {
+ get { return _account.ApiKey; }
+ set
+ {
+ _account.ApiKey = value;
+ NotifyOfPropertyChange(() => ApiKey);
+ }
+ }
+
+
+ }
+}
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
- <Image Visibility="{Binding Converter={StaticResource BoolToVisible}, Path=IsExpired}" Source="/Pithos.Client.WPF;component/Images/SmallWarning.png" Margin="2,0"/>
+ <Image Visibility="{Binding Converter={StaticResource BoolToVisible}, Path=IsExpired,Mode=OneWay}" Source="/Pithos.Client.WPF;component/Images/SmallWarning.png" Margin="2,0"/>
<TextBlock Text="{Binding AccountName}" />
</StackPanel>
</DataTemplate>
using System.Collections.Concurrent;
using System.ComponentModel.Composition;
+using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
{
private IEventAggregator _events;
+ //Logging in the Pithos client is provided by log4net
+ private static readonly log4net.ILog Log = log4net.LogManager.GetLogger("Pithos");
private PithosSettings _settings;
public PithosSettings Settings
}
}
- private ObservableConcurrentCollection<AccountSettings> _accounts;
- public ObservableConcurrentCollection<AccountSettings> Accounts
+ private ObservableConcurrentCollection<AccountViewModel> _accounts;
+ public ObservableConcurrentCollection<AccountViewModel> Accounts
{
get { return _accounts; }
set
Shell = shell;
Settings=settings;
- Accounts = new ObservableConcurrentCollection<AccountSettings>();
+ Accounts = new ObservableConcurrentCollection<AccountViewModel>();
if (settings.Accounts == null)
{
settings.Accounts=new AccountsCollection();
settings.Save();
}
- Accounts.AddFromEnumerable(settings.Accounts);
+ var accountVMs = from account in settings.Accounts
+ select new AccountViewModel(account);
+
+ Accounts.AddFromEnumerable(accountVMs);
var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
_shortcutPath = Path.Combine(startupPath, "Pithos.lnk");
var monitor = Shell.Monitors[CurrentAccount.AccountName];
- var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount);
+ var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount.Account);
if (_windowManager.ShowDialog(model) == true)
{
}
public async Task RefreshApiKey()
- {
- await Shell.TryAuthorize(CurrentAccount.AccountName, 3);
- NotifyOfPropertyChange(()=>CurrentAccount);
+ {
+ _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);
+
+ 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.IsExpired = false;
+ Settings.Save();
+ TaskEx.Delay(10000).ContinueWith(_ =>Shell.MonitorAccount(account.Account));
+ NotifyOfPropertyChange(() => Accounts);
+ }
+ catch (AggregateException exc)
+ {
+ string message = String.Format("API Key retrieval failed");
+ Log.Error(message, exc.InnerException);
+ _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
+ }
+ catch (Exception exc)
+ {
+ string message = String.Format("API Key retrieval failed");
+ Log.Error(message, exc);
+ _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
+ }
+
}
+
public void SaveChanges()
{
IsActive=wizard.IsAccountActive
};
Settings.Accounts.Add(newAccount);
- (Accounts as IProducerConsumerCollection<AccountSettings>).TryAdd(newAccount);
- CurrentAccount = newAccount;
+ var accountVM = new AccountViewModel(newAccount);
+ (Accounts as IProducerConsumerCollection<AccountViewModel>).TryAdd(accountVM);
+ CurrentAccount = accountVM;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(() => Settings);
}
{
var credentials=await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
+ var accountVM = new AccountViewModel(account);
if (account == null)
{
account=new AccountSettings{
ApiKey=credentials.Password
};
Settings.Accounts.Add(account);
- (Accounts as IProducerConsumerCollection<AccountSettings>).TryAdd(account);
+ accountVM = new AccountViewModel(account);
+ (Accounts as IProducerConsumerCollection<AccountViewModel>).TryAdd(accountVM);
}
else
{
account.ApiKey=credentials.Password;
}
//SelectedAccountIndex= Settings.Accounts.IndexOf(account);
- CurrentAccount = account;
+ CurrentAccount = accountVM;
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(()=>Settings);
}
public void RemoveAccount()
{
var accountName = CurrentAccount.AccountName;
- Settings.Accounts.Remove(CurrentAccount);
+ Settings.Accounts.Remove(CurrentAccount.Account);
Accounts.TryRemove(CurrentAccount);
}
}*/
- private AccountSettings _currentAccount;
+ private AccountViewModel _currentAccount;
private IWindowManager _windowManager;
private string _shortcutPath;
- public AccountSettings CurrentAccount
+ public AccountViewModel CurrentAccount
{
get { return _currentAccount; }
set
monitor.Start();
}
else
- Shell.MonitorAccount(CurrentAccount);
+ Shell.MonitorAccount(CurrentAccount.Account);
//Finally, notify that the Settings, CurrentAccount have changed
NotifyOfPropertyChange(() => CurrentAccount);
NotifyOfPropertyChange(() => Settings);
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.7.0.0")]
-[assembly: AssemblyFileVersionAttribute("0.7.20228.1899")]
+[assembly: AssemblyFileVersionAttribute("0.7.20229.2112")]
//Lazily initialized File Version info. This is done once and lazily to avoid blocking the UI
private Lazy<FileVersionInfo> _fileVersion;
+ private PollAgent _pollAgent;
+
///<summary>
/// The Shell depends on MEF to provide implementations for windowManager, events, the status checker service and the settings
///</summary>
/// The PithosSettings class encapsulates the app's settings to abstract their storage mechanism (App settings, a database or registry)
///</remarks>
[ImportingConstructor]
- public ShellViewModel(IWindowManager windowManager, IEventAggregator events, IStatusChecker statusChecker, PithosSettings settings)
+ public ShellViewModel(IWindowManager windowManager, IEventAggregator events, IStatusChecker statusChecker, PithosSettings settings,PollAgent pollAgent)
{
try
{
_events = events;
_events.Subscribe(this);
+ _pollAgent = pollAgent;
Settings = settings;
Proxy.SetFromSettings(settings);
public void SynchNow()
{
- var agent = IoC.Get<PollAgent>();
- agent.SynchNow();
+ _pollAgent.SynchNow();
}
public ObjectInfo RefreshObjectInfo(ObjectInfo currentInfo)
}
- public async Task TryAuthorize(string userName, int retries)
- {
- _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 });
-
- try
- {
-
- var credentials = await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
-
- var account = Settings.Accounts.First(act => act.AccountName == credentials.UserName);
- //The server may return credentials for a different account
- var monitor = _monitors[account.AccountName];
- account.ApiKey = credentials.Password;
- monitor.ApiKey = credentials.Password;
- account.IsExpired = false;
- Settings.Save();
- TaskEx.Delay(10000).ContinueWith(_=>
- StartMonitor(monitor, retries + 1));
- NotifyOfPropertyChange(()=>Accounts);
- }
- catch (AggregateException exc)
- {
- string message = String.Format("API Key retrieval for {0} failed", userName);
- Log.Error(message, exc.InnerException);
- _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
- }
- catch (Exception exc)
- {
- string message = String.Format("API Key retrieval for {0} failed", userName);
- Log.Error(message, exc);
- _events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
- }
-
- }
private static bool IsUnauthorized(WebException exc)
{
namespace Pithos.Interfaces
{
[DebuggerDisplay("Name {Name}")]
- public class ObjectInfo:DynamicObject
+ public class ObjectInfo//:DynamicObject
{
private readonly List<string> _knownContainers= new List<string>{"trash"};
public string Name { get; set; }
Hash = String.Empty,
Bytes = 0,
Content_Type = String.Empty,
- Last_Modified = DateTime.MinValue
+ Last_Modified = DateTime.MinValue,
+ Exists=false
};
-
+ private bool _exists=true;
+
+ public bool Exists
+ {
+ get {
+ return _exists;
+ }
+ set {
+ _exists = value;
+ }
+ }
+
public string RelativeUrlToFilePath(string currentAccount)
{
return finalPath;
}
+/*
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (binder.Name.StartsWith("x_object_meta"))
}
return false;
}
+*/
public string GetPermissionString()
{
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:Pithos"
- "ProductCode" = "8:{E88F0F45-5BE6-4616-A86B-D595712A5663}"
- "PackageCode" = "8:{8314D97A-C981-4184-8444-4DB962DC3240}"
+ "ProductCode" = "8:{013ABFEC-E6FB-4C5E-930F-736A4730268A}"
+ "PackageCode" = "8:{C7D65245-240C-42FA-9E46-2AAFB3351131}"
"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:0.7.20228"
+ "ProductVersion" = "8:0.7.20229"
"Manufacturer" = "8:GRNET"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:http://code.grnet.gr/projects/pithos-ms-client"
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:Pithos"
- "ProductCode" = "8:{F70830AB-AE3C-4721-9FBD-2EF0CD415B7D}"
- "PackageCode" = "8:{78D43546-C115-43DE-AAE2-6C262F691990}"
+ "ProductCode" = "8:{CDF5C181-8F2F-4135-9861-89F031E4B435}"
+ "PackageCode" = "8:{CD80CD47-92C9-4445-A777-4110130323B8}"
"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:0.7.20228"
+ "ProductVersion" = "8:0.7.20229"
"Manufacturer" = "8:GRNET"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:http://code.grnet.gr/projects/pithos-ms-client"