using System.Collections.Concurrent;
-using System.ComponentModel;
-using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ServiceModel;
-using System.ServiceModel.Description;
using System.Threading.Tasks;
using System.Windows;
using Caliburn.Micro;
using Hardcodet.Wpf.TaskbarNotification;
using Pithos.Client.WPF.Configuration;
using Pithos.Client.WPF.FileProperties;
-using Pithos.Client.WPF.Properties;
using Pithos.Client.WPF.SelectiveSynch;
using Pithos.Client.WPF.Services;
using Pithos.Client.WPF.Shell;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using Pithos.Network;
using StatusService = Pithos.Client.WPF.Services.StatusService;
{
//The Status Checker provides the current synch state
//TODO: Could we remove the status checker and use events in its place?
- private IStatusChecker _statusChecker;
- private IEventAggregator _events;
+ private readonly IStatusChecker _statusChecker;
+ private readonly IEventAggregator _events;
public PithosSettings Settings { get; private set; }
- private ConcurrentDictionary<string, PithosMonitor> _monitors = new ConcurrentDictionary<string, PithosMonitor>();
+ private readonly ConcurrentDictionary<string, PithosMonitor> _monitors = new ConcurrentDictionary<string, PithosMonitor>();
///<summary>
/// Dictionary of account monitors, keyed by account
///</summary>
}
- ///<summary>
- /// The status service is used by Shell extensions to retrieve file status information
- ///</summary>
- //TODO: CODE SMELL! This is the shell! While hosting in the shell makes executing start/stop commands easier, it is still a smell
- private ServiceHost _statusService { get; set; }
+ ///<summary>
+ /// The status service is used by Shell extensions to retrieve file status information
+ ///</summary>
+ //TODO: CODE SMELL! This is the shell! While hosting in the shell makes executing start/stop commands easier, it is still a smell
+ private ServiceHost _statusService;
//Logging in the Pithos client is provided by log4net
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger("Pithos");
}
- private async Task StartMonitoring()
+ private async void StartMonitoring()
{
try
{
{
return Task.Factory.StartNew(() =>
{
- PithosMonitor monitor = null;
+ PithosMonitor monitor;
var accountName = account.AccountName;
if (_monitors.TryGetValue(accountName, out monitor))
//PithosMonitor uses MEF so we need to resolve it
IoC.BuildUp(monitor);
- var appSettings = Properties.Settings.Default;
- monitor.AuthenticationUrl = account.ServerUrl;
+ monitor.AuthenticationUrl = account.ServerUrl;
_monitors[accountName] = monitor;
get { return _statusIcon; }
set
{
- //_statusIcon = value;
+ //TODO: Ensure all status icons use the Pithos logo
+ _statusIcon = value;
NotifyOfPropertyChange(() => StatusIcon);
}
}
{
if (String.IsNullOrWhiteSpace(filePath))
throw new ArgumentNullException("filePath");
- if (!File.Exists(filePath))
+ if (!File.Exists(filePath) && !Directory.Exists(filePath))
throw new ArgumentException(String.Format("Non existent file {0}",filePath),"filePath");
Contract.EndContractBlock();
var pair=(from monitor in Monitors
where filePath.StartsWith(monitor.Value.RootPath, StringComparison.InvariantCultureIgnoreCase)
select monitor).FirstOrDefault();
- var account = pair.Key;
- var accountMonitor = pair.Value;
+ var accountMonitor = pair.Value;
if (accountMonitor == null)
return;
var pair=(from monitor in Monitors
where filePath.StartsWith(monitor.Value.RootPath, StringComparison.InvariantCultureIgnoreCase)
select monitor).FirstOrDefault();
- var account = pair.Key;
- var accountMonitor = pair.Value;
+ var accountMonitor = pair.Value;
var info = accountMonitor.GetContainerInfo(filePath);
#endregion
- private Dictionary<PithosStatus, StatusInfo> iconNames = new List<StatusInfo>
+ private readonly Dictionary<PithosStatus, StatusInfo> _iconNames = new List<StatusInfo>
{
new StatusInfo(PithosStatus.InSynch, "All files up to date", "TrayInSynch"),
new StatusInfo(PithosStatus.Syncing, "Syncing Files", "TraySynching"),
{
var pithosStatus = _statusChecker.GetPithosStatus();
- if (iconNames.ContainsKey(pithosStatus))
+ if (_iconNames.ContainsKey(pithosStatus))
{
- var info = iconNames[pithosStatus];
+ var info = _iconNames[pithosStatus];
StatusIcon = String.Format(@"../Images/{0}.ico", info.IconName);
Assembly assembly = Assembly.GetExecutingAssembly();
var credentials = await PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
- var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
+ var account = Settings.Accounts.First(act => act.AccountName == credentials.UserName);
account.ApiKey = credentials.Password;
monitor.ApiKey = credentials.Password;
Settings.Save();
string message = String.Format("API Key retrieval for {0} failed", monitor.UserName);
Log.Error(message, exc.InnerException);
_events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
- return;
}
catch (Exception exc)
{
string message = String.Format("API Key retrieval for {0} failed", monitor.UserName);
Log.Error(message, exc);
_events.Publish(new Notification { Title = "Authorization failed", Message = message, Level = TraceLevel.Error });
- return;
-
}
}
public void NotifyChange(string status, TraceLevel level=TraceLevel.Info)
{
- this.StatusMessage = status;
+ StatusMessage = status;
_events.Publish(new Notification { Title = "Pithos", Message = status, Level = level });
}
public void NotifyChangedFile(string filePath)
{
var entry = new FileEntry {FullPath=filePath};
- IProducerConsumerCollection<FileEntry> files=this.RecentFiles;
+ IProducerConsumerCollection<FileEntry> files=RecentFiles;
FileEntry popped;
while (files.Count > 5)
files.TryTake(out popped);
{
if (!Settings.ShowDesktopNotifications)
return;
- BalloonIcon icon = BalloonIcon.None;
+ BalloonIcon icon;
switch (notification.Level)
{
case TraceLevel.Error:
if (Settings.ShowDesktopNotifications)
{
- var tv = (ShellView) this.GetView();
+ var tv = (ShellView) GetView();
tv.TaskbarView.ShowBalloonTip(notification.Title, notification.Message, icon);
}
}
Contract.EndContractBlock();
var fileName = message.FileName;
-
+ //TODO: Display file properties for non-container folders
if (File.Exists(fileName))
- this.ShowFileProperties(fileName);
+ //Retrieve the full name with exact casing. Pithos names are case sensitive
+ ShowFileProperties(FileInfoExtensions.GetProperFilePathCapitalization(fileName));
else if (Directory.Exists(fileName))
- this.ShowContainerProperties(fileName);
+ //Retrieve the full name with exact casing. Pithos names are case sensitive
+ {
+ var path = FileInfoExtensions.GetProperDirectoryCapitalization(fileName);
+ if (IsContainer(path))
+ ShowContainerProperties(path);
+ else
+ ShowFileProperties(path);
+ }
}
+
+ private bool IsContainer(string path)
+ {
+ var matchingFolders = from account in _accounts
+ from rootFolder in Directory.GetDirectories(account.AccountPath)
+ where rootFolder.Equals(path, StringComparison.InvariantCultureIgnoreCase)
+ select rootFolder;
+ return matchingFolders.Any();
+ }
+
}
}