181 lines
6.2 KiB
C#
181 lines
6.2 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
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 delegate void DatabaseUpdateProgressDelegate();
|
|
|
|
public event DatabaseAvailableDelegate SystemsAvailable;
|
|
public event DatabaseAvailableDelegate StationsAvailable;
|
|
|
|
public event DatabaseUpdateProgressDelegate DatabaseUpdateProgress;
|
|
public event DatabaseUpdateProgressDelegate DatabaseUpdateFinished;
|
|
|
|
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");
|
|
|
|
this.StationsAvailable += API_StationsAvailable;
|
|
}
|
|
|
|
private void API_StationsAvailable() {
|
|
TranslateStations();
|
|
DatabaseUpdateFinished?.Invoke();
|
|
}
|
|
|
|
private void DownloadFile(string url, string file, DatabaseAvailableDelegate notifier) {
|
|
WebClient client = new WebClient();
|
|
client.DownloadFileCompleted += Client_DownloadFileCompleted;
|
|
client.DownloadProgressChanged += Client_DownloadProgressChanged;
|
|
client.DownloadFileAsync(new Uri(url), file, notifier);
|
|
}
|
|
|
|
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
|
|
DatabaseUpdateProgress?.Invoke();
|
|
}
|
|
|
|
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<int, List<string>> systems = new Dictionary<int, List<string>>();
|
|
|
|
using (var str = new StreamReader(StationsFile)) {
|
|
using (var reader = new JsonTextReader(str)) {
|
|
JArray obj = (JArray)JToken.ReadFrom(reader);
|
|
|
|
foreach (JObject child in obj.Children<JObject>()) {
|
|
int system_id = child.Value<int>("system_id");
|
|
string name = child.Value<string>("name");
|
|
|
|
if (!systems.ContainsKey(system_id)) {
|
|
systems.Add(system_id, new List<string>());
|
|
}
|
|
|
|
DatabaseUpdateProgress?.Invoke();
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|