WPF.Properties.Resources.We_Apologize,
WPF.Properties.Resources.Please_Submit_Error);
ShowMessages("Oops!",message, messages);
- e.SetObserved();
+ e.SetObserved();
}
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
if (TagsChanged)
{
Container.Tags = this.Tags.ToDictionary(tag => tag.Name, tag => tag.Value);
- var monitor = Shell.Monitors[Container.Account];
+ var monitor = Shell.Monitors[Container.AccountKey];
monitor.CloudClient.UpdateMetadata(Container);
}
PithosFile.ContentEncoding = ContentEncoding;
PithosFile.Manifest = Manifest;
PithosFile.IsPublic = IsPublic;
-
- var monitor = Shell.Monitors[PithosFile.Account];
+
+ var monitor = Shell.Monitors[PithosFile.AccountKey];
monitor.CloudClient.UpdateMetadata(PithosFile);
* -----------------------------------------------------------------------
*/
#endregion
+
+using System;
using Caliburn.Micro;
using Pithos.Interfaces;
_account = account;
}
+ public Uri AccountKey
+ {
+ get { return new Uri(new Uri(_account.ServerUrl) , _account.AccountName); }
+ }
public string AccountName
{
Token = credentials.Password;
IsConfirmed = true;
+
}
catch (PithosException exc)
{
((Window) GetView()).Activate();
}
+ if (IsConfirmed)
+ TaskEx.Run(TestAccount);
+
}
public AddAccountViewModel()
/// The class is a single ViewModel for all Preferences tabs. It can be broken in separate
/// ViewModels, one for each tab.
/// </remarks>
- [Export]
+ [Export, PartCreationPolicy(CreationPolicy.Shared)]
public class PreferencesViewModel : Screen
{
private readonly IEventAggregator _events;
public void SelectiveSyncFolders()
{
- var monitor = Shell.Monitors[CurrentAccount.AccountName];
+ var monitor = Shell.Monitors[CurrentAccount.AccountKey];
var model = new SelectiveSynchViewModel(monitor,_events,CurrentAccount.Account);
{
foreach (var account in _accountsToRemove)
{
- Shell.RemoveMonitor(account.AccountName);
+ Shell.RemoveMonitor(account.ServerUrl, account.AccountName);
Shell.RemoveAccountFromDatabase(account);
}
var newPath= dlg.SelectedPath;
//Find the account's monitor and stop it
PithosMonitor monitor;
- if (Shell.Monitors.TryGetValue(CurrentAccount.AccountName, out monitor))
+ if (Shell.Monitors.TryGetValue(CurrentAccount.AccountKey, out monitor))
{
monitor.Stop();
// 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.7.20319.0")]
-[assembly: AssemblyFileVersionAttribute("0.7.20319.0")]
+[assembly: AssemblyVersion("0.7.20401.0")]
+[assembly: AssemblyFileVersionAttribute("0.7.20401.0")]
private const string DirectoryType = "application/directory";
private readonly IEventAggregator _events ;
- private string _title;
- public string Title
- {
- get { return _title; }
- set
- {
- _title = value;
- NotifyOfPropertyChange(() => Title);
- }
- }
public AccountSettings Account { get; set; }
{
Account = account;
AccountName = account.AccountName;
- Title = account.AccountName;
+ DisplayName = account.AccountName;
_monitor = monitor;
_events = events;
TaskEx.Run(LoadRootNode);
select new DirectoryRecord
{
DisplayName=account.name,
+ Uri=new Uri(client.StorageUrl,"../"+ account.name),
Directories=(from container in client.ListContainers(account.name)
select new DirectoryRecord
{
DisplayName=container.Name,
+ Uri = new Uri(client.StorageUrl, "../" + account.name + "/" + 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()
public PithosSettings Settings { get; private set; }
- private readonly ConcurrentDictionary<string, PithosMonitor> _monitors = new ConcurrentDictionary<string, PithosMonitor>();
+ private readonly ConcurrentDictionary<Uri, PithosMonitor> _monitors = new ConcurrentDictionary<Uri, PithosMonitor>();
///<summary>
/// Dictionary of account monitors, keyed by account
///</summary>
///</remarks>
// TODO: Does the Shell REALLY need access to the monitors? Could we achieve the same results with a better design?
// TODO: The monitors should be internal to Pithos.Core, even though exposing them makes coding of the Object and Container windows easier
- public ConcurrentDictionary<string, PithosMonitor> Monitors
+ public ConcurrentDictionary<Uri, PithosMonitor> Monitors
{
get { return _monitors; }
}
{
try
{
+ if (Settings.IgnoreCertificateErrors)
+ {
+ ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
+ }
+
var accounts = Settings.Accounts.Select(MonitorAccount);
await TaskEx.WhenAll(accounts);
_statusService = StatusService.Start();
-/*
- foreach (var account in Settings.Accounts)
- {
- await MonitorAccount(account);
- }
-*/
-
}
catch (AggregateException exc)
{
PithosMonitor monitor;
var accountName = account.AccountName;
- if (_monitors.TryGetValue(accountName, out monitor))
+ if (Monitors.TryGetValue(account.AccountKey, out monitor))
{
//If the account is active
if (account.IsActive)
{
//If the account is inactive
//Stop and remove the monitor
- RemoveMonitor(accountName);
+ RemoveMonitor(account.ServerUrl,accountName);
}
return;
}
monitor.AuthenticationUrl = account.ServerUrl;
- _monitors[accountName] = monitor;
+ Monitors[account.AccountKey] = monitor;
if (account.IsActive)
{
{
if (currentInfo==null)
throw new ArgumentNullException("currentInfo");
- Contract.EndContractBlock();
-
- var monitor = Monitors[currentInfo.Account];
+ Contract.EndContractBlock();
+ var monitor = Monitors[currentInfo.AccountKey];
var newInfo=monitor.CloudClient.GetObjectInfo(currentInfo.Account, currentInfo.Container, currentInfo.Name);
return newInfo;
}
throw new ArgumentNullException("container");
Contract.EndContractBlock();
- var monitor = Monitors[container.Account];
+ var monitor = Monitors[container.AccountKey];
var newInfo = monitor.CloudClient.GetContainerInfo(container.Account, container.Name);
return newInfo;
}
}
- public void RemoveMonitor(string accountName)
+ public void RemoveMonitor(string serverUrl,string accountName)
{
if (String.IsNullOrWhiteSpace(accountName))
return;
- var accountInfo=_accounts.FirstOrDefault(account => account.UserName == accountName);
+ var accountInfo=_accounts.FirstOrDefault(account => account.UserName == accountName && account.StorageUri.ToString().StartsWith(serverUrl));
if (accountInfo != null)
{
_accounts.TryRemove(accountInfo);
_pollAgent.RemoveAccount(accountInfo);
}
+ var accountKey = new Uri(new Uri(serverUrl),accountName);
PithosMonitor monitor;
- if (Monitors.TryRemove(accountName, out monitor))
+ if (Monitors.TryRemove(accountKey, out monitor))
{
monitor.Stop();
//TODO: Also remove any pending actions for this account
#region Event Handlers
public void Handle(SelectiveSynchChanges message)
- {
- var accountName = message.Account.AccountName;
+ {
PithosMonitor monitor;
- if (_monitors.TryGetValue(accountName, out monitor))
+ if (Monitors.TryGetValue(message.Account.AccountKey, out monitor))
{
monitor.SetSelectivePaths(message.Uris,message.Added,message.Removed);
\r
var differencer = _differencer.PostSnapshot(accountInfo, cleanRemotes);\r
\r
- ProcessDeletedFiles(accountInfo, differencer.Deleted.FilterDirectlyBelow(SelectiveUris));\r
+ var filterUris = SelectiveUris[accountInfo.AccountKey];\r
+\r
+ ProcessDeletedFiles(accountInfo, differencer.Deleted.FilterDirectlyBelow(filterUris));\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 = MovesToActions(accountInfo,differencer.Moved.FilterDirectlyBelow(SelectiveUris))\r
+ \r
+ var allActions = MovesToActions(accountInfo,differencer.Moved.FilterDirectlyBelow(filterUris))\r
.Union(\r
- ChangesToActions(accountInfo, differencer.Changed.FilterDirectlyBelow(SelectiveUris)))\r
+ ChangesToActions(accountInfo, differencer.Changed.FilterDirectlyBelow(filterUris)))\r
.Union(\r
- CreatesToActions(accountInfo, differencer.Created.FilterDirectlyBelow(SelectiveUris)));\r
+ CreatesToActions(accountInfo, differencer.Created.FilterDirectlyBelow(filterUris)));\r
\r
//And remove those that are already being processed by the agent\r
var distinctActions = allActions\r
}\r
\r
readonly AccountsDifferencer _differencer = new AccountsDifferencer();\r
- private List<Uri> _selectiveUris=new List<Uri>();\r
+ private Dictionary<Uri, List<Uri>> _selectiveUris = new Dictionary<Uri, List<Uri>>();\r
\r
/// <summary>\r
/// Deletes local files that are not found in the list of cloud files\r
}\r
}\r
\r
- public void SetSyncUris(Uri[] uris)\r
+ public void SetSyncUris(Uri accountKey, Uri[] uris)\r
{ \r
- SelectiveUris=uris.ToList();\r
+ SelectiveUris[accountKey]=uris.ToList();\r
}\r
\r
- protected List<Uri> SelectiveUris\r
+ protected Dictionary<Uri,List<Uri>> SelectiveUris\r
{\r
get { return _selectiveUris;}\r
set { _selectiveUris = value; }\r
StatusKeeper.StartProcessing(_cancellationSource.Token);
IndexLocalFiles();
//Extract the URIs from the string collection
- var settings = Settings.Accounts.First(s => s.AccountName == _accountInfo.UserName);
+ var settings = Settings.Accounts.First(s => s.AccountKey == _accountInfo.AccountKey );
var selectiveUrls=settings.SelectiveFolders.Cast<string>().Select(url => new Uri(url)).ToArray();
SetSelectivePaths(selectiveUrls,null,null);
var selectivePaths = UrisToFilePaths(uris);
FileAgent.SelectivePaths=selectivePaths;
- PollAgent.SetSyncUris(uris);
+ PollAgent.SetSyncUris(_accountInfo.AccountKey,uris);
var removedPaths = UrisToFilePaths(removed);
UnversionSelectivePaths(removedPaths);
--- /dev/null
+<html>
+<body>
+<h2>Pithos MS Client v. 0.7.20401</h2>
+Release Date: Apr 01, 2012, 23:00
+<br/>
+Includes:
+<br/>
+<ul>
+<li> Fixes for maximum hashmap size</li>
+</ul>
+</body>
+</html>
\ No newline at end of file
<title>Pithos MS Client</title> \r
<link>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/changes/trunk/Pithos.Installer/versioninfo.xml</link> \r
<description></description> \r
- <language>en</language> \r
+ <language>en</language> \r
+ <item> \r
+ <title>Version 0.7.20401</title>\r
+ <sparkle:releaseNotesLink>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/raw/trunk/Pithos.Installer/rnotes.0.7.20401.html</sparkle:releaseNotesLink>\r
+ <pubDate>Fri, 02 Apr 2012 23:00:00 +0200</pubDate>\r
+ <enclosure \r
+ url="https://code.grnet.gr/attachments/download/1051/PithosPlus_Setupv0.7.20319.0.exe"\r
+ length="4947759" \r
+ type="application/octet-stream"\r
+ sparkle:version="0.7.20401" \r
+ />\r
+ </item>\r
<item> \r
<title>Version 0.7.20319</title>\r
<sparkle:releaseNotesLink>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/raw/trunk/Pithos.Installer/rnotes.0.7.20319.html</sparkle:releaseNotesLink>\r
public string AccountName { get; set; }
-
+ public Uri AccountKey
+ {
+ get { return new Uri(new Uri(ServerUrl), AccountName); }
+ }
+
+
public string ApiKey { get; set; }
public bool IsActive { get; set; }
private StringCollection _selectiveFolders = new StringCollection();
- private bool _isExpired;
- public bool IsExpired
- {
- get { return _isExpired; }
- set { _isExpired = value; }
- }
+ public bool IsExpired { get; set; }
public StringCollection SelectiveFolders
{
}
}
+ public Uri AccountKey
+ {
+ get { return new Uri(StorageUri,"../" + Account); }
+ }
+
public ObjectInfo SetPrevious(ObjectInfo previous)
{
Previous = previous;
public string UserName { get; set; }
public string Token { get; set; }
public Uri StorageUri { get; set; }
+
+ public Uri AccountKey
+ {
+ get{return new Uri(StorageUri,"../" + UserName);}
+ }
private string _accountPath;
public string AccountPath
}
Log.InfoFormat("[AUTHENTICATE] End for {0}", UserName);
-
+ Debug.Assert(_baseClient!=null);
return new AccountInfo {StorageUri = StorageUrl, Token = Token, UserName = UserName,Groups=groups};
{
Account=account,
Name = container,
+ StorageUrl=this.StorageUrl.ToString(),
Count =
long.Parse(client.GetHeaderValue("X-Container-Object-Count")),
Bytes = long.Parse(client.GetHeaderValue("X-Container-Bytes-Used")),
{
//In case of 409 the missing parts will be in the response content
using (var stream = response.GetResponseStream())
- using(var reader=stream.GetLoggedReader(Log,response.ContentLength))
+ using(var reader=stream.GetLoggedReader(Log))
{
//We used to have to cleanup the content before returning it because it contains
//error content after the list of hashes
{
public string Account { get; set; }
public string Name { get; set; }
+ public string StorageUrl { get; set; }
public long Count { get; set; }
public long Bytes { get; set; }
public string BlockHash { get; set; }
public Dictionary<string, string> Tags { get; set; }
public Dictionary<string, string> Policies { get; set; }
+ public Uri AccountKey
+ {
+ get { return new Uri(new Uri(StorageUrl), "../" + Account); }
+ }
+
+
public static ContainerInfo Empty=new ContainerInfo();
public ContainerInfo()
}
}
- public static TextReader GetLoggedReader(this Stream stream, ILog log, long contentLength)
+ public static TextReader GetLoggedReader(this Stream stream, ILog log)
{
var reader = new StreamReader(stream);
if (!log.IsDebugEnabled)
using (reader)
{
- var buffer=new char[contentLength];
- var read=reader.Read(buffer, 0, (int)contentLength);
- var body = new string(buffer,0,read); //reader.ReadToEnd();
+ var body = reader.ReadToEnd();
log.DebugFormat("JSON response: {0}", body);
return new StringReader(body);
}