public void Data_age_filter_removes_data_older_than_the_limit_and_keeps_data_more_recent_than_the_limit() { var fourDaysAgo = HistoryEntry.FromJournalEntry(new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(4)), sol, 0, false, 0), null, out bool notused1); var now = HistoryEntry.FromJournalEntry(new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(0)), sol, 0, false, 0), null, out bool notused2); var input = new HistoryList(new List <HistoryEntry> { fourDaysAgo, now }); Check.That(TravelHistoryFilter.FromDays(2).Filter(input)).ContainsExactly(now); }
public void No_filter_does_not_filter_anything() { JournalFSDJump jsd = new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(500000)), sol, 0, false, 0); var veryOldData = HistoryEntry.FromJournalEntry(jsd, null, out bool notused); var input = new HistoryList(new List <HistoryEntry> { veryOldData }); Check.That(TravelHistoryFilter.NoFilter.Filter(input)).ContainsExactly(veryOldData); }
public void Last_2_items_filter_returns_the_2_most_recent_items_sorted_by_most_recent_and_removes_the_older_items() { var twentyDaysAgo = HistoryEntry.FromJournalEntry(new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(20)), sol, 0, false, 0), null, out bool notused); var tenDaysAgo = HistoryEntry.FromJournalEntry(new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(10)), sol, 0, false, 0), null, out bool notused2); var thirtyDaysAgo = HistoryEntry.FromJournalEntry(new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(30)), sol, 0, false, 0), null, out bool notused3); var input = new HistoryList(new List <HistoryEntry> { twentyDaysAgo, tenDaysAgo, thirtyDaysAgo }); Check.That(TravelHistoryFilter.Last(2).Filter(input)).ContainsExactly(tenDaysAgo, twentyDaysAgo); }
public void Entry(JournalEntry je, bool stored, bool recent) // on UI thread. hooked into journal monitor and receives new entries.. Also call if you programatically add an entry { System.Diagnostics.Debug.Assert(System.Windows.Forms.Application.MessageLoop); if (je.EventTimeUTC >= lastutc) // in case we get them fed in the wrong order, or during stored reply we have two playing, only take the latest one { System.Diagnostics.Debug.WriteLine("JE " + stored + ":" + recent + ":" + EDCommander.GetCommander(je.CommanderId).Name + ":" + je.EventTypeStr); if (je.CommanderId != currentcmdrnr) { Reset(false); currentcmdrnr = je.CommanderId; EDCommander.CurrentCmdrID = currentcmdrnr; } HistoryEntry he = HistoryEntry.FromJournalEntry(je, currenthe, false, out bool unusedjournalupdate); he.UpdateMaterials(je, currenthe); cashledger.Process(je); he.Credits = cashledger.CashTotal; he.UpdateMissionList(missionlistaccumulator.Process(je, he.System, he.WhereAmI)); currenthe = he; lastutc = je.EventTimeUTC; outfitting.Process(je); Tuple <ShipInformation, ModulesInStore> ret = shipinformationlist.Process(je, he.WhereAmI, he.System); he.UpdateShipInformation(ret.Item1); he.UpdateShipStoredModules(ret.Item2); NewEntry?.Invoke(he, stored, recent); } else { //System.Diagnostics.Debug.WriteLine("Rejected older JE " + stored + ":" + recent + ":" + EDCommander.GetCommander(je.CommanderId).Name + " " + je.EventTypeStr); } }
void Process(List <JournalFSDJump> edsmlogs, DateTime logstarttime, DateTime logendtime) { // Get all of the local entries now that we have the entries from EDSM // Moved here to avoid the race that could have been causing duplicate entries // EDSM only returns FSD entries, so only look for them. Tested 27/4/2018 after the HE optimisations List <HistoryEntry> hlfsdlist = JournalEntry.GetAll(Commander.Nr, logstarttime.AddDays(-1), logendtime.AddDays(1)). OfType <JournalLocOrJump>().OrderBy(je => je.EventTimeUTC). Select(je => HistoryEntry.FromJournalEntry(je, null, out bool jupdate)).ToList(); // using HE just because of the FillEDSM func HistoryList hl = new HistoryList(hlfsdlist); // just so we can access the FillEDSM func List <JournalFSDJump> toadd = new List <JournalFSDJump>(); int previdx = -1; foreach (JournalFSDJump jfsd in edsmlogs) // find out list of ones not present { int index = hlfsdlist.FindIndex(x => x.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase) && x.EventTimeUTC.Ticks == jfsd.EventTimeUTC.Ticks); if (index < 0) { // Look for any entries where DST may have thrown off the time foreach (var vi in hlfsdlist.Select((v, i) => new { v = v, i = i }).Where(vi => vi.v.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase))) { if (vi.i > previdx) { double hdiff = vi.v.EventTimeUTC.Subtract(jfsd.EventTimeUTC).TotalHours; if (hdiff >= -2 && hdiff <= 2 && hdiff == Math.Floor(hdiff)) { if (vi.v.System.EDSMID <= 0) // if we don't have a valid EDMSID.. { vi.v.System.EDSMID = 0; hl.FillEDSM(vi.v); } if (vi.v.System.EDSMID <= 0 || vi.v.System.EDSMID == jfsd.EdsmID) { index = vi.i; break; } } } } } if (index < 0) // its not a duplicate, add to db { toadd.Add(jfsd); } else { // it is a duplicate, check if the first discovery flag is set right JournalFSDJump existingfsd = hlfsdlist[index].journalEntry as JournalFSDJump; if (existingfsd != null && existingfsd.EDSMFirstDiscover != jfsd.EDSMFirstDiscover) // if we have a FSD one, and first discover is different { existingfsd.UpdateFirstDiscover(jfsd.EDSMFirstDiscover); } previdx = index; } } if (toadd.Count > 0) // if we have any, we can add { System.Diagnostics.Debug.WriteLine($"Adding EDSM logs count {toadd.Count}"); TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it tlu.type = TravelLogUnit.EDSMType; // EDSM tlu.Name = "EDSM-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); tlu.Size = 0; tlu.Path = "EDSM"; tlu.CommanderId = EDCommander.CurrentCmdrID; tlu.Add(); // Add to Database UserDatabase.Instance.ExecuteWithDatabase(cn => { foreach (JournalFSDJump jfsd in toadd) { System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", jfsd.EventTimeUTC, jfsd.StarSystem)); jfsd.SetTLUCommander(tlu.id, tlu.CommanderId.Value); // update its TLU id to the TLU made above jfsd.Add(jfsd.CreateFSDJournalEntryJson(), cn.Connection); // add it to the db with the JSON created } }); LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}"); OnDownloadedSystems?.Invoke(); } }
private void FetcherThreadProc() { Trace.WriteLine($"EDSM Thread logs start"); bool jupdate = false; DateTime lastCommentFetch = DateTime.MinValue; int waittime = 2000; // Max 1 request every 2 seconds, with a backoff if the rate limit is hit if (EDSMRequestBackoffTime > DateTime.UtcNow) { waittime = (int)Math.Min(EDSMMaxLogAgeMinutes * 60000, Math.Min(BackoffInterval.TotalSeconds * 1000, EDSMRequestBackoffTime.Subtract(DateTime.UtcNow).TotalSeconds * 1000)); } while (!ExitRequested.WaitOne(waittime)) { EDSMClass edsm = new EDSMClass(Commander); if (edsm.ValidCredentials && DateTime.UtcNow > lastCommentFetch.AddHours(1)) { edsm.GetComments(l => Trace.WriteLine(l)); lastCommentFetch = DateTime.UtcNow; } DateTime logstarttime = DateTime.MinValue; // return what we got.. DateTime logendtime = DateTime.MinValue; List <JournalFSDJump> edsmlogs = null; int res = -1; //return code if (edsm.ValidCredentials && Commander.SyncFromEdsm && DateTime.UtcNow > EDSMRequestBackoffTime) { if (DateTime.UtcNow.Subtract(LastEventTime).TotalMinutes >= EDSMMaxLogAgeMinutes) { System.Diagnostics.Debug.WriteLine($"Retrieving EDSM logs starting {LastEventTime}"); res = edsm.GetLogs(LastEventTime, null, out edsmlogs, out logstarttime, out logendtime); } else if (FirstEventTime > GammaStart) { System.Diagnostics.Debug.WriteLine($"Retrieving EDSM logs ending {FirstEventTime}"); res = edsm.GetLogs(null, FirstEventTime, out edsmlogs, out logstarttime, out logendtime); } } if (ExitRequested.WaitOne(0)) { return; } if (res == 429) // Rate Limit Exceeded { Trace.WriteLine($"EDSM Log request rate limit hit - backing off for {BackoffInterval.TotalSeconds}s"); EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval; BackoffInterval = BackoffInterval + TimeSpan.FromSeconds(60); } else if (logstarttime > LastEventTime && logendtime < FirstEventTime) { Trace.WriteLine($"Bad start and/or end times returned by EDSM - backing off for {BackoffInterval.TotalSeconds}s"); EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval; BackoffInterval = BackoffInterval + TimeSpan.FromSeconds(60); } else if (res == 100 && edsmlogs != null) { if (edsmlogs.Count > 0) // if anything to process.. { //Trace.WriteLine($"Retrieving EDSM logs count {edsmlogs.Count}"); BackoffInterval = TimeSpan.FromSeconds(60); if (logendtime > DateTime.UtcNow) { logendtime = DateTime.UtcNow; } if (logstarttime < DateTime.MinValue.AddDays(1)) { logstarttime = DateTime.MinValue.AddDays(1); } // Get all of the local entries now that we have the entries from EDSM // Moved here to avoid the race that could have been causing duplicate entries // EDSM only returns FSD entries, so only look for them. Tested 27/4/2018 after the HE optimisations List <HistoryEntry> hlfsdlist = JournalEntry.GetAll(Commander.Nr, logstarttime.AddDays(-1), logendtime.AddDays(1)). OfType <JournalLocOrJump>().OrderBy(je => je.EventTimeUTC). Select(je => HistoryEntry.FromJournalEntry(je, null, out jupdate)).ToList(); // using HE just because of the FillEDSM func HistoryList hl = new HistoryList(hlfsdlist); // just so we can access the FillEDSM func List <JournalFSDJump> toadd = new List <JournalFSDJump>(); int previdx = -1; foreach (JournalFSDJump jfsd in edsmlogs) // find out list of ones not present { int index = hlfsdlist.FindIndex(x => x.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase) && x.EventTimeUTC.Ticks == jfsd.EventTimeUTC.Ticks); if (index < 0) { // Look for any entries where DST may have thrown off the time foreach (var vi in hlfsdlist.Select((v, i) => new { v = v, i = i }).Where(vi => vi.v.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase))) { if (vi.i > previdx) { double hdiff = vi.v.EventTimeUTC.Subtract(jfsd.EventTimeUTC).TotalHours; if (hdiff >= -2 && hdiff <= 2 && hdiff == Math.Floor(hdiff)) { if (vi.v.System.EDSMID <= 0) // if we don't have a valid EDMSID.. { vi.v.System.EDSMID = 0; hl.FillEDSM(vi.v); } if (vi.v.System.EDSMID <= 0 || vi.v.System.EDSMID == jfsd.EdsmID) { index = vi.i; break; } } } } } if (index < 0) // its not a duplicate, add to db { toadd.Add(jfsd); } else { // it is a duplicate, check if the first discovery flag is set right JournalFSDJump existingfsd = hlfsdlist[index].journalEntry as JournalFSDJump; if (existingfsd != null && existingfsd.EDSMFirstDiscover != jfsd.EDSMFirstDiscover) // if we have a FSD one, and first discover is different { existingfsd.UpdateFirstDiscover(jfsd.EDSMFirstDiscover); } previdx = index; } } if (toadd.Count > 0) // if we have any, we can add { Trace.WriteLine($"Adding EDSM logs count {toadd.Count}"); TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it tlu.type = 2; // EDSM tlu.Name = "EDSM-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); tlu.Size = 0; tlu.Path = "EDSM"; tlu.CommanderId = EDCommander.CurrentCmdrID; tlu.Add(); // Add to Database using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true)) { foreach (JournalFSDJump jfsd in toadd) { System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", jfsd.EventTimeUTC, jfsd.StarSystem)); jfsd.SetTLUCommander(tlu.id, jfsd.CommanderId); // update its TLU id to the TLU made above jfsd.Add(jfsd.CreateFSDJournalEntryJson(), cn); } } LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}"); if (logendtime > LastEventTime || logstarttime <= GammaStart) { if (OnDownloadedSystems != null) { OnDownloadedSystems(); } } } } if (logstarttime < FirstEventTime) { FirstEventTime = logstarttime; } if (logendtime > LastEventTime) { LastEventTime = logendtime; } } } }
private void FetcherThreadProc() { Trace.WriteLine($"EDSM Thread logs start"); bool jupdate = false; int waittime = 2000; // Max 1 request every 2 seconds, with a backoff if the rate limit is hit if (EDSMRequestBackoffTime > DateTime.UtcNow) { waittime = (int)Math.Min(EDSMMaxLogAgeMinutes * 60000, Math.Min(BackoffInterval.TotalSeconds * 1000, EDSMRequestBackoffTime.Subtract(DateTime.UtcNow).TotalSeconds * 1000)); } // get them as of now.. since we are searching back in time it should be okay. On a refresh we would start again! List <HistoryEntry> hlfsdlist = JournalEntry.GetAll(Commander.Nr).OfType <JournalLocOrJump>().OrderBy(je => je.EventTimeUTC).Select(je => HistoryEntry.FromJournalEntry(je, null, false, out jupdate)).ToList(); while (!ExitRequested.WaitOne(waittime)) { EDSMClass edsm = new EDSMClass { apiKey = Commander.APIKey, commanderName = Commander.EdsmName }; List <HistoryEntry> edsmlogs = null; DateTime logstarttime = DateTime.MinValue; DateTime logendtime = DateTime.MinValue; int res = -1; if (edsm.IsApiKeySet && Commander.SyncFromEdsm && DateTime.UtcNow > EDSMRequestBackoffTime) { if (DateTime.UtcNow.Subtract(LastEventTime).TotalMinutes >= EDSMMaxLogAgeMinutes) { //Trace.WriteLine($"Retrieving EDSM logs starting {LastEventTime}"); res = edsm.GetLogs(LastEventTime, null, out edsmlogs, out logstarttime, out logendtime); } else if (FirstEventTime > GammaStart) { //Trace.WriteLine($"Retrieving EDSM logs ending {FirstEventTime}"); res = edsm.GetLogs(null, FirstEventTime, out edsmlogs, out logstarttime, out logendtime); } } if (ExitRequested.WaitOne(0)) { return; } if (res == 429) // Rate Limit Exceeded { Trace.WriteLine($"EDSM Log request rate limit hit - backing off for {BackoffInterval.TotalSeconds}s"); EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval; BackoffInterval = BackoffInterval + TimeSpan.FromSeconds(60); } else if (logstarttime > LastEventTime && logendtime < FirstEventTime) { Trace.WriteLine($"Bad start and/or end times returned by EDSM - backing off for {BackoffInterval.TotalSeconds}s"); EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval; BackoffInterval = BackoffInterval + TimeSpan.FromSeconds(60); } else if (res == 100 && edsmlogs != null) { if (edsmlogs.Count > 0) // if anything to process.. { //Trace.WriteLine($"Retrieving EDSM logs count {edsmlogs.Count}"); BackoffInterval = TimeSpan.FromSeconds(60); if (logendtime > DateTime.UtcNow) { logendtime = DateTime.UtcNow; } HistoryList hl = new HistoryList(hlfsdlist); List <DateTime> hlfsdtimes = hlfsdlist.Select(he => he.EventTimeUTC).ToList(); List <HistoryEntry> toadd = new List <HistoryEntry>(); int previdx = -1; foreach (HistoryEntry he in edsmlogs) // find out list of ones not present { int index = hlfsdlist.FindIndex(x => x.System.name.Equals(he.System.name, StringComparison.InvariantCultureIgnoreCase) && x.EventTimeUTC.Ticks == he.EventTimeUTC.Ticks); if (index < 0) { // Look for any entries where DST may have thrown off the time foreach (var vi in hlfsdlist.Select((v, i) => new { v = v, i = i }).Where(vi => vi.v.System.name.Equals(he.System.name, StringComparison.InvariantCultureIgnoreCase))) { if (vi.i > previdx) { double hdiff = vi.v.EventTimeUTC.Subtract(he.EventTimeUTC).TotalHours; if (hdiff >= -2 && hdiff <= 2 && hdiff == Math.Floor(hdiff)) { if (vi.v.System.id_edsm <= 0) { vi.v.System.id_edsm = 0; hl.FillEDSM(vi.v); } if (vi.v.System.id_edsm <= 0 || vi.v.System.id_edsm == he.System.id_edsm) { index = vi.i; break; } } } } } if (index < 0) { toadd.Add(he); } else { HistoryEntry lhe = hlfsdlist[index]; if (he.IsEDSMFirstDiscover && !lhe.IsEDSMFirstDiscover) { lhe.SetFirstDiscover(); } previdx = index; } } if (toadd.Count > 0) // if we have any, we can add { Trace.WriteLine($"Adding EDSM logs count {toadd.Count}"); TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it tlu.type = 2; // EDSM tlu.Name = "EDSM-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); tlu.Size = 0; tlu.Path = "EDSM"; tlu.CommanderId = EDCommander.CurrentCmdrID; tlu.Add(); // Add to Database using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true)) { foreach (HistoryEntry he in toadd) { JObject jo = JournalEntry.CreateFSDJournalEntryJson(he.EventTimeUTC, he.System.name, he.System.x, he.System.y, he.System.z, EliteConfigInstance.InstanceConfig.DefaultMapColour); JournalEntry je = JournalEntry.CreateFSDJournalEntry(tlu.id, tlu.CommanderId.Value, (int)SyncFlags.EDSM, jo); System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", je.EventTimeUTC, he.System.name)); je.Add(jo, cn); } } LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}"); if (logendtime > LastEventTime || logstarttime <= GammaStart) { if (OnDownloadedSystems != null) { OnDownloadedSystems(); } } } } if (logstarttime < FirstEventTime) { FirstEventTime = logstarttime; } if (logendtime > LastEventTime) { LastEventTime = logendtime; } } } }