using Newtonsoft.Json; using System.Net; namespace Fahrplan.Network; /// /// Class to help get the plan from the CCC API /// public class PlanPuller () { public const string PlanJsonUrl = "https://fahrplan.events.ccc.de/congress/2024/fahrplan/schedule/export/schedule.json"; public const string LocalPlanFilename = "ansi-fahrplan.json"; /// /// Pulls the current fahrplan, stores it in a temp /// directory and returns the parsed JSON object. /// If another plan already exists in the temp directory /// and is not older than three minutes, a new plan /// will not yet be pulled to save on web requests /// /// If true, skips checking the timestamp on the plan cache /// Parsed Fahrplan JSON object public async static Task GetFahrplanAsync (bool forcePull = false) { var localPlanFileFullpath = Path.GetTempPath () + LocalPlanFilename; if (File.Exists (localPlanFileFullpath)) { var fileInfo = new FileInfo (localPlanFileFullpath); // File is not older than three minutes, return cached file if (fileInfo.LastWriteTime + TimeSpan.FromMinutes (3) > DateTime.Now) { var reader = fileInfo.OpenText (); var content = await reader.ReadToEndAsync (); return JsonConvert.DeserializeObject (content); } } var httpClient = new HttpClient (); // Be a good netizen, add a proper UA string httpClient.DefaultRequestHeaders.Add ("User-Agent", "AnsiFahrplan/1.0 (by Snep, c3@diskcat.com)"); var response = await httpClient.GetAsync (new Uri (PlanJsonUrl)); response.EnsureSuccessStatusCode (); var responseContent = await response.Content.ReadAsStringAsync (); try { File.WriteAllText (localPlanFileFullpath, responseContent); } catch (Exception ex) { Console.Error.WriteLine ("Warning: Failed to write Plan cache file: " + ex.Message); } return JsonConvert.DeserializeObject (responseContent); } }