public static IEnumerable <Activity> MakeValid(this IEnumerable <Activity> source) { if (source == null) { throw new ArgumentNullException("source"); } // Non-null var activities = source.Where((a) => a != null); // Synced if (activities.Any()) { var item = activities.First(); if (!Categories.IsSync(item.Type)) { activities = new List <Activity>() { LivingLogger.GetSync(item.Timestamp) }.Concat(activities); } } return(activities.ToList()); }
void FileSplit() { if (Enabled) { Ui.WriteLine("Cannot split while logging. Please pause."); } else { if (LivingFile.Exists(m_filename)) { Dump(); var info = LivingFile.GetInfo(m_filename); Ui.WriteLine("Files of names " + info.BaseName + ".YYYY-MM" + info.Extension + " will be generated"); System.Diagnostics.Stopwatch w = new System.Diagnostics.Stopwatch(); long counter = 0; var logger = new System.Timers.Timer(); logger.AutoReset = true; logger.Interval = Constants.Second; logger.Elapsed += (s, e) => { Ui.SetStatus("activities: " + Tools.ToHumanString(counter).PadRight(8) + " elapsed: " + w.Elapsed.ToString()); }; logger.Start(); var backups = new Dictionary <string, string>(); try { w.Start(); var activities = LivingFile.ReadActivities(m_filename) .Do(() => ++ counter); foreach (var activityBlock in activities.PartitionBlocks(Constants.ReadingBlockSize)) { var groups = activityBlock .GroupBy((a) => { var at = a.Timestamp.ToDateTime(); return(new { Year = at.Year, Month = at.Month }); }); foreach (var group in groups) { if (group.Any()) { IEnumerable <Activity> groupActivities; var item = group.First(); if (!Categories.IsSync(item.Type)) { // When appending activities, always start with a sync activity // This will help "resorting" activities if needed groupActivities = Enumerable.Repeat(LivingLogger.GetSync(item.Timestamp), 1).Concat(group); } else { groupActivities = group; } lock (locker) { var filename = info.Child(group.Key.Year, group.Key.Month); var backup = filename + ".bak"; if (!backups.ContainsKey(filename)) { if (File.Exists(filename)) { if (File.Exists(backup)) { File.Delete(backup); } File.Copy(filename, backup); } backups.Add(filename, backup); Ui.WriteLine("Writing to " + filename); } Timestamp previous = groupActivities.First().Timestamp; using (var writer = new StreamWriter(File.Open(filename, FileMode.Append))) { foreach (var groupActivityBlock in groupActivities.PartitionBlocks(Constants.WritingBlockSize)) { WriteText(groupActivityBlock, ref previous, writer); } } } } } } Ui.SetStatus("Split task successful."); foreach (var kvp in backups) { counter = 0; w.Restart(); Ui.WriteLine("Processing " + kvp.Key); if (File.Exists(kvp.Value)) { File.Delete(kvp.Value); } if (File.Exists(kvp.Key)) { File.Copy(kvp.Key, kvp.Value); } var processed = ActivityTools.Process( LivingFile .ReadActivities(kvp.Value) .Do(() => ++ counter) ); Timestamp previous = processed.First().Timestamp; using (var writer = new StreamWriter(File.Create(kvp.Key))) { foreach (var pBlock in processed.PartitionBlocks(Constants.WritingBlockSize)) { WriteText(pBlock, ref previous, writer); } } } foreach (var kvp in backups) { if (File.Exists(kvp.Value)) { File.Delete(kvp.Value); } } using (var file = File.Create(m_filename)) { // "using" makes sura that the file is properly closed and not still in use } Ui.SetStatus("Processing task successful."); } catch (Exception e) { Ui.SetStatus("Error during split task. Removing temporary files..."); foreach (var kvp in backups) { if (File.Exists(kvp.Key)) { File.Delete(kvp.Key); } if (File.Exists(kvp.Value)) { File.Move(kvp.Value, kvp.Key); } } } finally { logger.Stop(); } } } }