Added fix for maximum error response
[pithos-ms-client] / trunk / Pithos.Client.WPF / TaskbarViewModel.cs
1 // -----------------------------------------------------------------------
2 // <copyright file="StatusViewModel.cs" company="Microsoft">
3 // TODO: Update copyright text.
4 // </copyright>
5 // -----------------------------------------------------------------------
6
7 using System.Collections.Concurrent;
8 using System.ComponentModel.Composition;
9 using System.Diagnostics;
10 using System.IO;
11 using System.Threading.Tasks;
12 using System.Windows;
13 using Caliburn.Micro;
14 using Pithos.Client.WPF.Properties;
15 using Pithos.Core;
16 using Pithos.Interfaces;
17
18 namespace Pithos.Client.WPF
19 {
20     using System;
21     using System.Collections.Generic;
22     using System.Linq;
23     using System.Text;
24
25     /// <summary>
26     /// TODO: Update summary.
27     /// </summary>
28     [Export]
29     public class TaskbarViewModel:ViewAware,IStatusNotification
30     {
31         private IStatusChecker _statusChecker;
32         private IEventAggregator _events;
33
34         public PithosMonitor Monitor { get; private set; }
35
36         public IPithosSettings Settings { get; private set; }
37
38         public IScreen Parent { get; set; }
39
40         [ImportingConstructor]
41         public TaskbarViewModel(IEventAggregator events, IStatusChecker statusChecker,PithosMonitor monitor,IPithosSettings settings)
42         {
43             OpenPithosFolderCommand = new PithosCommand(OpenPithosFolder);
44             _statusChecker = statusChecker;
45             _events = events;            
46             Settings = settings;
47             Monitor = monitor;
48             Monitor.StatusNotification = this;
49
50             
51
52             var account=settings.Accounts.FirstOrDefault(act => act.IsActive);
53             if (account != null)
54             {
55                 Monitor.UserName = account.AccountName;
56                 Monitor.ApiKey = account.ApiKey;
57                 Monitor.UsePithos = account.UsePithos;
58                 var appSettings = Properties.Settings.Default;
59                 Monitor.AuthenticationUrl = account.UsePithos
60                                                 ? appSettings.PithosAuthenticationUrl
61                                                 : appSettings.CloudfilesAuthenticationUrl;
62                 Monitor.RootPath = Path.Combine(Settings.PithosPath, account.RootPath??"");
63             }
64
65         }
66         #region Status Properties
67
68         private string _statusMessage;
69         public string StatusMessage
70         {
71             get { return _statusMessage; }
72             set
73             {
74                 _statusMessage = value;
75                 NotifyOfPropertyChange(() => StatusMessage);
76             }
77         }
78
79         private string _usageMessage;
80         public string UsageMessage
81         {
82             get { return _usageMessage; }
83             set
84             {
85                 _usageMessage = value;
86                 NotifyOfPropertyChange(() => UsageMessage);
87             }
88         }
89
90
91         private string _pauseSyncCaption="Pause Syncing";
92         public string PauseSyncCaption
93         {
94             get { return _pauseSyncCaption; }
95             set
96             {
97                 _pauseSyncCaption = value;
98                 NotifyOfPropertyChange(() => PauseSyncCaption);
99             }
100         }
101
102         private readonly ObservableConcurrentCollection<FileEntry> _recentFiles = new ObservableConcurrentCollection<FileEntry>();
103         public ObservableConcurrentCollection<FileEntry> RecentFiles
104         {
105             get { return _recentFiles; }
106         }
107
108
109         private string _statusIcon="Images/Tray.ico";
110         public string StatusIcon
111         {
112             get { return _statusIcon; }
113             set
114             {
115                 _statusIcon = value;
116                 NotifyOfPropertyChange(() => StatusIcon);
117             }
118         }
119
120         #endregion
121
122         #region Commands
123
124         public void ShowPreferences()
125         {
126             Settings.Reload();
127         }
128
129
130         public PithosCommand OpenPithosFolderCommand { get; private set; }
131
132         public void OpenPithosFolder()
133         {
134             Process.Start(Settings.PithosPath);
135         }
136
137         public void GoToSite()
138         {
139             Process.Start(Properties.Settings.Default.PithosSite);
140         }
141
142
143         public void ToggleSynching()
144         {
145             Monitor.Pause = !Monitor.Pause;
146             PauseSyncCaption = Monitor.Pause ? "Resume syncing" : "Pause syncing";
147             var iconKey = Monitor.Pause ? "TraySyncPaused" : "TrayInSynch";
148             StatusIcon = String.Format(@"Images/{0}.ico", iconKey);
149         }
150
151         public void ExitPithos()
152         {
153             Monitor.Stop();
154             Parent.TryClose();
155         }
156         #endregion
157
158
159         private Dictionary<PithosStatus, StatusInfo> iconNames = new List<StatusInfo>
160             {
161                 new StatusInfo(PithosStatus.InSynch, "All files up to date", "TrayInSynch"),
162                 new StatusInfo(PithosStatus.Syncing, "Syncing Files", "TraySynching"),
163                 new StatusInfo(PithosStatus.SyncPaused, "Sync Paused", "TraySyncPaused")
164             }.ToDictionary(s => s.Status);
165
166         
167         public void UpdateStatus()
168         {
169             var pithosStatus = _statusChecker.GetPithosStatus();
170
171             if (iconNames.ContainsKey(pithosStatus))
172             {
173                 var info = iconNames[pithosStatus];
174                 StatusIcon = String.Format(@"Images/{0}.ico", info.IconName);
175                 StatusMessage = String.Format("Pithos 1.0\r\n{0}", info.StatusText);
176             }
177
178             var tv=this.GetView();
179             _events.Publish(new Notification { Title = "Start", Message = "Start Monitoring", Level = TraceLevel.Info});
180             if (!String.IsNullOrWhiteSpace(Monitor.UserName) &&
181                 !String.IsNullOrWhiteSpace(Monitor.ApiKey))
182                 StartMonitor();                
183         }
184
185         private void StartMonitor()
186         {
187             Task.Factory.StartNew(() =>
188             {
189                 try
190                 {
191                     Monitor.Start();
192                 }
193                 catch(Exception exc)
194                 {
195                     var message = String.Format("An exception occured. Can't start monitoring\nWill retry in 10 seconds\n{0}",exc);
196                     _events.Publish(new Notification{Title = "Error", Message = message, Level = TraceLevel.Error});
197                     Task.Factory.StartNewDelayed(10000, StartMonitor);                    
198                 }
199             });
200         }
201
202
203         public void NotifyChange(string status, TraceLevel level=TraceLevel.Info)
204         {
205             this.StatusMessage = status;
206             
207             _events.Publish(new Notification { Title = "Pithos", Message = status, Level = level });
208         }
209
210         public void NotifyChangedFile(string filePath)
211         {
212             var entry = new FileEntry {FullPath=filePath};
213             IProducerConsumerCollection<FileEntry> files=this.RecentFiles;
214             FileEntry popped;
215             while (files.Count > 5)
216                 files.TryTake(out popped);
217             files.TryAdd(entry);
218         }
219     }
220 }