Compare commits
17 Commits
df616fd42c
...
79575df472
| Author | SHA1 | Date | |
|---|---|---|---|
| 79575df472 | |||
| 517658bf74 | |||
| c257d7ff8c | |||
| 34918e6c38 | |||
| d3e651ef89 | |||
| 62ff7a04de | |||
| 465b8e05e7 | |||
| d6fc1bf314 | |||
| 0c8706788a | |||
| b61980a30d | |||
| 388b1ec23f | |||
| ea987c52a4 | |||
| 7f658be963 | |||
| e265958434 | |||
| 0ab60324fd | |||
| c68c2cf8db | |||
| 4017e1eeb1 |
@@ -0,0 +1,7 @@
|
||||
namespace lottery_co_uk_scraper.core.Exceptions
|
||||
{
|
||||
public class NullResultException(string message) : Exception(message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace lottery_co_uk_scraper.core.Models.EuroMillions
|
||||
{
|
||||
[Index(nameof(DrawNumber), nameof(RaffleCode), IsUnique = true)]
|
||||
public class EurosRaffleResult
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int DrawNumber { get; set; }
|
||||
|
||||
public string RaffleCode { get; set; }
|
||||
}
|
||||
}
|
||||
147
lottery-co-uk-scraper.core/Models/EurosResult.cs
Normal file
147
lottery-co-uk-scraper.core/Models/EurosResult.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using lottery_co_uk_scraper.core.Models.EuroMillions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace lottery_co_uk_scraper.core.Models
|
||||
{
|
||||
[Index(nameof(DrawNumber), IsUnique = true)]
|
||||
public class EurosResult
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public DateOnly DrawDate { get; set; }
|
||||
|
||||
public int DrawNumber { get; set; }
|
||||
|
||||
public bool Rollover { get; set; }
|
||||
|
||||
public EurosRaffleResult MillionaireMakerCode { get; set; }
|
||||
|
||||
public int BallSetUsed { get; set; }
|
||||
|
||||
public int MachineUsed { get; set; }
|
||||
|
||||
public int DrawnBall1 { get; set; }
|
||||
|
||||
public int DrawnBall2 { get; set; }
|
||||
|
||||
public int DrawnBall3 { get; set; }
|
||||
|
||||
public int DrawnBall4 { get; set; }
|
||||
|
||||
public int DrawnBall5 { get; set; }
|
||||
|
||||
public int LuckyStar1 { get; set; }
|
||||
|
||||
public int LuckyStar2 { get; set; }
|
||||
|
||||
public int TotalMatched2 { get; set; }
|
||||
|
||||
public int TotalMatched2UK { get; set; }
|
||||
|
||||
public int Matched2PrizeUK { get; set; }
|
||||
|
||||
public int Matched2PrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched2Plus1Star { get; set; }
|
||||
|
||||
public int TotalMatched2Plus1StarUK { get; set; }
|
||||
|
||||
public int Matched2Plus1StarPrizeUK { get; set; }
|
||||
|
||||
public int Matched2Plus1StarPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched1Plus2Stars { get; set; }
|
||||
|
||||
public int TotalMatched1Plus2StarsUK { get; set; }
|
||||
|
||||
public int Matched1Plus2StarsPrizeUK { get; set; }
|
||||
|
||||
public int Matched1Plus2StarsPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched2Plus2Stars { get; set; }
|
||||
|
||||
public int TotalMatched2Plus2StarsUK { get; set; }
|
||||
|
||||
public int Matched2Plus2StarsPrizeUK { get; set; }
|
||||
|
||||
public int Matched2Plus2StarsPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched3 { get; set; }
|
||||
|
||||
public int TotalMatched3UK { get; set; }
|
||||
|
||||
public int Matched3PrizeUK { get; set; }
|
||||
|
||||
public int Matched3PrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched3Plus1Star { get; set; }
|
||||
|
||||
public int TotalMatched3Plus1StarUK { get; set; }
|
||||
|
||||
public int Matched3Plus1StarPrizeUK { get; set; }
|
||||
|
||||
public int Matched3Plus1StarPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched3Plus2Stars { get; set; }
|
||||
|
||||
public int TotalMatched3Plus2StarsUK { get; set; }
|
||||
|
||||
public int Matched3Plus2StarsPrizeUK { get; set; }
|
||||
|
||||
public int Matched3Plus2StarsPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched4 { get; set; }
|
||||
|
||||
public int TotalMatched4UK { get; set; }
|
||||
|
||||
public int Matched4PrizeUK { get; set; }
|
||||
|
||||
public int Matched4PrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched4Plus1Star { get; set; }
|
||||
|
||||
public int TotalMatched4Plus1StarUK { get; set; }
|
||||
|
||||
public int Matched4Plus1StarPrizeUK { get; set; }
|
||||
|
||||
public int Matched4Plus1StarPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched4Plus2Stars { get; set; }
|
||||
|
||||
public int TotalMatched4Plus2StarsUK { get; set; }
|
||||
|
||||
public int Matched4Plus2StarsPrizeUK { get; set; }
|
||||
|
||||
public int Matched4Plus2StarsPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched5 { get; set; }
|
||||
|
||||
public int TotalMatched5UK { get; set; }
|
||||
|
||||
public int Matched5PrizeUK { get; set; }
|
||||
|
||||
public int Matched5PrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched5Plus1Star { get; set; }
|
||||
|
||||
public int TotalMatched5Plus1StarUK { get; set; }
|
||||
|
||||
public int Matched5Plus1StarPrizeUK { get; set; }
|
||||
|
||||
public int Matched5Plus1StarPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalMatched5Plus2Stars { get; set; }
|
||||
|
||||
public int TotalMatched5Plus2StarsUK { get; set; }
|
||||
|
||||
public int Matched5Plus2StarsPrizeUK { get; set; }
|
||||
|
||||
public int Matched5Plus2StarsPrizeFundUK { get; set; }
|
||||
|
||||
public int TotalWinners { get; set; }
|
||||
|
||||
public int TotalWinnersUK { get; set; }
|
||||
|
||||
public int TotalPrizeFundUK { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using lottery_co_uk_scraper.core.Models.EuroMillions;
|
||||
|
||||
namespace lottery_co_uk_scraper.data
|
||||
{
|
||||
@@ -13,5 +13,23 @@ namespace lottery_co_uk_scraper.data
|
||||
dbContext.LottoResults.Add(lottoResults);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public static void SaveModelToDatabase(EurosResult eurosResults)
|
||||
{
|
||||
using var dbContext = new LotteryContext();
|
||||
|
||||
dbContext.Database.EnsureCreated();
|
||||
dbContext.EurosResults.Add(eurosResults);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public static void SaveModelToDatabase(EurosRaffleResult eurosRaffleResults)
|
||||
{
|
||||
using var dbContext = new LotteryContext();
|
||||
|
||||
dbContext.Database.EnsureCreated();
|
||||
dbContext.EurosRaffleResults.Add(eurosRaffleResults);
|
||||
dbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.core.Models.EuroMillions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace lottery_co_uk_scraper.data
|
||||
{
|
||||
public class LotteryContext : DbContext
|
||||
{
|
||||
public DbSet<EurosResult> EurosResults { get; set; }
|
||||
|
||||
public DbSet<EurosRaffleResult> EurosRaffleResults { get; set; }
|
||||
|
||||
public DbSet<LottoResult> LottoResults { get; set; }
|
||||
|
||||
public LotteryContext()
|
||||
|
||||
242
lottery-co-uk-scraper/EuroMillions/DrawBalls.cs
Normal file
242
lottery-co-uk-scraper/EuroMillions/DrawBalls.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static lottery_co_uk_scraper.NationalLottery.Lotto;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawBalls
|
||||
{
|
||||
private static readonly ILogger<DrawBalls> _logger;
|
||||
|
||||
private static HtmlNode GetNodeById(HtmlNode containerNode, string nodeId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return containerNode.DescendantsAndSelf()
|
||||
.FirstOrDefault(x => x.Attributes["id"] != null && x.Attributes["id"].Value == nodeId)
|
||||
?? throw new InvalidOperationException($"Node with ID '{nodeId}' not found.");
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new InvalidOperationException($"Node with ID '{nodeId}' not found.");
|
||||
}
|
||||
}
|
||||
|
||||
public static int ProcessBallSetUsed(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ballSetUsedString = doc.DocumentNode.Descendants("td")
|
||||
.Where(x => x.InnerHtml.Contains("<strong>Ball Set Used:</strong>"))
|
||||
.Select(x => x.InnerText.Split(':')[1].Trim())
|
||||
.FirstOrDefault();
|
||||
|
||||
if (int.TryParse(ballSetUsedString, out int ballSetUsed))
|
||||
{
|
||||
AssignBallSetToModelProperty(LotteryTableRow.BallSetUsed, ballSetUsed, eurosResult);
|
||||
|
||||
return ballSetUsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("Failed to parse Euro Millions Ball Set Used.");
|
||||
|
||||
throw new Exception("Failed to parse Euro Millions Ball Set Used.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("Failed to parse Euro Millions Ball Set Used.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignBallSetToModelProperty(string containerNode, int ballSetUsed, EurosResult eurosResult)
|
||||
{
|
||||
if (containerNode == LotteryTableRow.BallSetUsed)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.BallSetUsed), eurosResult, ballSetUsed);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessMainBalls(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
|
||||
|
||||
List<int>? euroBalls = ballsDrawn != null
|
||||
? ExtractBalls(ballsDrawn, "euromillions-ball")
|
||||
: null;
|
||||
|
||||
if (euroBalls != null)
|
||||
{
|
||||
AssignDrawBallsToModelProperty(LotteryTableRow.BallsDrawn, euroBalls, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("EuroMillions Draw Balls were null!");
|
||||
|
||||
throw new Exception("EuroMillions Draw Balls were null!");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("There was a problem processing the EuroMillions Draw Balls. {Message}", ex.Message);
|
||||
|
||||
throw new Exception($"There was a problem processing the EuroMillions Draw Balls. {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<int> ExtractBalls(HtmlNode ballsNode, string className)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ballsNode.Descendants("span")
|
||||
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains(className))
|
||||
.Select(x =>
|
||||
{
|
||||
if (int.TryParse(x.InnerText, out int ball))
|
||||
{
|
||||
return ball;
|
||||
}
|
||||
|
||||
_logger.LogError("Failed to parse {className} value: {x.InnerText}", className, x.InnerText);
|
||||
|
||||
throw new Exception($"Failed to parse {className} value: {x.InnerText}");
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception($"Failed to parse {className}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignDrawBallsToModelProperty(string containerNode, object ballInformation, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (containerNode == LotteryTableRow.BallsDrawn)
|
||||
{
|
||||
if (ballInformation is List<int> balls && balls.Count >= 5)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
string propertyName = $"DrawnBall{i + 1}";
|
||||
PropertyManager.SetProperty(propertyName, eurosResult, balls[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Invalid drawn balls information.");
|
||||
|
||||
throw new Exception("Invalid drawn balls information.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Unhandled containerNode: {containerNode}", containerNode);
|
||||
|
||||
throw new Exception($"Unhandled containerNode: {containerNode}");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ToDo:
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessLuckyStars(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
|
||||
|
||||
List<int>? luckyStars = ballsDrawn != null
|
||||
? ExtractLuckyStar(ballsDrawn, "euromillions-lucky-star")
|
||||
: null;
|
||||
|
||||
if (luckyStars != null)
|
||||
{
|
||||
AssignLuckyStarToModelProperty(LotteryTableRow.BallsDrawn, luckyStars, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Lucky Stars appear to be null.");
|
||||
|
||||
throw new Exception("Lucky Stars appear to be null.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("There was a problem processing the EuroMillions Lucky Stars. {Message}", ex.Message);
|
||||
|
||||
throw new Exception($"There was a problem processing the EuroMillions Lucky Stars. {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<int>ExtractLuckyStar(HtmlNode ballsNode, string ballClass)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ballsNode.Descendants("span")
|
||||
.Where(x => x.HasClass(ballClass))
|
||||
.Select(x =>
|
||||
{
|
||||
if (int.TryParse(x.InnerText, out int ball))
|
||||
{
|
||||
return ball;
|
||||
}
|
||||
|
||||
_logger.LogError("Failed to parse {className} value: {x.InnerText}", ballClass, x.InnerText);
|
||||
|
||||
throw new Exception($"Failed to parse {ballClass} value: {x.InnerText}");
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.LogError("There was a problem processing the EuroMillions Lucky Stars.");
|
||||
|
||||
throw new Exception($"There was a problem processing the EuroMillions Lucky Stars.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void AssignLuckyStarToModelProperty(string containerNode, object ballInformation, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (containerNode == LotteryTableRow.BallsDrawn)
|
||||
{
|
||||
if (ballInformation is List<int> balls && balls.Count >= 2)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
string propertyName = $"LuckyStar{i + 1}";
|
||||
PropertyManager.SetProperty(propertyName, eurosResult, balls[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Invalid Lucky Star balls information.");
|
||||
|
||||
throw new Exception("Invalid Lucky Star balls information.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Unhandled containerNode: {containerNode}", containerNode);
|
||||
|
||||
throw new Exception($"Unhandled containerNode: {containerNode}");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ToDo:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
lottery-co-uk-scraper/EuroMillions/DrawCode.cs
Normal file
42
lottery-co-uk-scraper/EuroMillions/DrawCode.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawCode
|
||||
{
|
||||
public static List<string> ProcessMillionaireMaker(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var raffleNumbers = new List<string>();
|
||||
|
||||
foreach (var span in doc.DocumentNode.Descendants("span"))
|
||||
{
|
||||
var classAttribute = span.GetAttributeValue("class", "");
|
||||
|
||||
if (classAttribute.Contains("millionaire") && classAttribute.Contains("raffle"))
|
||||
{
|
||||
raffleNumbers.Add(span.InnerText.Trim());
|
||||
}
|
||||
}
|
||||
|
||||
AssignMillionaireMakerToModelProperty(nameof(eurosResult.MillionaireMakerCode), raffleNumbers, eurosResult);
|
||||
|
||||
return raffleNumbers;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void AssignMillionaireMakerToModelProperty(string propertyName, List<string> raffleNumbers, EurosResult eurosResult)
|
||||
{
|
||||
PropertyManager.SetProperty(propertyName, eurosResult, raffleNumbers);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
lottery-co-uk-scraper/EuroMillions/DrawDate.cs
Normal file
57
lottery-co-uk-scraper/EuroMillions/DrawDate.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawDate
|
||||
{
|
||||
public static void ProcessDrawDateFromMeta(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var title = doc.DocumentNode.Descendants("title")
|
||||
.FirstOrDefault();
|
||||
|
||||
if (title != null)
|
||||
{
|
||||
var titleText = title.InnerText;
|
||||
var date = TextRemoval.ParseDateString(titleText);
|
||||
|
||||
string formattedDate = date.ToString("dd/MM/yyyy");
|
||||
|
||||
AssignDrawDateToModelProperty(nameof(eurosResult.DrawDate), formattedDate, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger - Title not found
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignDrawDateToModelProperty(string propertyName, string formattedDate, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DateOnly.TryParse(formattedDate, out DateOnly value))
|
||||
{
|
||||
PropertyManager.SetProperty(propertyName, eurosResult, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Failed to parse {propertyName}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
lottery-co-uk-scraper/EuroMillions/DrawMachine.cs
Normal file
41
lottery-co-uk-scraper/EuroMillions/DrawMachine.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawMachine
|
||||
{
|
||||
public static string ProcessMachineUsed(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var machineName = doc.DocumentNode.Descendants("td")
|
||||
.Where(x => x.InnerHtml.Contains("<strong>Ball Machine Used:</strong>"))
|
||||
.Select(x => x.InnerText.Split(':')[1].Trim())
|
||||
.FirstOrDefault();
|
||||
|
||||
if (machineName != null)
|
||||
{
|
||||
AssignDrawMachineToModelProperty(nameof(eurosResult.MachineUsed), machineName, eurosResult);
|
||||
|
||||
return machineName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignDrawMachineToModelProperty(string propertyName, string machineName, EurosResult eurosResult)
|
||||
{
|
||||
PropertyManager.SetProperty(propertyName, eurosResult, machineName);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
lottery-co-uk-scraper/EuroMillions/DrawNumber.cs
Normal file
56
lottery-co-uk-scraper/EuroMillions/DrawNumber.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawNumber
|
||||
{
|
||||
public static int ProcessDrawNumberFromMeta(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
var metaKeywords = doc.DocumentNode.Descendants("meta")
|
||||
.FirstOrDefault(x => x.GetAttributeValue("name", "") == "keywords");
|
||||
|
||||
if (metaKeywords != null)
|
||||
{
|
||||
var keywordsText = metaKeywords.GetAttributeValue("content", "");
|
||||
var drawNumberMatch = Regex.Match(keywordsText, @"euromillions draw (\d+)");
|
||||
|
||||
if (drawNumberMatch.Success)
|
||||
{
|
||||
if (int.TryParse(drawNumberMatch.Groups[1].Value, out int drawNumber))
|
||||
{
|
||||
Console.WriteLine("Draw Number: " + drawNumber);
|
||||
|
||||
AssignDrawNumberToModelProperty(drawNumber, eurosResult);
|
||||
return drawNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Failed to parse draw number.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Draw Number not found.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Meta keywords not found.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignDrawNumberToModelProperty(int drawNumber, EurosResult eurosResult)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.DrawNumber), eurosResult, drawNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
lottery-co-uk-scraper/EuroMillions/DrawStatus.cs
Normal file
50
lottery-co-uk-scraper/EuroMillions/DrawStatus.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class DrawStatus
|
||||
{
|
||||
public static bool ProcessRollover(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rolloverElement = doc.DocumentNode.Descendants("span")
|
||||
.FirstOrDefault(x => x.InnerText.Trim() == "Rollover");
|
||||
bool rollover = rolloverElement != null;
|
||||
|
||||
if (rollover)
|
||||
{
|
||||
AssignDrawStatusToModelProperty(rollover, eurosResult);
|
||||
Console.WriteLine("Rollover: " + rollover);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//ToDo: This isn't ideal how will i know if it fails.
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void AssignDrawStatusToModelProperty(bool status, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Rollover), eurosResult, status);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
733
lottery-co-uk-scraper/EuroMillions/DrawWinnerInformation.cs
Normal file
733
lottery-co-uk-scraper/EuroMillions/DrawWinnerInformation.cs
Normal file
@@ -0,0 +1,733 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
using lottery_co_uk_scraper.core.Exceptions;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal partial class DrawWinnerInformation
|
||||
{
|
||||
[GeneratedRegex(@"(\d+)")]
|
||||
private static partial Regex MyRegex();
|
||||
|
||||
internal class EurosTableRow()
|
||||
{
|
||||
internal const string Match1Plus2Stars = "Match 1 and 2 Stars";
|
||||
internal const string Match2 = "Match 2";
|
||||
internal const string Match2Plus1Star = "Match 2 and 1 Star";
|
||||
internal const string Match2Plus2Stars = "Match 2 and 2 Star";
|
||||
internal const string Match3 = "Match 3";
|
||||
internal const string Match3Plus1Star = "Match 3 and 1 Star";
|
||||
internal const string Match3Plus2Stars = "Match 3 and 2 Star";
|
||||
internal const string Match4 = "Match 4";
|
||||
internal const string Match4Plus1Star = "Match 4 and 1 Star";
|
||||
internal const string Match4Plus2Stars = "Match 4 and 2 Star";
|
||||
internal const string Match5 = "Match 5";
|
||||
internal const string Match5Plus1Star = "Match 5 and 1 Star";
|
||||
internal const string Match5Plus2Stars = "Match 5 and 2 Star";
|
||||
internal const string Total = "Totals";
|
||||
internal const string Winners = "UK Winners";
|
||||
internal const string PrizePerWinner = "Prize Per Winner";
|
||||
internal const string PrizeFundAmountUK = "UK Prize Fund";
|
||||
internal const string TotalWinners = "Total Winners";
|
||||
}
|
||||
|
||||
public static void ProcessWinnersTable(HtmlDocument doc, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var table = doc.DocumentNode.Descendants("table")
|
||||
.FirstOrDefault(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("euromillions mobFormat"));
|
||||
|
||||
if (table != null)
|
||||
{
|
||||
ProcessTableSection(table, EurosTableRow.Match1Plus2Stars, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match2, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match2Plus1Star, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match2Plus2Stars, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match3, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match3Plus1Star, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match3Plus2Stars, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match4, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match4Plus1Star, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match4Plus2Stars, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match5, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match5Plus1Star, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Match5Plus2Stars, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.Winners, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.PrizePerWinner, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.PrizeFundAmountUK, eurosResult);
|
||||
ProcessTableSection(table, EurosTableRow.TotalWinners, eurosResult);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Catch Exception
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessTableSection(HtmlNode table, string sectionTitle, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sectionRow = GetSectionRowByTitle(table, sectionTitle);
|
||||
|
||||
if (sectionRow != null)
|
||||
{
|
||||
var ukWinnersNode = GetNodeByDataTitle(sectionRow, EurosTableRow.Winners);
|
||||
var prizePerWinnerNode = GetNodeByDataTitle(sectionRow, EurosTableRow.PrizePerWinner);
|
||||
var prizeFundUKNode = GetNodeByDataTitle(sectionRow, EurosTableRow.PrizeFundAmountUK);
|
||||
var totalWinnersNode = GetNodeByDataTitle(sectionRow, EurosTableRow.TotalWinners);
|
||||
|
||||
if (ukWinnersNode != null && prizePerWinnerNode != null && prizeFundUKNode != null)
|
||||
{
|
||||
ProcessUKWinners(sectionTitle, ukWinnersNode, eurosResult);
|
||||
ProcessWinnerPrizeAmount(sectionTitle, prizePerWinnerNode, eurosResult);
|
||||
ProcessPrizeFundAmountUK(sectionTitle, prizeFundUKNode, eurosResult);
|
||||
ProcessTotalWinners(sectionTitle, totalWinnersNode, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo:Logger - Missing winners, prize per winner, or prize fund nodes in the table.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger - Section title '{sectionTitle}' not found in the table.
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger - Exception
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static HtmlNode GetSectionRowByTitle(HtmlNode table, string sectionTitle)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sectionRow = table.Descendants("tr")
|
||||
.FirstOrDefault(x => x.Descendants("td").Any(y => y.InnerText.Contains(sectionTitle, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
if (sectionRow != null)
|
||||
{
|
||||
return sectionRow;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NullResultException("Machine name is null.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo Logger
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static HtmlNode GetNodeByDataTitle(HtmlNode sectionRow, string dataTitle)
|
||||
{
|
||||
try
|
||||
{
|
||||
return sectionRow.Descendants("td")
|
||||
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == dataTitle)
|
||||
?? throw new InvalidOperationException($"Section row with title '{dataTitle}' not found.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ProcessUKWinners(string sectionTitle, HtmlNode winnersNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(winnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out int winners))
|
||||
{
|
||||
string columnTitle = winnersNode.Attributes["data-title"].Value;
|
||||
|
||||
ParseWinnerCount(sectionTitle, columnTitle, winners, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger - Failed to parse {sectionTitle} winners.
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseWinnerCount(string sectionTitle, string columnTitle, int winners, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssignValueToModelProperty(sectionTitle, EurosTableRow.Match2, columnTitle, winners, eurosResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessWinnerPrizeAmount(string sectionTitle, HtmlNode prizePerWinnerNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
string prizeText = prizePerWinnerNode.InnerText.Trim().Replace("£", "").Replace(",", "");
|
||||
string columnTitle = prizePerWinnerNode.Attributes["data-title"].Value;
|
||||
int prizePerWinner;
|
||||
|
||||
if (prizeText == "Free Ticket")
|
||||
{
|
||||
prizePerWinner = 999999999;
|
||||
}
|
||||
else if (int.TryParse(prizeText, NumberStyles.Currency, CultureInfo.InvariantCulture, out int parsedPrize))
|
||||
{
|
||||
prizePerWinner = parsedPrize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger - Failed to parse prize per winner ({sectionTitle}).
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ParseWinnerPrizeAmount(sectionTitle, columnTitle, prizePerWinner, eurosResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ParseWinnerPrizeAmount(string sectionTitle, string columnTitle, int prizePerWinner, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssignValueToModelProperty(sectionTitle, EurosTableRow.Match2, columnTitle, prizePerWinner, eurosResult);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessPrizeFundAmountUK(string sectionTitle, HtmlNode prizeFundNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
string prizeFundText = prizeFundNode.InnerText.Trim().Replace("£", "").Replace(",", "");
|
||||
string columnTitle = prizeFundNode.Attributes["data-title"].Value;
|
||||
int prizeFund;
|
||||
|
||||
if (prizeFundText == "-")
|
||||
{
|
||||
prizeFund = 999999999;
|
||||
}
|
||||
else if (int.TryParse(prizeFundText, NumberStyles.Currency, CultureInfo.InvariantCulture, out int parsedPrizeFund))
|
||||
{
|
||||
prizeFund = parsedPrizeFund;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger
|
||||
return;
|
||||
}
|
||||
|
||||
ParsePrizeFundAmountUK(sectionTitle, columnTitle, prizeFund, eurosResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ParsePrizeFundAmountUK(string sectionTitle, string columnTitle, int prizeFundNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssignValueToModelProperty(sectionTitle, EurosTableRow.Match2, columnTitle, prizeFundNode, eurosResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ProcessTotalWinners(string sectionTitle, HtmlNode totalWinnersNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(totalWinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out int totalWinners))
|
||||
{
|
||||
string columnTitle = totalWinnersNode.Attributes["data-title"].Value;
|
||||
|
||||
ParseTotalWinners(sectionTitle, columnTitle, totalWinners, eurosResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo: Logger - Failed to parse {sectionTitle} winners.
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void ParseTotalWinners(string sectionTitle, string columnTitle, int totalWinnersNode, EurosResult eurosResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
AssignValueToModelProperty(sectionTitle, EurosTableRow.Match2, columnTitle, totalWinnersNode, eurosResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignValueToModelProperty(string sectionTitle, string propertyName, string columnTitle, int value, EurosResult eurosResult)
|
||||
{
|
||||
switch (sectionTitle)
|
||||
{
|
||||
#region Match 1 Plus 2 Stars
|
||||
case EurosTableRow.Match1Plus2Stars:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched1Plus2StarsUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched1Plus2StarsPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched1Plus2StarsPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched1Plus2Stars), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Match 2, Match 2 Plus 1 Star & Match 2 Plus 2 Stars
|
||||
case EurosTableRow.Match2:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2UK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2PrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2PrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match2Plus1Star:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2Plus1StarUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2Plus1StarPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2Plus1StarPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2Plus1Star), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match2Plus2Stars:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2Plus2StarsUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2Plus2StarsPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched2Plus2StarsPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched2Plus2Stars), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Match 3, Match 3 Plus 1 Star & Match 3 Plus 2 Stars
|
||||
case EurosTableRow.Match3:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3UK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3PrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3PrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match3Plus1Star:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3Plus1StarUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3Plus1StarPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3Plus1StarPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3Plus1Star), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match3Plus2Stars:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3Plus2StarsUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3Plus2StarsPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched3Plus2StarsPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched3Plus2Stars), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Match 4, Match 4 Plus 1 Star & Match 4 Plus 2 Stars
|
||||
case EurosTableRow.Match4:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4UK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4PrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4PrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match4Plus1Star:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4Plus1StarUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4Plus1StarPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4Plus1StarPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4Plus1Star), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match4Plus2Stars:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4Plus2StarsUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4Plus2StarsPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched4Plus2StarsPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched4Plus2Stars), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Match 5, Match 5 Plus 1 Star & Match 5 Plus 2 Stars
|
||||
case EurosTableRow.Match5:
|
||||
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5UK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5PrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5PrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5), eurosResult, value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match5Plus1Star:
|
||||
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5Plus1StarUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5Plus1StarPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5Plus1StarPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5Plus1Star), eurosResult, value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EurosTableRow.Match5Plus2Stars:
|
||||
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5Plus2StarsUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizePerWinner)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5Plus2StarsPrizeUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.Matched5Plus2StarsPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
|
||||
if (columnTitle == EurosTableRow.TotalWinners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalMatched5Plus2Stars), eurosResult, value);
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
|
||||
#region Totals
|
||||
case EurosTableRow.Total:
|
||||
try
|
||||
{
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalWinnersUK), eurosResult, value);
|
||||
}
|
||||
if (columnTitle == EurosTableRow.PrizeFundAmountUK)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalPrizeFundUK), eurosResult, value);
|
||||
}
|
||||
if (columnTitle == EurosTableRow.Winners)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(eurosResult.TotalWinners), eurosResult, value);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ToDo: Logger
|
||||
Console.WriteLine("Nothing to match");
|
||||
}
|
||||
|
||||
break;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
lottery-co-uk-scraper/EuroMillions/Euros.cs
Normal file
43
lottery-co-uk-scraper/EuroMillions/Euros.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.data;
|
||||
|
||||
namespace lottery_co_uk_scraper.EuroMillions
|
||||
{
|
||||
internal class Euros
|
||||
{
|
||||
public static async Task GetEuroMillionsData(string url, HttpClient client)
|
||||
{
|
||||
try
|
||||
{
|
||||
string html = await client.GetStringAsync(url);
|
||||
var eurosResult = new EurosResult();
|
||||
var doc = new HtmlDocument();
|
||||
doc.LoadHtml(html);
|
||||
|
||||
DrawBalls.ProcessBallSetUsed(doc, eurosResult);
|
||||
DrawDate.ProcessDrawDateFromMeta(doc, eurosResult); // Not working.
|
||||
DrawNumber.ProcessDrawNumberFromMeta(doc, eurosResult);
|
||||
DrawCode.ProcessMillionaireMaker(doc, eurosResult); // Not working.
|
||||
DrawStatus.ProcessRollover(doc, eurosResult);
|
||||
DrawBalls.ProcessMainBalls(doc, eurosResult);
|
||||
DrawBalls.ProcessLuckyStars(doc, eurosResult);
|
||||
DrawMachine.ProcessMachineUsed(doc, eurosResult);
|
||||
DrawWinnerInformation.ProcessWinnersTable(doc, eurosResult);
|
||||
|
||||
|
||||
CommitToDatabase.SaveModelToDatabase(eurosResult);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
// ToDo: Logger HTTP request error: {ex.Message}
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: Logger - An error occurred: {ex.Message}
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,13 +50,27 @@ namespace lottery_co_uk_scraper.NationalLottery
|
||||
|
||||
public static void ProcessMainBalls(HtmlDocument doc, LottoResult lottoResult)
|
||||
{
|
||||
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
|
||||
try
|
||||
{
|
||||
var ballsDrawn = GetNodeById(doc.DocumentNode, LotteryTableRow.BallsDrawn);
|
||||
|
||||
List<int>? lottoBalls = ballsDrawn != null
|
||||
? ExtractBalls(ballsDrawn, "lotto-ball")
|
||||
: null;
|
||||
List<int>? lottoBalls = ballsDrawn != null
|
||||
? ExtractBalls(ballsDrawn, "lotto-ball")
|
||||
: null;
|
||||
|
||||
AssignDrawBallsToModelProperty(LotteryTableRow.BallsDrawn, lottoBalls, lottoResult);
|
||||
if (lottoBalls != null)
|
||||
{
|
||||
AssignDrawBallsToModelProperty(LotteryTableRow.BallsDrawn, lottoBalls, lottoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ToDo:
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ToDo:
|
||||
}
|
||||
}
|
||||
|
||||
private static HtmlNode GetNodeById(HtmlNode containerNode, string nodeId)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using HtmlAgilityPack;
|
||||
using lottery_co_uk_scraper.core.Exceptions;
|
||||
using lottery_co_uk_scraper.core.Models;
|
||||
using lottery_co_uk_scraper.Utilities;
|
||||
|
||||
@@ -8,20 +9,39 @@ namespace lottery_co_uk_scraper.NationalLottery
|
||||
{
|
||||
public static string ProcessMachineUsed(HtmlDocument doc, LottoResult lottoResult)
|
||||
{
|
||||
var machineName = doc.DocumentNode.Descendants("td")
|
||||
.Where(x => x.InnerHtml.Contains("<strong>Ball Machine Used:</strong>"))
|
||||
.Select(x => x.InnerText.Split(':')[1].Trim())
|
||||
.FirstOrDefault();
|
||||
try
|
||||
{
|
||||
var machineName = doc.DocumentNode.Descendants("td")
|
||||
.Where(x => x.InnerHtml.Contains("<strong>Ball Machine Used:</strong>"))
|
||||
.Select(x => x.InnerText.Split(':')[1].Trim())
|
||||
.FirstOrDefault();
|
||||
|
||||
AssignDrawMachineToModelProperty("MachineName", machineName, lottoResult);
|
||||
Console.WriteLine("Machine Name: " + machineName);
|
||||
// should there be a try parse and error exception stuff here like in ballSetUsed
|
||||
return machineName;
|
||||
if (machineName != null)
|
||||
{
|
||||
AssignDrawMachineToModelProperty(nameof(lottoResult.MachineUsed), machineName, lottoResult);
|
||||
|
||||
return machineName;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NullResultException(nameof(lottoResult.MachineUsed) + " is null.");
|
||||
}
|
||||
}
|
||||
catch (NullResultException nullEx)
|
||||
{
|
||||
return nullEx.Message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// ToDo: _logger.LogErrorMessage();
|
||||
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AssignDrawMachineToModelProperty(string propertyName, string machineName, LottoResult lottoResult)
|
||||
{
|
||||
PropertyManager.SetProperty(nameof(lottoResult.MachineUsed), lottoResult, machineName);
|
||||
PropertyManager.SetProperty(propertyName, lottoResult, machineName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ namespace lottery_co_uk_scraper.NationalLottery
|
||||
{
|
||||
var rolloverElement = doc.DocumentNode.Descendants("span")
|
||||
.FirstOrDefault(x => x.InnerText.Trim() == "Rollover");
|
||||
|
||||
bool rollover = rolloverElement != null;
|
||||
|
||||
if (rollover)
|
||||
@@ -30,7 +29,6 @@ namespace lottery_co_uk_scraper.NationalLottery
|
||||
{
|
||||
var rolldownElement = doc.DocumentNode.Descendants("span")
|
||||
.FirstOrDefault(x => x.InnerText.Trim() == "Rolldown");
|
||||
|
||||
bool rolldown = rolldownElement != null;
|
||||
|
||||
if (rolldown)
|
||||
|
||||
@@ -11,54 +11,68 @@ namespace lottery_co_uk_scraper.NationalLottery
|
||||
{
|
||||
public static void ProcessTableSection(HtmlNode table, string sectionTitle, LottoResult lottoResult)
|
||||
{
|
||||
var sectionRow = GetSectionRowByTitle(table, sectionTitle);
|
||||
|
||||
if (sectionRow != null)
|
||||
try
|
||||
{
|
||||
var winnersNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.Winners);
|
||||
var prizePerWinnerNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.PrizePerWinner);
|
||||
var prizeFundNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.PrizeFundAmount);
|
||||
var rolldown = lottoResult.Rolldown;
|
||||
var sectionRow = GetSectionRowByTitle(table, sectionTitle);
|
||||
|
||||
if (winnersNode != null && prizePerWinnerNode != null && prizeFundNode != null)
|
||||
if (sectionRow != null)
|
||||
{
|
||||
ProcessWinners(sectionTitle, winnersNode, lottoResult);
|
||||
ProcessPrizeFundAmount(sectionTitle, prizeFundNode, lottoResult);
|
||||
var winnersNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.Winners);
|
||||
var prizePerWinnerNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.PrizePerWinner);
|
||||
var prizeFundNode = GetNodeByDataTitle(sectionRow, LotteryTableRow.PrizeFundAmount);
|
||||
var rolldown = lottoResult.Rolldown;
|
||||
|
||||
if (rolldown == false)
|
||||
if (winnersNode != null && prizePerWinnerNode != null && prizeFundNode != null)
|
||||
{
|
||||
ProcessWinnerPrizeAmount(sectionTitle, prizePerWinnerNode, lottoResult);
|
||||
ProcessWinners(sectionTitle, winnersNode, lottoResult);
|
||||
ProcessPrizeFundAmount(sectionTitle, prizeFundNode, lottoResult);
|
||||
|
||||
if (rolldown == false)
|
||||
{
|
||||
ProcessWinnerPrizeAmount(sectionTitle, prizePerWinnerNode, lottoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessRolldownWinnerPrizeAmount(sectionTitle, prizePerWinnerNode, lottoResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessRolldownWinnerPrizeAmount(sectionTitle, prizePerWinnerNode, lottoResult);
|
||||
Console.WriteLine("Missing winners, prize per winner, or prize fund nodes in the table.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Missing winners, prize per winner, or prize fund nodes in the table.");
|
||||
Console.WriteLine($"Section title '{sectionTitle}' not found in the table.");
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Section title '{sectionTitle}' not found in the table.");
|
||||
|
||||
}
|
||||
}
|
||||
private static HtmlNode GetSectionRowByTitle(HtmlNode table, string sectionTitle)
|
||||
{
|
||||
var sectionRow = table.Descendants("tr")
|
||||
.FirstOrDefault(x =>
|
||||
x.Descendants("td").Any(y => y.InnerText.Contains(sectionTitle, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
try
|
||||
{
|
||||
var sectionRow = table.Descendants("tr")
|
||||
.FirstOrDefault(x => x.Descendants("td").Any(y => y.InnerText.Contains(sectionTitle, StringComparison.OrdinalIgnoreCase)));
|
||||
|
||||
if (sectionRow != null)
|
||||
{
|
||||
return sectionRow;
|
||||
if (sectionRow != null)
|
||||
{
|
||||
return sectionRow;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static HtmlNode GetNodeByDataTitle(HtmlNode sectionRow, string dataTitle)
|
||||
|
||||
Reference in New Issue
Block a user