Initial commit
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BritishHorseRacingApi" Version="1.0.43" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="SuccessfulCode.BetfairApi" Version="1.0.11" />
|
||||
<PackageReference Include="SuccessfulCodeTools" Version="1.0.8" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AutoBet.Db\AutoBet.Db.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="SwiftyMessageHub.Core">
|
||||
<HintPath>..\..\SwiftyMessageHub\SwiftyMessageHub.RabbitMq\bin\Debug\netstandard2.0\SwiftyMessageHub.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SwiftyMessageHub.RabbitMq">
|
||||
<HintPath>..\..\SwiftyMessageHub\SwiftyMessageHub.RabbitMq\bin\Debug\netstandard2.0\SwiftyMessageHub.RabbitMq.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<targets>
|
||||
<target name="logfile" xsi:type="File" fileName="file.txt" />
|
||||
<target name="logconsole" xsi:type="Console" />
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Info" writeTo="logconsole" />
|
||||
<logger name="*" minlevel="Debug" writeTo="logfile" />
|
||||
</rules>
|
||||
</nlog>
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using AutoBet.DataRecorded.RaceResultsDataCollector;
|
||||
using BritishHorseRacingApi;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class PostRaceDataCollectorController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task LoadRaces(PostRaceDataCollectorDetails details)
|
||||
{
|
||||
var api = new ApiClient();
|
||||
Console.WriteLine("Loading races");
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
var results = await db.Races.Where(e => e.RaceDate.Date == details.DateToCollect.Date)
|
||||
.Where(e => !db.RunnerResults.Any(e1 => e1.RaceId == e.RaceId))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var result in results)
|
||||
{
|
||||
await CurrentContext.Hub.SendMessage(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
using BritishHorseRacingApi;
|
||||
using BritishHorseRacingApi.Models;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class PostRaceRunnerCollectorController : MessageController
|
||||
{
|
||||
private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);
|
||||
[MessageRoute]
|
||||
public async Task LoadRaces(Db.Race details)
|
||||
{
|
||||
var api = new ApiClient();
|
||||
Console.WriteLine($"Getting results for race {details.RaceId}");
|
||||
_semaphore.Wait();
|
||||
PagedResult<RunnerResult> results;
|
||||
try
|
||||
{
|
||||
results = await api.GetRaceResults(details.RaceDate.Year, details.RaceId, details.DivisionSequence);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
foreach (var result in results.Data)
|
||||
{
|
||||
await CurrentContext.Hub.SendMessage(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
using BritishHorseRacingApi.Models;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class PostRaceRunnerResultRecorderController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task SaveRunnerResult(RunnerResult details)
|
||||
{
|
||||
Console.WriteLine($"Saving results for {details.RacehorseName}");
|
||||
var dbRunnerResult = new Db.RunnerResult()
|
||||
{
|
||||
RaceId = details.RaceId,
|
||||
YearOfRace = details.YearOfRace,
|
||||
DivisionSequence = details.DivisionSequence,
|
||||
HorseId = details.HorseId,
|
||||
AnimalId = details.AnimalId,
|
||||
ResultFinishPos = details.ResultFinishPos,
|
||||
Status = details.Status,
|
||||
Ran = details.Ran,
|
||||
NonRunnerDeclaredReason = details.NonRunnerDeclaredReason,
|
||||
NonRunnerDeclaredDate = details.NonRunnerDeclaredDate,
|
||||
NonRunnerDeclaredTime = details.NonRunnerDeclaredTime,
|
||||
RacehorseName = details.RacehorseName,
|
||||
AgeYear = details.AgeYear,
|
||||
Bred = details.Bred,
|
||||
ClothNumber = details.ClothNumber,
|
||||
DrawnStall = details.DrawnStall,
|
||||
WeightValue = details.WeightValue,
|
||||
SexType = details.SexType,
|
||||
JockeyId = details.JockeyId,
|
||||
JockeyName = details.JockeyName,
|
||||
JockeyProfile = details.JockeyProfile,
|
||||
TrainerId = details.TrainerId,
|
||||
TrainerName = details.TrainerName,
|
||||
OwnerId = details.OwnerId,
|
||||
OwnerName = details.OwnerName,
|
||||
WbSilkCode = details.WbSilkCode,
|
||||
WbSilkDescription = details.WbSilkDescription,
|
||||
SilkImage = details.SilkImage,
|
||||
Plus10 = details.Plus10,
|
||||
ResultBtnDistance = details.ResultBtnDistance,
|
||||
PositionFinishTime = details.PositionFinishTime,
|
||||
BettingRatio = details.BettingRatio,
|
||||
PerformanceFigure = details.PerformanceFigure,
|
||||
RatingFlat = details.RatingFlat,
|
||||
RatingAwt = details.RatingAwt,
|
||||
RatingChase = details.RatingChase,
|
||||
RatingHurdle = details.RatingHurdle,
|
||||
RaceCriteriaRaceType = details.RaceCriteriaRaceType,
|
||||
Hro = details.Hro,
|
||||
FinishTime = details.FinishTime,
|
||||
ResultFinishDNF = details.ResultFinishDNF,
|
||||
FinishTimeInMilliseconds = String.IsNullOrWhiteSpace(details.ResultFinishDNF) ? details.FinishTimeInMilliseconds() : null,
|
||||
LossMilliseconds = details.LossMilliseconds(),
|
||||
};
|
||||
using(var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
db.RunnerResults.Add(dbRunnerResult);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
Console.WriteLine($"Saved results for {details.RacehorseName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace AutoBet.DataRecorded.RaceResultsDataCollector
|
||||
{
|
||||
public class PostRaceDataCollectorDetails
|
||||
{
|
||||
public DateTime DateToCollect { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using SuccessfulCode.BetfairApi;
|
||||
using SuccessfulCode.BetfairApi.BettingModels;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class OddsDataCollectorController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task GenerateSnapshot(OddsSnapshotDetails details)
|
||||
{
|
||||
var auth = new Authentication("TheRocker1987", "reSharper1036!", "H5TT4zKqOlRCpNOr");
|
||||
var client = new BettingApiClient(auth);
|
||||
var horseRacingQueries = new BetfairHorseRacingQueries(client);
|
||||
var horseWins = await horseRacingQueries.GetHorseWinCatalogue(DateTime.UtcNow.AddHours(-2), DateTime.UtcNow);
|
||||
var marketDetails = horseWins.ToDictionary(e => e.MarketId, e => e);
|
||||
var horseDetails = horseWins.SelectMany(e => e.Runners.Select(e1 => new { Key = (e.MarketId, e1.SelectionId), Value = e1 })).ToDictionary(e => e.Key, e => e.Value);
|
||||
var prices = await horseRacingQueries.GetBestPrices(horseWins.Select(e => e.MarketId).ToArray());
|
||||
var snapShots = prices.SelectMany(e => e.Runners.Select(e1 => GenerateOddsSnapshots(marketDetails, horseDetails, e1, e)));
|
||||
|
||||
foreach (var snapshot in snapShots)
|
||||
{
|
||||
await SendResponse(snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
private static Db.OddsSnapshot GenerateOddsSnapshots(Dictionary<string, MarketCatalogue> marketDetails, Dictionary<(string MarketId, long SelectionId), RunnerCatalog> horseDetails, Runner runner, MarketBook book)
|
||||
{
|
||||
var marketDetail = marketDetails[book.MarketId];
|
||||
var horseDetail = horseDetails[(marketDetail.MarketId, runner.SelectionId)];
|
||||
var runnerName = Regex.Match(horseDetail.RunnerName, "^[0-9]*\\.? ?(.*)", RegexOptions.Compiled).Groups[1].Value;
|
||||
var oddsSnapshot = new Db.OddsSnapshot()
|
||||
{
|
||||
EventName = marketDetail.Event.Name,
|
||||
HorseName = runnerName,
|
||||
JockeyName = horseDetail.Metadata.JockeyName,
|
||||
Odds = GenerateOdds(runner),
|
||||
SnapshotDate = DateTime.UtcNow
|
||||
};
|
||||
|
||||
return oddsSnapshot;
|
||||
}
|
||||
|
||||
private static List<Db.BetOdds> GenerateOdds(Runner e1)
|
||||
{
|
||||
var backOdds = e1.ExchangePrices.AvailableToBack.Select(e => new Db.BetOdds()
|
||||
{
|
||||
OddsType = Db.OddsType.Back,
|
||||
Available = (decimal)e.Size,
|
||||
Odds = e.Price
|
||||
}).ToList();
|
||||
|
||||
var layOdds = e1.ExchangePrices.AvailableToBack.Select(e => new Db.BetOdds()
|
||||
{
|
||||
OddsType = Db.OddsType.Lay,
|
||||
Available = (decimal)e.Size,
|
||||
Odds = e.Price
|
||||
}).ToList();
|
||||
|
||||
backOdds.AddRange(layOdds);
|
||||
return backOdds;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using SwiftyMessageHub.Core;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
[MessageType("OddsSnapshotDetails")]
|
||||
public class OddsSnapshotDetails
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using AutoBet.Db;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class OddsDataRecorderController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task SaveSnapshot(OddsSnapshot snapshotToSave)
|
||||
{
|
||||
using (var db = new HorseRacingDataContext())
|
||||
{
|
||||
db.OddsSnapshots.Add(snapshotToSave);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
|
||||
namespace AutoBet.DataRecorded
|
||||
{
|
||||
[MessageType("PreRaceDataSnapshotDetails")]
|
||||
public class PreRaceDataCollectDetails
|
||||
{
|
||||
public DateTime DateToCollect { get; set; }
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.MessageControllers
|
||||
{
|
||||
public class PreRaceDataCollectorController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task CollectPreRaceData(PreRaceDataCollectDetails details)
|
||||
{
|
||||
var client = new BritishHorseRacingApi.ApiClient();
|
||||
var date = details.DateToCollect;
|
||||
Console.WriteLine("Loading races");
|
||||
var races = await client.GetAllRacesForDay(date.Year, date.Month, date.Day);
|
||||
foreach (var race in races)
|
||||
{
|
||||
Console.WriteLine($"Race id {race.RaceId} loaded");
|
||||
await CurrentContext.Hub.SendMessage(race);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
using BritishHorseRacingApi.Models;
|
||||
using AutoBet.DataRecorded.PreRaceRunnerCollector;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
namespace AutoBet.DataRecorded.PreRaceDataRecorder
|
||||
{
|
||||
public class PreRaceDataRecorderController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task CollectPreRaceData(Race details)
|
||||
{
|
||||
Console.WriteLine($"Saving race id {details.RaceId}");
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
db.Races.Add(new Db.Race()
|
||||
{
|
||||
DistanceChangeText = details.DistanceChangeText,
|
||||
BlackTypeRace = details.BlackTypeRace,
|
||||
AbandonedReasonCode = details.AbandonedReasonCode,
|
||||
RaceCriteriaRaceType = details.RaceCriteriaRaceType,
|
||||
DistanceChange = details.DistanceChange,
|
||||
DistanceText = details.DistanceText,
|
||||
DistanceValue = details.DistanceValue,
|
||||
DistanceUnits = details.DistanceUnits,
|
||||
RawDistanceText = details.RawDistanceText,
|
||||
RatingBand = details.RatingBand,
|
||||
RaceClass = details.RaceClass,
|
||||
PrizeCurrency = details.PrizeCurrency,
|
||||
PrizeAmount = details.PrizeAmount,
|
||||
AgeLimit = details.AgeLimit,
|
||||
RaceName = details.RaceName,
|
||||
RaceTime = details.RaceTime,
|
||||
RaceDate = details.RaceDate,
|
||||
DivisionSequence = details.DivisionSequence,
|
||||
YearOfRace = details.YearOfRace,
|
||||
RaceId = details.RaceId,
|
||||
Plus10 = details.Plus10,
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
await CurrentContext.Hub.SendMessage(new PreRaceRunnerCollectDetails()
|
||||
{
|
||||
DateToCollect = details.RaceDate,
|
||||
RaceId = details.RaceId
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace AutoBet.DataRecorded.PreRaceRunnerCollector
|
||||
{
|
||||
public class PreRaceRunnerCollectDetails
|
||||
{
|
||||
public PreRaceRunnerCollectDetails()
|
||||
{
|
||||
}
|
||||
|
||||
public DateTime DateToCollect { get; set; }
|
||||
public int RaceId { get; set; }
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using BritishHorseRacingApi.Models;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.PreRaceRunnerCollector
|
||||
{
|
||||
public class PreRaceRunnerCollectorController : MessageController
|
||||
{
|
||||
public static SemaphoreSlim semaphore = new SemaphoreSlim(1);
|
||||
[MessageRoute]
|
||||
public async Task CollectPreRaceData(PreRaceRunnerCollectDetails details)
|
||||
{
|
||||
var client = new BritishHorseRacingApi.ApiClient();
|
||||
var date = details.DateToCollect;
|
||||
Console.WriteLine($"Preparing to load runners for race id {details.RaceId}");
|
||||
await semaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Loading runners for race id {details.RaceId}");
|
||||
var runners = await client.GetRaceRunners(date.Year, details.RaceId);
|
||||
foreach (var runner in runners.Data)
|
||||
{
|
||||
Console.WriteLine($"Loaded runner {runner.RacehorseName} id {details.RaceId}");
|
||||
await CurrentContext.Hub.SendMessage(runner);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
using BritishHorseRacingApi.Models;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AutoBet.DataRecorded.PreRaceRunnerRecorder
|
||||
{
|
||||
public class PreRaceRunnerRecorderController : MessageController
|
||||
{
|
||||
[MessageRoute]
|
||||
public async Task RecordRunner(Runner details)
|
||||
{
|
||||
Console.WriteLine($"Saving runner {details.RacehorseName}");
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
db.Runners.Add(new Db.Runner()
|
||||
{
|
||||
HeadGearWearingCode = details.HeadGearWearingCode,
|
||||
HeadGearWearingSheepSkin = details.HeadGearWearingSheepSkin,
|
||||
HeadGearDescription = details.HeadGearDescription,
|
||||
HeadGearAbbreviation = details.HeadGearAbbreviation,
|
||||
JockeyProfile = details.JockeyProfile,
|
||||
CourseWinner = details.CourseWinner,
|
||||
DistanceWinner = details.DistanceWinner,
|
||||
WindSurgeryFirstRun = details.WindSurgeryFirstRun,
|
||||
TrainerId = details.TrainerId,
|
||||
TrainerName = details.TrainerName,
|
||||
OwnerId = details.OwnerId,
|
||||
OwnerName = details.OwnerName,
|
||||
WbSilkCode = details.WbSilkCode,
|
||||
WbSilkDescription = details.WbSilkDescription,
|
||||
SilkImage = details.SilkImage,
|
||||
Plus10 = details.Plus10,
|
||||
ForecastPriceNumerator = details.ForecastPriceNumerator,
|
||||
ForecastPriceDenominator = details.ForecastPriceDenominator,
|
||||
WeightText = details.WeightText,
|
||||
WeightsJockeyClaiming = details.WeightsJockeyClaiming,
|
||||
Odds = details.Odds,
|
||||
DecimalOdds = details.DecimalOdds(),
|
||||
JockeyName = details.JockeyName,
|
||||
Status = (Db.Status)details.Status,
|
||||
RaceId = details.RaceId,
|
||||
YearOfRace = details.YearOfRace,
|
||||
DivisionSequence = details.DivisionSequence,
|
||||
AnimalId = details.AnimalId,
|
||||
RacehorseName = details.RacehorseName,
|
||||
AgeYears = details.AgeYears,
|
||||
Bred = details.Bred,
|
||||
ClothNumber = details.ClothNumber,
|
||||
DrawnStall = details.DrawnStall,
|
||||
ReserveNumber = details.ReserveNumber,
|
||||
BhaRating = details.BhaRating,
|
||||
FormFigures = details.FormFigures,
|
||||
WeightValue = details.WeightValue,
|
||||
PenaltyValue = details.PenaltyValue,
|
||||
SexType = (Db.SexType)details.SexType,
|
||||
NonRunnerDeclaredReason = details.NonRunnerDeclaredReason,
|
||||
NonRunnerDeclaredDate = details.NonRunnerDeclaredDate,
|
||||
NonRunnerDeclaredTime = details.NonRunnerDeclaredTime,
|
||||
RunnerNumber = details.RunnerNumber,
|
||||
JockeyId = details.JockeyId,
|
||||
RaceHorseNameWithoutCountry = details.RacehorseNameWithoutCountry,
|
||||
WeightInGrams = details.WeightInGrams,
|
||||
LastRuns = details.LastRuns?.Select(e => new Db.LastRun()
|
||||
{
|
||||
Days = e.Days,
|
||||
RaceType = e.RaceType
|
||||
}).ToList()
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
using AutoBet.DataRecorded.MessageControllers;
|
||||
using SwiftyMessageHub.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AutoBet.DataRecorded.RaceResultsDataCollector;
|
||||
using BritishHorseRacingApi;
|
||||
using System.Collections.Generic;
|
||||
using BritishHorseRacingApi.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using AutoBet.Db;
|
||||
using ApiModels = BritishHorseRacingApi.Models;
|
||||
|
||||
namespace AutoBet.DataRecorded
|
||||
{
|
||||
class Program
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
//StartResultsCollection().GetAwaiter().GetResult();
|
||||
//var dayToCollectRunners = GetDayToCollect();
|
||||
await CollectPastResults();
|
||||
|
||||
//await CollectCurrent();
|
||||
//await GetFixtureIds();
|
||||
|
||||
}
|
||||
|
||||
private static async Task GetFixtureIds()
|
||||
{
|
||||
Db.Fixture[] fixturesToProcces;
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
var ids = db.Races.Where(e => e.FixtureId != 0).Select(e => e.FixtureId).ToArray();
|
||||
fixturesToProcces = db.Fixtures.Where(e => !ids.Contains(e.FixtureId)).ToArray();
|
||||
var client = new ApiClient(TimeSpan.FromSeconds(0), "D_SID=188.172.158.138:JT/OEx87nl5ScspTQk38UsDfuIz94DbCf5CYsIC7WpU; __utmz=36595059.1583064856.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); D_ZID=52A68C14-B4B6-3844-8896-9B0E426FEABA; D_ZUID=2E7A90D0-30B7-31B4-BB43-CB2B0DACBDF8; D_HID=0316E576-4AF0-35A5-BEB9-CECB592B4EC2; bha-ie-test=true; __utmc=36595059; __utma=36595059.34208775.1583064856.1583966446.1584046318.17; bha_token=%7B%22token%22%3A%22MjE3Y2I1NDBhYWViZWQ0YmM4YjZmYjg2NDRlOTA2NzU%3D%22%2C%22timestamp%22%3A1584046320723%7D; D_IID=A18DB74E-9ABD-33E1-BF94-96209AF6178E; D_UID=9CDC96FD-4EFE-308E-BC28-2F105AC0B01B; __utmt=1; __utmb=36595059.6.10.1584046318");
|
||||
foreach (var fixture in fixturesToProcces)
|
||||
{
|
||||
var races = await client.GetRaces(fixture.FixtureYear, fixture.FixtureId);
|
||||
foreach (var race in races.Data)
|
||||
{
|
||||
var dbRace = db.Races.FirstOrDefault(e => e.RaceId == race.RaceId);
|
||||
if (dbRace == null)
|
||||
{
|
||||
AddRace(db, fixture.FixtureId, race);
|
||||
await LoadRunners(fixture.FixtureDate.Date, client, db, race);
|
||||
continue;
|
||||
}
|
||||
|
||||
dbRace.FixtureId = fixture.FixtureId;
|
||||
}
|
||||
db.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task CollectPastResults()
|
||||
{
|
||||
var dayToCollectRunners = new DateTime(2019, 11, 23);// GetDayToCollect();
|
||||
|
||||
var client = new ApiClient(TimeSpan.FromSeconds(0), "D_SID=188.172.158.138:JT/OEx87nl5ScspTQk38UsDfuIz94DbCf5CYsIC7WpU; __utmz=36595059.1583064856.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); D_IID=A18DB74E-9ABD-33E1-BF94-96209AF6178E; D_UID=9CDC96FD-4EFE-308E-BC28-2F105AC0B01B; __utmc=36595059; bha-ie-test=true; D_ZID=3F37C446-48FB-3F85-B8D2-66FC90A17473; D_ZUID=27B27203-7708-3F5E-8C01-86A8BF3A21DD; D_HID=BC00CAA4-06EE-39E0-8579-A00DCFA20171; bha_token=%7B%22token%22%3A%22ZjYxM2UwMWEwZmZjNjdhYmM5NzRmMDhmMGVmOTYxNGY%3D%22%2C%22timestamp%22%3A1586699412252%7D; __utma=36595059.34208775.1583064856.1586685187.1586702516.21; __utmt=1; __utmb=36595059.2.10.1586702516");
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dayToCollectResults = dayToCollectRunners;
|
||||
await LoadPreRaceData(dayToCollectRunners, client);
|
||||
await LoadResults(dayToCollectResults, client);
|
||||
dayToCollectRunners = dayToCollectRunners.AddDays(-1);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
Console.WriteLine("Enter new cookie:");
|
||||
var cookie = Console.ReadLine();
|
||||
if (!String.IsNullOrWhiteSpace(cookie))
|
||||
client = new ApiClient(TimeSpan.FromSeconds(0), cookie);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task CollectCurrent()
|
||||
{
|
||||
var dayToCollectRunners = DateTime.Now.Date;
|
||||
var dayToCollectResults = dayToCollectRunners.AddDays(-1);
|
||||
var client = new ApiClient(TimeSpan.FromSeconds(0), "D_SID=188.172.158.138:JT/OEx87nl5ScspTQk38UsDfuIz94DbCf5CYsIC7WpU; __utmz=36595059.1583064856.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); D_ZID=52A68C14-B4B6-3844-8896-9B0E426FEABA; D_ZUID=2E7A90D0-30B7-31B4-BB43-CB2B0DACBDF8; D_HID=0316E576-4AF0-35A5-BEB9-CECB592B4EC2; bha-ie-test=true; __utmc=36595059; D_IID=A18DB74E-9ABD-33E1-BF94-96209AF6178E; D_UID=9CDC96FD-4EFE-308E-BC28-2F105AC0B01B; __utma=36595059.34208775.1583064856.1584046318.1584135333.18; __utmt=1; __utmb=36595059.1.10.1584135333; bha_token=%7B%22token%22%3A%22NTc0OTdjNTRiMjg2ZGYyYzEyYThmMjRlZDZmYmIyMzM%3D%22%2C%22timestamp%22%3A1584135334879%7D");
|
||||
await LoadPreRaceData(dayToCollectRunners, client);
|
||||
await LoadResults(dayToCollectResults, client);
|
||||
}
|
||||
|
||||
private static async Task LoadPreRaceData(DateTime date, ApiClient client)
|
||||
{
|
||||
Console.WriteLine($"Loading fixtures for {date}");
|
||||
var fixtures = await client.GetAllFixturesForDay(date.Year, date.Month, date.Day);
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
foreach (var fixture in fixtures)
|
||||
{
|
||||
Console.WriteLine($"Processing fixture {fixture.FixtureName}");
|
||||
var dbFixture = ApiFixtureToDbFixture(fixture);
|
||||
db.Fixtures.Add(dbFixture);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
await LoadRaces(date, client, db, fixture.FixtureYear, fixture.FixtureId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task LoadRaces(DateTime date, ApiClient client, HorseRacingDataContext db, int year, int fixtureId)
|
||||
{
|
||||
Console.WriteLine($"Loading races for {date}");
|
||||
var races = await client.GetRaces(year, fixtureId);
|
||||
|
||||
foreach (var race in races.Data)
|
||||
{
|
||||
AddRace(db, fixtureId, race);
|
||||
await db.SaveChangesAsync();
|
||||
await LoadRunners(date, client, db, race);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task LoadRunners(DateTime date, ApiClient client, HorseRacingDataContext db, ApiModels.Race race)
|
||||
{
|
||||
Console.WriteLine($"Loading runners for race id {race.RaceId}");
|
||||
var runners = await client.GetRaceRunners(date.Year, race.RaceId, race.DivisionSequence);
|
||||
foreach (var runner in runners.Data)
|
||||
{
|
||||
Console.WriteLine($"Loaded runner {runner.RacehorseName} for race {race.RaceId})");
|
||||
db.Runners.Add(new Db.Runner()
|
||||
{
|
||||
HeadGearWearingCode = runner.HeadGearWearingCode,
|
||||
HeadGearWearingSheepSkin = runner.HeadGearWearingSheepSkin,
|
||||
HeadGearDescription = runner.HeadGearDescription,
|
||||
HeadGearAbbreviation = runner.HeadGearAbbreviation,
|
||||
JockeyProfile = runner.JockeyProfile,
|
||||
CourseWinner = runner.CourseWinner,
|
||||
DistanceWinner = runner.DistanceWinner,
|
||||
WindSurgeryFirstRun = runner.WindSurgeryFirstRun,
|
||||
TrainerId = runner.TrainerId,
|
||||
TrainerName = runner.TrainerName,
|
||||
OwnerId = runner.OwnerId,
|
||||
OwnerName = runner.OwnerName,
|
||||
WbSilkCode = runner.WbSilkCode,
|
||||
WbSilkDescription = runner.WbSilkDescription,
|
||||
SilkImage = runner.SilkImage,
|
||||
Plus10 = runner.Plus10,
|
||||
ForecastPriceNumerator = runner.ForecastPriceNumerator,
|
||||
ForecastPriceDenominator = runner.ForecastPriceDenominator,
|
||||
WeightText = runner.WeightText,
|
||||
WeightsJockeyClaiming = runner.WeightsJockeyClaiming,
|
||||
Odds = runner.Odds,
|
||||
DecimalOdds = runner.DecimalOdds(),
|
||||
JockeyName = runner.JockeyName,
|
||||
Status = (Db.Status)runner.Status,
|
||||
RaceId = runner.RaceId,
|
||||
YearOfRace = runner.YearOfRace,
|
||||
DivisionSequence = runner.DivisionSequence,
|
||||
AnimalId = runner.AnimalId,
|
||||
RacehorseName = runner.RacehorseName,
|
||||
AgeYears = runner.AgeYears,
|
||||
Bred = runner.Bred,
|
||||
ClothNumber = runner.ClothNumber,
|
||||
DrawnStall = runner.DrawnStall,
|
||||
ReserveNumber = runner.ReserveNumber,
|
||||
BhaRating = runner.BhaRating,
|
||||
FormFigures = runner.FormFigures,
|
||||
WeightValue = runner.WeightValue,
|
||||
PenaltyValue = runner.PenaltyValue,
|
||||
SexType = (Db.SexType)runner.SexType,
|
||||
NonRunnerDeclaredReason = runner.NonRunnerDeclaredReason,
|
||||
NonRunnerDeclaredDate = runner.NonRunnerDeclaredDate,
|
||||
NonRunnerDeclaredTime = runner.NonRunnerDeclaredTime,
|
||||
RunnerNumber = runner.RunnerNumber,
|
||||
JockeyId = runner.JockeyId,
|
||||
RaceHorseNameWithoutCountry = runner.RacehorseNameWithoutCountry,
|
||||
WeightInGrams = runner.WeightInGrams,
|
||||
LastRuns = runner.LastRuns?.Select(e => new Db.LastRun()
|
||||
{
|
||||
Days = e.Days,
|
||||
RaceType = e.RaceType
|
||||
}).ToList()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddRace(HorseRacingDataContext db, int fixtureId, ApiModels.Race race)
|
||||
{
|
||||
Console.WriteLine($"Saving {race.RaceName}");
|
||||
var dbRace = ApiRaceToDbRace(race, fixtureId);
|
||||
db.Races.Add(dbRace);
|
||||
|
||||
}
|
||||
|
||||
private static Db.Fixture ApiFixtureToDbFixture(ApiModels.Fixture fixture)
|
||||
{
|
||||
return new Db.Fixture()
|
||||
{
|
||||
GoingUpdatedTime = fixture.GoingUpdatedTime,
|
||||
GoingUpdatedDate = fixture.GoingUpdatedDate,
|
||||
FixtureSession = (Db.FixtureSession)fixture.FixtureSession,
|
||||
AbandonedReasonCode = fixture.AbandonedReasonCode,
|
||||
Rail = fixture.Rail,
|
||||
Stalls = fixture.Stalls,
|
||||
Other = fixture.Other,
|
||||
Weather = fixture.Weather,
|
||||
Going = fixture.Going,
|
||||
MajorEvent = fixture.MajorEvent,
|
||||
TicketsLink = fixture.TicketsLink,
|
||||
CourseId = fixture.CourseId,
|
||||
RacePlanningCode = (Db.RacePlanningCode)fixture.RacePlanningCode,
|
||||
RacingTrackType = (Db.RacingTrackType)fixture.RacingTrackType,
|
||||
MeetingId = fixture.MeetingId,
|
||||
FixtureType = (Db.FixtureType)fixture.FixtureType,
|
||||
FixtureName = fixture.FixtureName,
|
||||
NumberOfRaces = fixture.NumberOfRaces,
|
||||
BcsEvent = fixture.BcsEvent,
|
||||
BlackTypeRaces = fixture.BlackTypeRaces,
|
||||
EntriesAvailable = fixture.EntriesAvailable,
|
||||
RacecardAvailable = fixture.RacecardAvailable,
|
||||
ResultsAvailable = fixture.ResultsAvailable,
|
||||
FirstRace = fixture.FirstRace,
|
||||
CourseName = fixture.CourseName,
|
||||
Distance = fixture.Distance,
|
||||
FixtureDate = fixture.FixtureDate,
|
||||
FixtureYear = fixture.FixtureYear,
|
||||
FixtureId = fixture.FixtureId
|
||||
};
|
||||
}
|
||||
|
||||
private static Db.Race ApiRaceToDbRace(ApiModels.Race race, int fixtureId)
|
||||
{
|
||||
return new Db.Race()
|
||||
{
|
||||
DistanceChangeText = race.DistanceChangeText,
|
||||
BlackTypeRace = race.BlackTypeRace,
|
||||
AbandonedReasonCode = race.AbandonedReasonCode,
|
||||
RaceCriteriaRaceType = race.RaceCriteriaRaceType,
|
||||
DistanceChange = race.DistanceChange,
|
||||
DistanceText = race.DistanceText,
|
||||
DistanceValue = race.DistanceValue,
|
||||
DistanceUnits = race.DistanceUnits,
|
||||
RawDistanceText = race.RawDistanceText,
|
||||
RatingBand = race.RatingBand,
|
||||
RaceClass = race.RaceClass,
|
||||
PrizeCurrency = race.PrizeCurrency,
|
||||
PrizeAmount = race.PrizeAmount,
|
||||
AgeLimit = race.AgeLimit,
|
||||
RaceName = race.RaceName,
|
||||
RaceTime = race.RaceTime,
|
||||
RaceDate = race.RaceDate,
|
||||
DivisionSequence = race.DivisionSequence,
|
||||
YearOfRace = race.YearOfRace,
|
||||
RaceId = race.RaceId,
|
||||
Plus10 = race.Plus10,
|
||||
FixtureId = fixtureId
|
||||
};
|
||||
}
|
||||
|
||||
private static async Task LoadResults(DateTime date, ApiClient client)
|
||||
{
|
||||
using (var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
var races = await db.Races.Where(e => e.RaceDate == date.Date).ToListAsync();
|
||||
foreach(var race in races)
|
||||
{
|
||||
if (race.RaceId != 1684)
|
||||
continue;
|
||||
var results = await client.GetRaceResults(race.YearOfRace, race.RaceId, race.DivisionSequence);
|
||||
foreach (var runnerResult in results.Data)
|
||||
{
|
||||
var dbRunnerResult = new Db.RunnerResult()
|
||||
{
|
||||
RaceId = runnerResult.RaceId,
|
||||
YearOfRace = runnerResult.YearOfRace,
|
||||
DivisionSequence = runnerResult.DivisionSequence,
|
||||
HorseId = runnerResult.HorseId,
|
||||
AnimalId = runnerResult.AnimalId,
|
||||
ResultFinishPos = runnerResult.ResultFinishPos,
|
||||
Status = runnerResult.Status,
|
||||
Ran = runnerResult.Ran,
|
||||
NonRunnerDeclaredReason = runnerResult.NonRunnerDeclaredReason,
|
||||
NonRunnerDeclaredDate = runnerResult.NonRunnerDeclaredDate,
|
||||
NonRunnerDeclaredTime = runnerResult.NonRunnerDeclaredTime,
|
||||
RacehorseName = runnerResult.RacehorseName,
|
||||
RacehorseNameWithoutConuntry = runnerResult.RacehorseNameWithoutCountry,
|
||||
AgeYear = runnerResult.AgeYear,
|
||||
Bred = runnerResult.Bred,
|
||||
ClothNumber = runnerResult.ClothNumber,
|
||||
DrawnStall = runnerResult.DrawnStall,
|
||||
WeightValue = runnerResult.WeightValue,
|
||||
SexType = runnerResult.SexType,
|
||||
JockeyId = runnerResult.JockeyId,
|
||||
JockeyName = runnerResult.JockeyName,
|
||||
JockeyProfile = runnerResult.JockeyProfile,
|
||||
TrainerId = runnerResult.TrainerId,
|
||||
TrainerName = runnerResult.TrainerName,
|
||||
OwnerId = runnerResult.OwnerId,
|
||||
OwnerName = runnerResult.OwnerName,
|
||||
WbSilkCode = runnerResult.WbSilkCode,
|
||||
WbSilkDescription = runnerResult.WbSilkDescription,
|
||||
SilkImage = runnerResult.SilkImage,
|
||||
Plus10 = runnerResult.Plus10,
|
||||
ResultBtnDistance = runnerResult.ResultBtnDistance,
|
||||
PositionFinishTime = runnerResult.PositionFinishTime,
|
||||
BettingRatio = runnerResult.BettingRatio,
|
||||
PerformanceFigure = runnerResult.PerformanceFigure,
|
||||
RatingFlat = runnerResult.RatingFlat,
|
||||
RatingAwt = runnerResult.RatingAwt,
|
||||
RatingChase = runnerResult.RatingChase,
|
||||
RatingHurdle = runnerResult.RatingHurdle,
|
||||
RaceCriteriaRaceType = runnerResult.RaceCriteriaRaceType,
|
||||
Hro = runnerResult.Hro,
|
||||
FinishTime = runnerResult.FinishTime,
|
||||
ResultFinishDNF = runnerResult.ResultFinishDNF,
|
||||
FinishTimeInMilliseconds = String.IsNullOrWhiteSpace(runnerResult.ResultFinishDNF) ? runnerResult.FinishTimeInMilliseconds() : null,
|
||||
LossMilliseconds = runnerResult.LossMilliseconds(),
|
||||
};
|
||||
db.RunnerResults.Add(dbRunnerResult);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime _dateToCollectRunners = GetDayToCollect();
|
||||
public static DateTime GetDayToCollect()
|
||||
{
|
||||
using(var db = new Db.HorseRacingDataContext())
|
||||
{
|
||||
var date = db.Races.OrderBy(e => e.RaceDate)
|
||||
.Select(e => e.RaceDate)
|
||||
.First()
|
||||
.Date;
|
||||
|
||||
return date.AddDays(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user