Kenneth Bruen
3 months ago
2 changed files with 117 additions and 116 deletions
@ -1,114 +1,115 @@ |
|||||||
using System; |
using System; |
||||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||||
using System.Diagnostics; |
using System.Diagnostics; |
||||||
using System.Net; |
using System.Net; |
||||||
using System.Net.Http; |
using System.Net.Http; |
||||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||||
using InfoferScraper; |
using InfoferScraper; |
||||||
using InfoferScraper.Models.Station; |
using InfoferScraper.Models.Station; |
||||||
using InfoferScraper.Models.Train; |
using InfoferScraper.Models.Train; |
||||||
using Microsoft.Extensions.Logging; |
using Microsoft.Extensions.Logging; |
||||||
using scraper.Models.Itinerary; |
using Microsoft.Extensions.Options; |
||||||
using Server.Models; |
using scraper.Models.Itinerary; |
||||||
using Server.Services.Interfaces; |
using Server.Models; |
||||||
using Server.Utils; |
using Server.Services.Interfaces; |
||||||
|
using Server.Utils; |
||||||
namespace Server.Services.Implementations { |
|
||||||
public class DataManager : IDataManager { |
namespace Server.Services.Implementations { |
||||||
private ILogger<DataManager> Logger { get; } |
public class DataManager : IDataManager { |
||||||
private IDatabase Database { get; } |
private ILogger<DataManager> Logger { get; } |
||||||
|
private IDatabase Database { get; } |
||||||
private NodaTime.IDateTimeZoneProvider TzProvider { get; } |
|
||||||
private NodaTime.DateTimeZone CfrTimeZone => TzProvider["Europe/Bucharest"]; |
private NodaTime.IDateTimeZoneProvider TzProvider { get; } |
||||||
|
private NodaTime.DateTimeZone CfrTimeZone => TzProvider["Europe/Bucharest"]; |
||||||
public DataManager(NodaTime.IDateTimeZoneProvider tzProvider, IDatabase database, ILogger<DataManager> logger, ProxySettings? proxySettings) { |
|
||||||
this.TzProvider = tzProvider; |
public DataManager(NodaTime.IDateTimeZoneProvider tzProvider, IDatabase database, ILogger<DataManager> logger, IOptions<ProxySettings> proxySettings) { |
||||||
this.Database = database; |
this.TzProvider = tzProvider; |
||||||
this.Logger = logger; |
this.Database = database; |
||||||
|
this.Logger = logger; |
||||||
HttpClientHandler httpClientHandler = new (){ |
|
||||||
UseProxy = proxySettings != null, |
HttpClientHandler httpClientHandler = new() { |
||||||
Proxy = proxySettings == null ? null : new WebProxy(proxySettings.Url), |
UseProxy = proxySettings.Value.UseProxy, |
||||||
DefaultProxyCredentials = proxySettings?.Credentials == null ? null : new NetworkCredential(proxySettings.Credentials.Username, proxySettings.Credentials.Password), |
Proxy = proxySettings.Value.UseProxy ? new WebProxy(proxySettings.Value.Url) : null, |
||||||
}; |
DefaultProxyCredentials = string.IsNullOrEmpty(proxySettings.Value.Credentials?.Username) ? null : new NetworkCredential(proxySettings.Value.Credentials.Username, proxySettings.Value.Credentials.Password), |
||||||
InfoferScraper.Scrapers.StationScraper stationScraper = new(httpClientHandler); |
}; |
||||||
InfoferScraper.Scrapers.TrainScraper trainScraper = new(httpClientHandler); |
InfoferScraper.Scrapers.StationScraper stationScraper = new(httpClientHandler); |
||||||
InfoferScraper.Scrapers.RouteScraper routeScraper = new(httpClientHandler); |
InfoferScraper.Scrapers.TrainScraper trainScraper = new(httpClientHandler); |
||||||
|
InfoferScraper.Scrapers.RouteScraper routeScraper = new(httpClientHandler); |
||||||
stationCache = new(async (t) => { |
|
||||||
var (stationName, date) = t; |
stationCache = new(async (t) => { |
||||||
Logger.LogDebug("Fetching station {StationName} for date {Date}", stationName, date); |
var (stationName, date) = t; |
||||||
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
Logger.LogDebug("Fetching station {StationName} for date {Date}", stationName, date); |
||||||
|
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
||||||
var station = await stationScraper.Scrape(stationName, zonedDate.ToDateTimeOffset()); |
|
||||||
if (station != null) { |
var station = await stationScraper.Scrape(stationName, zonedDate.ToDateTimeOffset()); |
||||||
_ = Task.Run(async () => { |
if (station != null) { |
||||||
var watch = Stopwatch.StartNew(); |
_ = Task.Run(async () => { |
||||||
await Database.OnStationData(station); |
var watch = Stopwatch.StartNew(); |
||||||
var ms = watch.ElapsedMilliseconds; |
await Database.OnStationData(station); |
||||||
Logger.LogInformation("OnStationData timing: {StationDataMs} ms", ms); |
var ms = watch.ElapsedMilliseconds; |
||||||
}); |
Logger.LogInformation("OnStationData timing: {StationDataMs} ms", ms); |
||||||
} |
}); |
||||||
return station; |
} |
||||||
}, TimeSpan.FromMinutes(1)); |
return station; |
||||||
trainCache = new(async (t) => { |
}, TimeSpan.FromMinutes(1)); |
||||||
var (trainNumber, date) = t; |
trainCache = new(async (t) => { |
||||||
Logger.LogDebug("Fetching train {TrainNumber} for date {Date}", trainNumber, date); |
var (trainNumber, date) = t; |
||||||
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
Logger.LogDebug("Fetching train {TrainNumber} for date {Date}", trainNumber, date); |
||||||
|
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
||||||
var train = await trainScraper.Scrape(trainNumber, zonedDate.ToDateTimeOffset()); |
|
||||||
if (train != null) { |
var train = await trainScraper.Scrape(trainNumber, zonedDate.ToDateTimeOffset()); |
||||||
_ = Task.Run(async () => { |
if (train != null) { |
||||||
var watch = Stopwatch.StartNew(); |
_ = Task.Run(async () => { |
||||||
await Database.OnTrainData(train); |
var watch = Stopwatch.StartNew(); |
||||||
var ms = watch.ElapsedMilliseconds; |
await Database.OnTrainData(train); |
||||||
Logger.LogInformation("OnTrainData timing: {StationDataMs} ms", ms); |
var ms = watch.ElapsedMilliseconds; |
||||||
}); |
Logger.LogInformation("OnTrainData timing: {StationDataMs} ms", ms); |
||||||
} |
}); |
||||||
return train; |
} |
||||||
}, TimeSpan.FromSeconds(30)); |
return train; |
||||||
itinerariesCache = new(async (t) => { |
}, TimeSpan.FromSeconds(30)); |
||||||
var (from, to, date) = t; |
itinerariesCache = new(async (t) => { |
||||||
Logger.LogDebug("Fetching itinerary from {From} to {To} for date {Date}", from, to, date); |
var (from, to, date) = t; |
||||||
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
Logger.LogDebug("Fetching itinerary from {From} to {To} for date {Date}", from, to, date); |
||||||
|
var zonedDate = new NodaTime.LocalDate(date.Year, date.Month, date.Day).AtStartOfDayInZone(CfrTimeZone); |
||||||
var itineraries = await routeScraper.Scrape(from, to, zonedDate.ToDateTimeOffset()); |
|
||||||
if (itineraries != null) { |
var itineraries = await routeScraper.Scrape(from, to, zonedDate.ToDateTimeOffset()); |
||||||
_ = Task.Run(async () => { |
if (itineraries != null) { |
||||||
var watch = Stopwatch.StartNew(); |
_ = Task.Run(async () => { |
||||||
await Database.OnItineraries(itineraries); |
var watch = Stopwatch.StartNew(); |
||||||
var ms = watch.ElapsedMilliseconds; |
await Database.OnItineraries(itineraries); |
||||||
Logger.LogInformation("OnItineraries timing: {StationDataMs} ms", ms); |
var ms = watch.ElapsedMilliseconds; |
||||||
}); |
Logger.LogInformation("OnItineraries timing: {StationDataMs} ms", ms); |
||||||
} |
}); |
||||||
|
} |
||||||
return itineraries; |
|
||||||
}, TimeSpan.FromMinutes(1)); |
return itineraries; |
||||||
} |
}, TimeSpan.FromMinutes(1)); |
||||||
|
} |
||||||
private readonly AsyncCache<(string, DateOnly), IStationScrapeResult?> stationCache; |
|
||||||
private readonly AsyncCache<(string, DateOnly), ITrainScrapeResult?> trainCache; |
private readonly AsyncCache<(string, DateOnly), IStationScrapeResult?> stationCache; |
||||||
private readonly AsyncCache<(string, string, DateOnly), IReadOnlyList<IItinerary>?> itinerariesCache; |
private readonly AsyncCache<(string, DateOnly), ITrainScrapeResult?> trainCache; |
||||||
|
private readonly AsyncCache<(string, string, DateOnly), IReadOnlyList<IItinerary>?> itinerariesCache; |
||||||
public Task<IStationScrapeResult?> FetchStation(string stationName, DateTimeOffset date) { |
|
||||||
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date), CfrTimeZone); |
public Task<IStationScrapeResult?> FetchStation(string stationName, DateTimeOffset date) { |
||||||
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date), CfrTimeZone); |
||||||
|
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
||||||
return stationCache.GetItem((stationName.RoLettersToEn().ToLowerInvariant(), cfrDate)); |
|
||||||
} |
return stationCache.GetItem((stationName.RoLettersToEn().ToLowerInvariant(), cfrDate)); |
||||||
|
} |
||||||
public Task<ITrainScrapeResult?> FetchTrain(string trainNumber, DateTimeOffset date) { |
|
||||||
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date), CfrTimeZone); |
public Task<ITrainScrapeResult?> FetchTrain(string trainNumber, DateTimeOffset date) { |
||||||
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date), CfrTimeZone); |
||||||
|
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
||||||
return trainCache.GetItem((trainNumber, cfrDate)); |
|
||||||
} |
return trainCache.GetItem((trainNumber, cfrDate)); |
||||||
|
} |
||||||
public async Task<IReadOnlyList<IItinerary>?> FetchItineraries(string from, string to, DateTimeOffset? date = null) { |
|
||||||
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date ?? DateTimeOffset.Now), CfrTimeZone); |
public async Task<IReadOnlyList<IItinerary>?> FetchItineraries(string from, string to, DateTimeOffset? date = null) { |
||||||
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
var cfrDateTime = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(date ?? DateTimeOffset.Now), CfrTimeZone); |
||||||
|
var cfrDate = new DateOnly(cfrDateTime.Year, cfrDateTime.Month, cfrDateTime.Day); |
||||||
return await itinerariesCache.GetItem((from, to, cfrDate)); |
|
||||||
} |
return await itinerariesCache.GetItem((from, to, cfrDate)); |
||||||
} |
} |
||||||
} |
} |
||||||
|
} |
||||||
|
Loading…
Reference in new issue