226 lines
12 KiB
C#
226 lines
12 KiB
C#
using DocumentFormat.OpenXml.Drawing.Diagrams;
|
|
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Dbas;
|
|
using Sarand.Net.Standard.Base.Helpers;
|
|
using Sarand.Net.Standard.Base.Tasks;
|
|
using Sarand.Net.Standard.Base.Utils;
|
|
using Saxonite.Net.Standard.Base.App;
|
|
using Saxonite.Net.Standard.Base.Bus.Reference;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Saxonite.Net.Core.Web.Base.Procs
|
|
{
|
|
//=======================================================================
|
|
partial class SaxGolfUsgaDataLookup
|
|
{
|
|
//-------------------------------------------------------------------
|
|
private class ScheduledUsgaDataLookupControlData
|
|
{
|
|
public DateTime CountriesLastLookedUp { get; set; } = DateTime.Now;
|
|
}
|
|
private static ScheduledUsgaDataLookupControlData usgaDataLookupControl { get; } = new ScheduledUsgaDataLookupControlData();
|
|
|
|
/// <summary>
|
|
/// Determine which USGA data population process to run.
|
|
/// <para>- Method is invoked periodically (every 20 mins) by the Admin Hosted Service Console.</para>
|
|
/// <para>- 1. Populate countries if not already done or not done for a while (eg. 24 hours).</para>
|
|
/// <para>- 2. Populate provinces for a Country that has none or occasionally to refresh one that has.</para>
|
|
/// <para>- 3. Populate Courses for a Province that has none or occasionally to refresh one that has.</para>
|
|
/// <para>- 4. Populate Courses for a Province that has none or occasionally to refresh one that has.</para>
|
|
/// </summary>
|
|
public static void ExecuteScheduledUsgaDataLookup(SaxSessionContext sessionContext, DbUpdateInfo dbUpdateInfo, SacsTaskData taskData)
|
|
{
|
|
SaLogger.Debug($"{SysUtil.Fn}");
|
|
|
|
using (DisposableCollection<SacsDisposable> disposableItems = new DisposableCollection<SacsDisposable>())
|
|
{
|
|
SaxInternals internals = new SaxInternals(sessionContext);
|
|
disposableItems.Add(internals);
|
|
|
|
// Configure process.
|
|
SaxGolfUsgaDataLookup.Config courseLookupConfig = new SaxGolfUsgaDataLookup.Config(sessionContext, dbUpdateInfo);
|
|
SaxGolfUsgaDataLookup usgaDataLookup = new SaxGolfUsgaDataLookup(courseLookupConfig);
|
|
|
|
if (taskData.IsCancellationRequested) return;
|
|
|
|
// Determine which process to run.
|
|
// Check USGA country population.
|
|
List<SaxGolfUsgaCountry> usgaCountries = internals.ReferenceGolfMgr.GetUsgaCountryList(new SaxGolfUsgaCountry.Params());
|
|
if (!usgaCountries.Any() || (DateTime.Now - usgaDataLookupControl.CountriesLastLookedUp).TotalHours > MathUtil.Constrain(Sax.Config.Admin.Processes.Scheduled.UsgaGolfDataLookup.HoursBetweenCountryLookup, 1, 24 * 7))
|
|
{
|
|
// No countries currently found or long enough since last lookup.
|
|
// Lookup USGA countries.
|
|
List<SaxGolfUsgaDataLookup.CountryData> countriesData = usgaDataLookup.LookupUsgaCountries();
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Countries populated: {countriesData.Count}.", true);
|
|
usgaDataLookupControl.CountriesLastLookedUp = DateTime.Now;
|
|
return;
|
|
}
|
|
if (taskData.IsCancellationRequested) return;
|
|
|
|
// Population of Countries without Provinces is only allowed occasionally to avoid delaying population of lower data.
|
|
bool populateCountryWithNoProvinces = SacsRandomHelper.GetInt32(1, 7) == 1;
|
|
|
|
// Check USGA Country Province population.
|
|
List<SaxGolfUsgaCountry> usgaCountriesWithProvinces = new List<SaxGolfUsgaCountry>();
|
|
List<SaxGolfUsgaCountry> usgaCountriesWithNoProvinces = new List<SaxGolfUsgaCountry>();
|
|
foreach (SaxGolfUsgaCountry usgaCountry in usgaCountries.OrderBy(item => item.Priority ? 0 : 1).ThenBy(_ => SacsRandomHelper.GetInt32(Int32.MaxValue)))
|
|
{
|
|
SaxGolfUsgaProvince.Params prmUsgaProvince = new SaxGolfUsgaProvince.Params();
|
|
prmUsgaProvince.CountryIdsIncluded.Add(usgaCountry.Id);
|
|
if (internals.ReferenceGolfMgr.GetUsgaProvinceCount(prmUsgaProvince) < 1)
|
|
{
|
|
usgaCountriesWithNoProvinces.Add(usgaCountry);
|
|
if (populateCountryWithNoProvinces)
|
|
{
|
|
// Country has no Provinces - look them up.
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces populated for {usgaCountry.CountryCode} {usgaCountry.CountryName}" + (usgaCountry.Priority ? " [Priority]" : "") + $": {provincesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Country has Provinces.
|
|
usgaCountriesWithProvinces.Add(usgaCountry);
|
|
}
|
|
if (taskData.IsCancellationRequested) return;
|
|
}
|
|
|
|
if (usgaCountriesWithProvinces.Any())
|
|
{
|
|
// Pick the first (randomly sorted) Country.
|
|
SaxGolfUsgaCountry usgaCountry = usgaCountriesWithProvinces[0];
|
|
|
|
// One of the Countries with Provinces can have its list of provinces refreshed occasionally.
|
|
bool refreshCountryWithProvinces = SacsRandomHelper.GetInt32(1, 17) == 1;
|
|
if (refreshCountryWithProvinces)
|
|
{
|
|
SaxGolfUsgaProvince.Params prmUsgaProvince = new SaxGolfUsgaProvince.Params();
|
|
prmUsgaProvince.CountryIdsIncluded.Add(usgaCountry.Id);
|
|
List<SaxGolfUsgaProvince> usgaProvinces = internals.ReferenceGolfMgr.GetUsgaProvinceList(prmUsgaProvince).OrderBy(item => item.Priority ? 0 : 1).ThenBy(_ => SacsRandomHelper.GetInt32(Int32.MaxValue)).ToList();
|
|
if (usgaProvinces.Any())
|
|
{
|
|
// Refresh Country Provinces.
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces refreshed for {usgaCountry.CountryCode} {usgaCountry.CountryName}" + (usgaCountry.Priority ? " [Priority]" : "") + $": {provincesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (usgaCountriesWithProvinces.Any())
|
|
{
|
|
// Pick the first (randomly sorted) Country.
|
|
SaxGolfUsgaCountry usgaCountry = usgaCountriesWithProvinces[0];
|
|
|
|
// Population of Courses for Province without Facilities is allowed occasionally.
|
|
bool populateProvinceWithNoFacilities = SacsRandomHelper.GetInt32(1, 7) == 1;
|
|
|
|
// Check USGA Province Course population.
|
|
List<SaxGolfUsgaProvince> usgaProvincesWithFacilities = new List<SaxGolfUsgaProvince>();
|
|
List<SaxGolfUsgaProvince> usgaProvincesWithNoFacilities = new List<SaxGolfUsgaProvince>();
|
|
SaxGolfUsgaProvince.Params prmUsgaProvince = new SaxGolfUsgaProvince.Params();
|
|
prmUsgaProvince.CountryIdsIncluded.Add(usgaCountry.Id);
|
|
foreach (SaxGolfUsgaProvince usgaProvince in internals.ReferenceGolfMgr.GetUsgaProvinceList(prmUsgaProvince).OrderBy(item => item.Priority ? 0 : 1).ThenBy(_ => SacsRandomHelper.GetInt32(Int32.MaxValue)))
|
|
{
|
|
SaxGolfUsgaFacility.Params prmUsgaFacility = new SaxGolfUsgaFacility.Params();
|
|
prmUsgaFacility.ProvinceIdsIncluded.Add(usgaProvince.Id);
|
|
if (internals.ReferenceGolfMgr.GetUsgaFacilityCount(prmUsgaFacility) < 1)
|
|
{
|
|
usgaProvincesWithNoFacilities.Add(usgaProvince);
|
|
if (populateProvinceWithNoFacilities)
|
|
{
|
|
// Province has no Facilities - look up the courses.
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = usgaDataLookup.LookupUsgaCoursesForCountryAndProvince(usgaCountry.CountryCode, usgaProvince.ProvinceCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Courses populated for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName}" + (usgaProvince.Priority ? " [Priority]" : "") + $": {coursesData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Country has provinces.
|
|
usgaProvincesWithFacilities.Add(usgaProvince);
|
|
}
|
|
if (taskData.IsCancellationRequested) return;
|
|
}
|
|
|
|
if (usgaProvincesWithFacilities.Any())
|
|
{
|
|
// Pick the first (randomly sorted) province.
|
|
SaxGolfUsgaProvince usgaProvince = usgaProvincesWithFacilities[0];
|
|
|
|
// Population of Courses for Province with Facilities is allowed occasionally.
|
|
bool populateProvinceWithFacilities = SacsRandomHelper.GetInt32(1, 17) == 1;
|
|
if (populateProvinceWithFacilities)
|
|
{
|
|
// Refresh Courses for Province with Facilities.
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = usgaDataLookup.LookupUsgaCoursesForCountryAndProvince(usgaCountry.CountryCode, usgaProvince.ProvinceCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Courses refreshed for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName}" + (usgaProvince.Priority ? " [Priority]" : "") + $": {coursesData.Count}.", true);
|
|
return;
|
|
}
|
|
|
|
// Compile list of Courses for this province.
|
|
SaxGolfUsgaCourse.Params prmCourse = new SaxGolfUsgaCourse.Params();
|
|
prmCourse.ProvinceIdsIncluded.Add(usgaProvince.Id);
|
|
List<SaxGolfUsgaCourse> usgaCourses = internals.ReferenceGolfMgr.GetUsgaCourseList(prmCourse).OrderBy(item => item.Priority ? 0 : 1).ThenBy(_ => SacsRandomHelper.GetInt32(Int32.MaxValue)).ToList();
|
|
List<SaxGolfUsgaCourse> usgaCoursesWithMarkers = new List<SaxGolfUsgaCourse>();
|
|
foreach (SaxGolfUsgaCourse usgaCourse in usgaCourses)
|
|
{
|
|
SaxGolfUsgaMarker.Params prmMarker = new SaxGolfUsgaMarker.Params();
|
|
prmMarker.CourseIdsIncluded.Add(usgaCourse.Id);
|
|
if (internals.ReferenceGolfMgr.GetUsgaMarkerCount(prmMarker) == 0)
|
|
{
|
|
// Populate Markers for first course without markers.
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = usgaDataLookup.LookupUsgaMarkersForCourse(usgaCourse.CourseId);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Markers populated for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName} - {usgaCourse.Caption} [Id: {usgaCourse.CourseId}" + (usgaCourse.Priority ? ", Priority" : "") + $"]: {markersData.Count}.", true);
|
|
return;
|
|
}
|
|
else usgaCoursesWithMarkers.Add(usgaCourse);
|
|
}
|
|
if (usgaCoursesWithMarkers.Any())
|
|
{
|
|
// Populate Markers for first course with markers.
|
|
SaxGolfUsgaCourse usgaCourse = usgaCoursesWithMarkers[0];
|
|
List<SaxGolfUsgaDataLookup.MarkerData> markersData = usgaDataLookup.LookupUsgaMarkersForCourse(usgaCourse.CourseId);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Markers refreshed for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName} - {usgaCourse.Caption} [Id: {usgaCourse.CourseId}" + (usgaCourse.Priority ? ", Priority" : "") + $"]: {markersData.Count}.", true);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Fallback - populate Courses for Province.
|
|
bool allowFallbackCoursePopulation = true;
|
|
if (allowFallbackCoursePopulation)
|
|
{
|
|
SaxGolfUsgaProvince usgaProvince = usgaProvincesWithNoFacilities.Any() ? usgaProvincesWithNoFacilities[0] : usgaProvincesWithFacilities.Any() ? usgaProvincesWithFacilities[0] : null;
|
|
if (usgaCountry != null && usgaProvince != null && usgaCountry.Id.Equals(usgaProvince.CountryId))
|
|
{
|
|
List<SaxGolfUsgaDataLookup.CourseData> coursesData = usgaDataLookup.LookupUsgaCoursesForCountryAndProvince(usgaCountry.CountryCode, usgaProvince.ProvinceCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Courses populated for {usgaCountry.CountryCode} {usgaCountry.CountryName} - {usgaProvince.ProvinceCode} {usgaProvince.ProvinceName}" + (usgaProvince.Priority ? " [Priority]" : "") + $": {coursesData.Count}. [Fallback]", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fallback - populate provinces for country.
|
|
bool allowFallbackProvincePopulation = true;
|
|
if (allowFallbackProvincePopulation)
|
|
{
|
|
SaxGolfUsgaCountry usgaCountry = usgaCountriesWithNoProvinces.Any() ? usgaCountriesWithNoProvinces[0] : usgaCountriesWithProvinces.Any() ? usgaCountriesWithProvinces[0] : null;
|
|
if (usgaCountry != null)
|
|
{
|
|
List<SaxGolfUsgaDataLookup.ProvinceData> provincesData = usgaDataLookup.LookupUsgaProvincesForCountry(usgaCountry.CountryCode);
|
|
SaLogger.Info($"{SysUtil.Fn} USGA Provinces populated for {usgaCountry.CountryCode} {usgaCountry.CountryName}" + (usgaCountry.Priority ? " [Priority]" : "") + $": {provincesData.Count}. [Fallback]", true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|