private async Task ExportEventsSummary(IEnumerable <BandEventViewModel> bandEvents, CloudDataExporterSettings settings, string filePath, IProgress <BandCloudExportProgress> progress) { // TODO: set more logical initial capacity? var csv = new StringBuilder(500000); var dataToDump = new List <Dictionary <string, object> >(100); var progressReport = new BandCloudExportProgress { TotalEventsToExport = bandEvents.Count(), StatusMessage = "Exporting Events..." }; progress.Report(progressReport); await Task.Yield(); foreach (var bandEvent in bandEvents) { // TODO: I hate this pattern. I should be able to just tell the CloudClient to download all of the data for my event, // or tell the event to download the data itself // TODO: This fits ExportsEventsFull, not Summary //var data = await _cloud.GetFullEventData(bandEvent.Event.EventID, bandEvent.Event.Expanders); //bandEvent.Event.InitFullEventData(data); dataToDump.Add(bandEvent.Event.DumpBasicEventData()); progressReport.ExportedEventsCount++; progress.Report(progressReport); await Task.Yield(); // since we need to update progress, make sure to yield for a bit } CSVExporter.ExportToFile(dataToDump, filePath); }
/// <summary> /// Make sure to call LoadEvents() first, this will then dump everything in Events /// </summary> public async Task ExportFullEventData(string folder, CloudDataExporterSettings settings, IProgress <BandCloudExportProgress> progress) { bool wasError = false; // TODO: there is a limit to how quickly we can hit the service. This limit should be enforced at // a global level var progressReport = new BandCloudExportProgress() { TotalEventsToExport = Events.Count }; foreach (var eventViewModel in Events) { if (CancelFullExport) { CancelFullExport = false; return; } ++progressReport.ExportedEventsCount; progressReport.StatusMessage = "Loading data for activity " + progressReport.ExportedEventsCount + "/" + Events.Count + " (" + eventViewModel.Event.FriendlyEventType + ")\n\nNote: This can take a while as the Health service imposes limits on how fast we can pull data."; progress.Report(progressReport); System.Diagnostics.Debug.WriteLine("loading " + progressReport.ExportedEventsCount); try { await eventViewModel.LoadFull(); } catch (WebException e) { progressReport.StatusMessage = "Sadly there was an error downloading your data on activity number " + progressReport.ExportedEventsCount + "/" + Events.Count + ". We're going to try to continue in just a moment...\n\nError: " + e.Message; progress.Report(progressReport); wasError = true; } // TODO: display error count? // TODO: abort after X number of errors? if (wasError) { await Task.Delay(10000); wasError = false; } var bandEvent = eventViewModel.Event; foreach (var exporter in bandEvent.Exporters) { var dateTime = (settings.ConvertDateTimeToLocal ? bandEvent.StartTime.ToLocalTime() : bandEvent.StartTime); var filePath = System.IO.Path.Combine(folder, bandEvent.FriendlyEventType + "_" + dateTime.ToString("yyyyMMdd_hhmm") + "_" + exporter.DefaultExportSuffix + exporter.DefaultExtension); // export in the background, no await exporter.ExportToFile(bandEvent, filePath); } } }
public async Task ExportEventsSummaryToCSV(int?count, CloudDataExporterSettings settings, string fileName, IProgress <BandCloudExportProgress> progress) { // TODO: Still need to find a better way to load events incrementally if (count == null) { count = 10000000; // suitably large number to encompass "everything". } if (Events.Count < count) { // clear out our existing events, since they're going to be replaced Events.Clear(); progress.Report(new BandCloudExportProgress { TotalEventsToExport = 0, StatusMessage = "Downloading Events..." }); await LoadEvents((int)count); } // we have now downloaded the correct number of events, export them // Note: Take will take min(Events.Count, count) await ExportEventsSummary( Events.Where(e => { return((settings.IncludeRuns && e.Event.EventType == BandEventType.Running) || (settings.IncludeSleep && e.Event.EventType == BandEventType.Sleeping) || (settings.IncludeWorkouts && (e.Event.EventType == BandEventType.GuidedWorkout || e.Event.EventType == BandEventType.Workout)) || (settings.IncludeSteps && (e.Event.EventType == BandEventType.UserDailyActivity)) || (settings.IncludeBiking && (e.Event.EventType == BandEventType.Biking)) ); } ) .Take((int)count), settings, fileName, progress ); }
/// <summary> /// Make sure to call LoadEvents() first, this will then dump everything in Events /// </summary> public async Task ExportFullEventData(string folder, CloudDataExporterSettings settings, IProgress <BandCloudExportProgress> progress) { // TODO: there is a limit to how quickly we can hit the service. This limit should be enforced at // a global level var progressReport = new BandCloudExportProgress() { TotalEventsToExport = Events.Count }; foreach (var eventViewModel in Events) { if (CancelFullExport) { CancelFullExport = false; return; } ++progressReport.ExportedEventsCount; progressReport.StatusMessage = "Loading data for activity " + progressReport.ExportedEventsCount + "/" + Events.Count + " (" + eventViewModel.Event.FriendlyEventType + ")\n\nNote: This can take a while, we are restricted to loading full data for one Activity per 10 seconds."; progress.Report(progressReport); System.Diagnostics.Debug.WriteLine("loading " + progressReport.ExportedEventsCount); await eventViewModel.LoadFull(); var bandEvent = eventViewModel.Event; foreach (var exporter in bandEvent.Exporters) { var dateTime = (settings.ConvertDateTimeToLocal ? bandEvent.StartTime.ToLocalTime() : bandEvent.StartTime); var filePath = System.IO.Path.Combine(folder, bandEvent.FriendlyEventType + "_" + dateTime.ToString("yyyyMMdd_hhmm") + "_" + exporter.DefaultExportSuffix + exporter.DefaultExtension); // export in the background, no await exporter.ExportToFile(bandEvent, filePath); } // we are restricted to loading an event / 10 seconds (approximately). See https://github.com/nachmore/unBand/issues/20 // for more details await Task.Delay(10000); } }
/// <summary> /// Make sure to call LoadEvents() first, this will then dump everything in Events /// </summary> public async Task ExportFullEventData(string folder, CloudDataExporterSettings settings, IProgress<BandCloudExportProgress> progress) { bool wasError = false; // TODO: there is a limit to how quickly we can hit the service. This limit should be enforced at // a global level var progressReport = new BandCloudExportProgress() { TotalEventsToExport = Events.Count }; foreach (var eventViewModel in Events) { if (CancelFullExport) { CancelFullExport = false; return; } ++progressReport.ExportedEventsCount; progressReport.StatusMessage = "Loading data for activity " + progressReport.ExportedEventsCount + "/" + Events.Count + " (" + eventViewModel.Event.FriendlyEventType + ")\n\nNote: This can take a while as the Health service imposes limits on how fast we can pull data."; progress.Report(progressReport); System.Diagnostics.Debug.WriteLine("loading " + progressReport.ExportedEventsCount); try { await eventViewModel.LoadFull(); } catch (WebException e) { progressReport.StatusMessage = "Sadly there was an error downloading your data on activity number " + progressReport.ExportedEventsCount + "/" + Events.Count + ". We're going to try to continue in just a moment...\n\nError: " + e.Message; progress.Report(progressReport); wasError = true; } // TODO: display error count? // TODO: abort after X number of errors? if (wasError) { await Task.Delay(10000); wasError = false; } var bandEvent = eventViewModel.Event; foreach (var exporter in bandEvent.Exporters) { var dateTime = (settings.ConvertDateTimeToLocal ? bandEvent.StartTime.ToLocalTime() : bandEvent.StartTime); var filePath = System.IO.Path.Combine(folder, bandEvent.FriendlyEventType + "_" + dateTime.ToString("yyyyMMdd_hhmm") + "_" + exporter.DefaultExportSuffix + exporter.DefaultExtension); // export in the background, no await exporter.ExportToFile(bandEvent, filePath); } } }
private async Task ExportEventsSummary(IEnumerable<BandEventViewModel> bandEvents, CloudDataExporterSettings settings, string filePath, IProgress<BandCloudExportProgress> progress) { // TODO: set more logical initial capacity? var csv = new StringBuilder(500000); var dataToDump = new List<Dictionary<string, object>>(100); var progressReport = new BandCloudExportProgress() { TotalEventsToExport = bandEvents.Count(), StatusMessage = "Exporting Events..." }; progress.Report(progressReport); await Task.Yield(); foreach (var bandEvent in bandEvents) { // TODO: I hate this pattern. I should be able to just tell the CloudClient to download all of the data for my event, // or tell the event to download the data itself // TODO: This fits ExportsEventsFull, not Summary //var data = await _cloud.GetFullEventData(bandEvent.Event.EventID, bandEvent.Event.Expanders); //bandEvent.Event.InitFullEventData(data); dataToDump.Add(bandEvent.Event.DumpBasicEventData()); progressReport.ExportedEventsCount++; progress.Report(progressReport); await Task.Yield(); // since we need to update progress, make sure to yield for a bit } CSVExporter.ExportToFile(dataToDump, filePath); }
public async Task ExportEventsSummaryToCSV(int? count, CloudDataExporterSettings settings, string fileName, IProgress<BandCloudExportProgress> progress) { // TODO: Still need to find a better way to load events incrementally if (count == null) count = 10000000; // suitably large number to encompass "everything". if (Events.Count < count) { // clear out our existing events, since they're going to be replaced Events.Clear(); progress.Report(new BandCloudExportProgress() { TotalEventsToExport = 0, StatusMessage = "Downloading Events..." }); await LoadEvents((int)count); } // we have now downloaded the correct number of events, export them // Note: Take will take min(Events.Count, count) await ExportEventsSummary( Events.Where(e => { return (settings.IncludeRuns && e.Event.EventType == BandEventType.Running) || (settings.IncludeSleep && e.Event.EventType == BandEventType.Sleeping) || (settings.IncludeWorkouts && (e.Event.EventType == BandEventType.GuidedWorkout || e.Event.EventType == BandEventType.Workout)) || (settings.IncludeSteps && (e.Event.EventType == BandEventType.UserDailyActivity)) || (settings.IncludeBiking && (e.Event.EventType == BandEventType.Biking)) ; } ) .Take((int)count), settings, fileName, progress ); }
private void LoadExportSettings() { ExportSettings = (Settings.Current.ExportSettings ?? new CloudDataExporterSettings()); }