diff options
Diffstat (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels')
| -rw-r--r-- | Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs | 288 | ||||
| -rw-r--r-- | Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs | 1 |
2 files changed, 289 insertions, 0 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs new file mode 100644 index 000000000..52955e18a --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/LogsViewVM.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.Core; +using Tango.Core.Commands; +using Tango.Core.Helpers; +using Tango.FSE.Common; +using Tango.FSE.Common.Connection; +using Tango.FSE.Common.Dialogs; +using Tango.FSE.Common.FileSystem; +using Tango.FSE.Common.Logging; +using Tango.Logging; +using Tango.PPC.Shared.Logs; +using Tango.SharedUI.Components; +using static Tango.SharedUI.Controls.NavigationControl; + +namespace Tango.FSE.PPCConsole.ViewModels +{ + public class LogsViewVM : FSEViewModel, INavigationViewModel + { + private bool _loaded; + + private List<RemoteLogFileModel<LogItemBase>> _logFiles; + /// <summary> + /// Gets or sets the remote log files. + /// </summary> + public List<RemoteLogFileModel<LogItemBase>> LogFiles + { + get { return _logFiles; } + set { _logFiles = value; RaisePropertyChangedAuto(); } + } + + private RemoteLogFileModel<LogItemBase> _selectedLogFile; + /// <summary> + /// Gets or sets the selected remote log file. + /// </summary> + public RemoteLogFileModel<LogItemBase> SelectedLogFile + { + get { return _selectedLogFile; } + set { _selectedLogFile = value; RaisePropertyChangedAuto(); OnSelectedLogFileChanged(); } + } + + /// <summary> + /// Gets or sets the application logs. + /// </summary> + public ObservableCollection<LogItemBase> ApplicationLogs { get; set; } + + /// <summary> + /// Gets or sets the application logs view. + /// </summary> + public ICollectionView ApplicationLogsView { get; set; } + + /// <summary> + /// Gets or sets the selected application logs categories. + /// </summary> + public SelectedObjectCollection<LogCategory> SelectedApplicationLogsCategories { get; set; } + + private String _applicationLogsFilter; + /// <summary> + /// Gets or sets the application logs filter. + /// </summary> + public String ApplicationLogsFilter + { + get { return _applicationLogsFilter; } + set { _applicationLogsFilter = value; RaisePropertyChangedAuto(); ApplicationLogsView.Refresh(); } + } + + /// <summary> + /// Opens the detailed application log dialog. + /// </summary> + public RelayCommand<LogItemBase> OpenApplicationLogItemCommand { get; set; } + + /// <summary> + /// Exports the selected log file to local disk. + /// </summary> + public RelayCommand ExportLogFileCommand { get; set; } + + /// <summary> + /// Exports all the downloaded log files to disk. + /// </summary> + public RelayCommand ExportAllDownloadedLogFilesCommand { get; set; } + + /// <summary> + /// Downloads all the available log files. + /// </summary> + public RelayCommand DownloadAllLogFilesCommand { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="LogsViewVM"/> class. + /// </summary> + public LogsViewVM() + { + ApplicationLogs = new ObservableCollection<LogItemBase>(); + ApplicationLogsView = CollectionViewSource.GetDefaultView(ApplicationLogs); + ApplicationLogsView.Filter = FilterApplicationLogs; + SelectedApplicationLogsCategories = new SelectedObjectCollection<LogCategory>(new ObservableCollection<LogCategory>() + { + LogCategory.Info, + LogCategory.Warning, + LogCategory.Error, + LogCategory.Critical, + }, new ObservableCollection<LogCategory>() + { + LogCategory.Info, + LogCategory.Warning, + LogCategory.Error, + LogCategory.Critical, + }); + + SelectedApplicationLogsCategories.SynchedSource.CollectionChanged += (_, __) => ApplicationLogsView.Refresh(); + + OpenApplicationLogItemCommand = new RelayCommand<LogItemBase>(OpenApplicationLogItem); + + ExportLogFileCommand = new RelayCommand(ExportSelectedLogFile); + ExportAllDownloadedLogFilesCommand = new RelayCommand(ExportAllDownloadedLogFiles); + DownloadAllLogFilesCommand = new RelayCommand(DownloadAllLogFiles); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + MachineProvider.MachineConnected += MachineProvider_MachineConnected; + } + + private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + if (e.DifferentFromPrevious) + { + _loaded = false; + + if (MachineProvider.ConnectionType.IsRemote() && IsVisible) + { + LoadLogFiles(); + } + } + } + + public override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (!_loaded) + { + LoadLogFiles(); + } + } + + private async void LoadLogFiles() + { + if (!MachineProvider.ConnectionType.IsRemote() || !IsFree) return; + + try + { + IsFree = false; + var logFiles = await LoggingProvider.GetApplicationLogFiles(); + LogFiles = logFiles.Select(x => + { + + var model = new RemoteLogFileModel<LogItemBase>(new ApplicationLogFileParser()); + model.RemoteLogFile = x; + model.DownloadCompleted += OnRemoteLogFileDownloadCompleted; + return model; + + }).ToList(); + SelectedLogFile = LogFiles.FirstOrDefault(); + _loaded = true; + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading log files."); + } + finally + { + IsFree = true; + } + } + + private void OnRemoteLogFileDownloadCompleted(object sender, EventArgs e) + { + if (SelectedLogFile == sender) + { + OnSelectedLogFileChanged(); + } + } + + private void OnSelectedLogFileChanged() + { + if (SelectedLogFile == null) return; + + InvokeUI(() => + { + ApplicationLogs.Clear(); + foreach (var logItem in SelectedLogFile.LogItems) + { + ApplicationLogs.Add(logItem); + } + + ApplicationLogsView.Refresh(); + }); + } + + private async void OpenApplicationLogItem(LogItemBase logItem) + { + await NotificationProvider.ShowDialog(new ApplicationLogItemViewVM() { LogItem = logItem }); + } + + private bool FilterApplicationLogs(object obj) + { + var log = obj as LogItemBase; + return SelectedApplicationLogsCategories.SynchedSource.Contains(log.Category) && (String.IsNullOrWhiteSpace(ApplicationLogsFilter) || log.Message.ToLower().Contains(ApplicationLogsFilter.ToLower())); + } + + private async void ExportSelectedLogFile() + { + if (SelectedLogFile != null && SelectedLogFile.Status == RemoteLogFileStatus.Downloaded) + { + var result = await StorageProvider.SaveFile("Export Log File", "Application Log Files|*.log", SelectedLogFile.RemoteLogFile.Name, ".log"); + if (result) + { + using (NotificationProvider.PushTaskItem("Exporting log file...")) + { + try + { + File.Copy(SelectedLogFile.TemporaryFile, result.SelectedItem, true); + await NotificationProvider.ShowSuccess("Log file exported successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error exporting application log file."); + await NotificationProvider.ShowError($"Could not export the log file.\n{ex.FlattenMessage()}"); + } + } + } + } + } + + private async void ExportAllDownloadedLogFiles() + { + var result = await StorageProvider.SelectFolder("Export Log Files"); + if (result) + { + var toExport = LogFiles.Where(x => x.Status == RemoteLogFileStatus.Downloaded).ToList(); + var count = toExport.Count; + + using (var task = NotificationProvider.PushTaskItem("Exporting log files...")) + { + foreach (var logFile in toExport.ToList()) + { + try + { + await Task.Delay(500); + File.Copy(logFile.TemporaryFile, Path.Combine(result.SelectedItem, logFile.RemoteLogFile.Name), true); + toExport.Remove(logFile); + task.UpdateProgress("Exporting log files...", count - toExport.Count, count, false); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error exporting application log file '{logFile.RemoteLogFile.Name}'."); + await NotificationProvider.ShowError($"Could not export '{logFile.RemoteLogFile.Name}'.\n{ex.FlattenMessage()}"); + } + } + } + + await NotificationProvider.ShowSuccess($"Successfully exported {count - toExport.Count} out of {count} log files."); + } + } + + private async void DownloadAllLogFiles() + { + var toDownload = LogFiles.Where(x => x.Status == RemoteLogFileStatus.None); + var totalSize = FileHelper.GetFriendlyFileSize(toDownload.Select(x => x.RemoteLogFile.Length).Sum()); + + if (await NotificationProvider.ShowWarningQuestion($"Are you sure you wish to download the entire history of log files?\nTotal size: {totalSize}", "DOWNLOAD", "CANCEL")) + { + foreach (var logFile in toDownload) + { + logFile.DownloadLogFile(); + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs index e18a75ef6..f4614ccf1 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.PPCConsole/ViewModels/MainViewVM.cs @@ -20,6 +20,7 @@ namespace Tango.FSE.PPCConsole.ViewModels MonitoringView, FileSystemView, UpdatesView, + LogsView, } private NavigationView _selectedView; |
