using System; using System.IO; using System.Net; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace NonaBGS.EDDB { public class API { private static readonly string EDDB_SYSTEMS_ARCHIVE = "https://eddb.io/archive/v6/systems_populated.json"; private static readonly string EDDB_STATIONS_ARCHIVE = "https://eddb.io/archive/v6/stations.json"; private string cache_folder = null; private string systems_file = null; private string stations_file = null; private string stations_file_short = null; public delegate void DatabaseAvailableDelegate(); public event DatabaseAvailableDelegate SystemsAvailable; public event DatabaseAvailableDelegate StationsAvailable; public string SystemsFile => systems_file; public string StationsFile => stations_file; public string StationsFileShort => stations_file_short; public string Cache { get => cache_folder; set => cache_folder = value; } public API(string cache_folder) { Initialise(cache_folder); } private void Initialise(string cache_folder) { this.cache_folder = cache_folder; systems_file = Path.Combine(this.cache_folder, "systems_populated.json"); stations_file = Path.Combine(this.cache_folder, "stations.json"); stations_file_short = Path.Combine(this.cache_folder, "stations_short.json"); } private void DownloadFile(string url, string file, DatabaseAvailableDelegate notifier) { WebClient client = new WebClient(); client.DownloadFileCompleted += Client_DownloadFileCompleted; client.DownloadFileAsync(new Uri(url), file, notifier); } private void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { DatabaseAvailableDelegate notifier = e.UserState as DatabaseAvailableDelegate; notifier?.Invoke(); } private void TranslateStations() { if (!HaveStationsFile) { return; } var short_time = File.GetLastWriteTimeUtc(StationsFileShort); var long_time = File.GetLastWriteTimeUtc(StationsFile); if (HaveStationsFileShort && long_time <= short_time) { return; } Dictionary> systems = new Dictionary>(); using (var str = new StreamReader(StationsFile)) { using (var reader = new JsonTextReader(str)) { JArray obj = (JArray)JToken.ReadFrom(reader); foreach (JObject child in obj.Children()) { int system_id = child.Value("system_id"); string name = child.Value("name"); if (!systems.ContainsKey(system_id)) { systems.Add(system_id, new List()); } systems[system_id].Add(name); } } } JObject short_stations = new JObject(); foreach(int ids in systems.Keys) { JArray station_names = new JArray(); foreach(string system in systems[ids]) { station_names.Add(system); } short_stations.Add(ids.ToString(), station_names); } using (var outstr = new StreamWriter(stations_file_short)) { using (var jwriter = new JsonTextWriter(outstr)) { short_stations.WriteTo(jwriter); } } } public void CheckDatabases() { if (HaveSystemsFile) { SystemsAvailable?.Invoke(); } if (HaveStationsFile) { StationsAvailable?.Invoke(); } } public void Download(bool force) { if (!HaveSystemsFile || force) { DownloadFile(EDDB_SYSTEMS_ARCHIVE, systems_file, SystemsAvailable); } else if (HaveSystemsFile) { SystemsAvailable?.Invoke(); } if (!HaveStationsFile || force) { DownloadFile(EDDB_STATIONS_ARCHIVE, stations_file, StationsAvailable); } else if (HaveStationsFile) { StationsAvailable?.Invoke(); } } public void Download() { Download(false); } public bool HaveSystemsFile { get { return systems_file != null && File.Exists(systems_file); } } public bool HaveStationsFile { get { return stations_file != null && File.Exists(stations_file); } } public bool HaveStationsFileShort { get { return stations_file_short != null && File.Exists(stations_file_short); } } public PopulatedSystems MakePopulatedSystems() { if (!HaveSystemsFile) { throw new InvalidOperationException("no local systems file downloaded"); } return PopulatedSystems.FromFile(SystemsFile); } public Stations MakeStations() { if (!HaveStationsFile) { throw new InvalidOperationException("no local systems file downloaded"); } TranslateStations(); return Stations.FromFile(StationsFileShort); } } }