Skip to content

Commit

Permalink
Merge tag '2.0.5' into dev
Browse files Browse the repository at this point in the history
DriverManager hotfix
  • Loading branch information
KarmaKamikaze committed Sep 25, 2024
2 parents c416ddf + 8525850 commit 294fc0a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 32 deletions.
15 changes: 7 additions & 8 deletions MoxfieldPriceScraper/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
FROM alpine:3.20 AS base

RUN useradd -m moxfieldpricescraper
USER moxfieldpricescraper

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
ARG BUILD_CONFIGURATION=Release
WORKDIR /app

COPY *.csproj ./
RUN DOTNET_EnableWriteXorExecute=0 dotnet restore --disable-parallel
RUN DOTNET_EnableWriteXorExecute=0 dotnet restore

COPY . ./
RUN DOTNET_EnableWriteXorExecute=0 dotnet publish -c $BUILD_CONFIGURATION -o out --no-restore

FROM mcr.microsoft.com/dotnet/runtime:8.0 AS runtime
WORKDIR /app

# Install chromium
# Install chromium and dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
chromium-driver \
libgtk-3-0 \
libx11-xcb1 \
libxcomposite1 \
Expand All @@ -33,6 +29,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN useradd -m moxfieldpricescraper && chown -R moxfieldpricescraper /app
USER moxfieldpricescraper

COPY --from=build-env /app/out .

HEALTHCHECK --interval=5m --timeout=1m --start-period=30s --retries=3 CMD ["dotnet", "MoxfieldPriceScraper.dll", "healthcheck"]
Expand Down
4 changes: 2 additions & 2 deletions MoxfieldPriceScraper/Healthcheck/Healthcheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static void UpdateTaskStatus(string taskName, string status)
var taskStatus = JsonConvert.DeserializeObject<TaskStatus>(File.ReadAllText(statusFilePath));
if (taskStatus != null)
{
taskStatus.Statuses[taskName] = status;
taskStatus.Status[taskName] = status;
File.WriteAllText(statusFilePath, JsonConvert.SerializeObject(taskStatus, Formatting.Indented));
}
}
Expand All @@ -64,7 +64,7 @@ public static bool AreTasksRunning()
}

var taskStatus = JsonConvert.DeserializeObject<TaskStatus>(File.ReadAllText(statusFilePath));
return taskStatus != null && taskStatus.Statuses.ContainsValue("running");
return taskStatus != null && taskStatus.Status.ContainsValue("running");
}
}
}
2 changes: 1 addition & 1 deletion MoxfieldPriceScraper/Healthcheck/TaskStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public class TaskStatus
{
public Dictionary<string, string> Statuses { get; set; } = new();
public Dictionary<string, string> Status { get; set; } = new();
}
46 changes: 25 additions & 21 deletions MoxfieldPriceScraper/MoxfieldScraper.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
using System.Globalization;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Serilog;
using System.Drawing;
using WebDriverManager;
using WebDriverManager.DriverConfigs.Impl;

namespace MoxfieldPriceScraper;

public class MoxfieldScraper : IMoxfieldScraper
{
private readonly ISettings _settings;
private readonly string _deckUrl;
private readonly TimeSpan _elementSeekTimeout = TimeSpan.FromSeconds(30);
private readonly ISettings _settings;
private string _deckAuthor = string.Empty;
private string _deckTitle = string.Empty;
private readonly TimeSpan _elementSeekTimeout = TimeSpan.FromSeconds(30);
private ChromeDriver? _driver;
private bool _disposed;
private ChromeDriver? _driver;

public MoxfieldScraper(string deckUrl, ISettings settings)
{
Expand All @@ -25,7 +26,7 @@ public MoxfieldScraper(string deckUrl, ISettings settings)
InitializeWebDriver();
}

/// <inheritdoc/>
/// <inheritdoc />
public async Task ScrapeAsync(CancellationToken cancellationToken)
{
await _driver!.Navigate().GoToUrlAsync(_deckUrl);
Expand Down Expand Up @@ -75,7 +76,7 @@ await EmailService.SendEmailWithEmbeddedImageAsync(_settings.SenderEmailAddress,
}

/// <summary>
/// Disposes of the WebDriver instance.
/// Disposes of the WebDriver instance.
/// </summary>
public void Dispose()
{
Expand All @@ -84,7 +85,7 @@ public void Dispose()
}

/// <summary>
/// Disposes of the WebDriver instance.
/// Disposes of the WebDriver instance.
/// </summary>
/// <param name="disposing">Determines if the function is called from Dispose.</param>
protected virtual void Dispose(bool disposing)
Expand All @@ -102,15 +103,14 @@ protected virtual void Dispose(bool disposing)
}

/// <summary>
/// Initializes the WebDriver with the required settings.
/// Initializes the WebDriver with the required settings.
/// </summary>
private void InitializeWebDriver()
{
Log.Debug("Initializing WebDriver");
new DriverManager().SetUpDriver(new ChromeConfig());
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--no-sandbox"); // Bypass OS security model
chromeOptions.AddArgument("--headless"); // Run in headless mode, without a GUI
chromeOptions.AddArgument("--headless=new"); // Run in headless mode, without a GUI
chromeOptions.AddArgument("--window-size=2560,1440"); // Set window size
chromeOptions.AddArgument("--log-level=3"); // Disable logging
chromeOptions.AddExcludedArguments("enable-logging"); // Disable logging
Expand All @@ -121,15 +121,21 @@ private void InitializeWebDriver()
};
chromeOptions.AddUserProfilePreference("prefs", preferences);

if (RuntimeInformation.OSArchitecture == Architecture.Arm ||
RuntimeInformation.OSArchitecture == Architecture.Arm64)
{
new DriverManager().SetUpDriver(new ChromeConfig());
}

_driver = new ChromeDriver(chromeOptions);
_driver.Manage().Timeouts().ImplicitWait = _elementSeekTimeout;
Log.Debug("WebDriver initialized with ImplicitWait set to {Timeout}", _elementSeekTimeout);
}

/// <summary>
/// Gets the location of the Chrome/Chromium browser.
/// Gets the location of the Chrome/Chromium browser.
/// </summary>
/// <returns></returns>
/// <returns>Returns the path to the browser binary.</returns>
private static string GetChromeLocation()
{
var options = new ChromeOptions
Expand All @@ -140,7 +146,7 @@ private static string GetChromeLocation()
}

/// <summary>
/// Logs in to Moxfield with the provided credentials.
/// Logs in to Moxfield with the provided credentials.
/// </summary>
/// <param name="username">Moxfield username for login.</param>
/// <param name="password">Moxfield password for login.</param>
Expand Down Expand Up @@ -186,7 +192,7 @@ private void LoginToMoxfieldAsync(string username, string password)
}

/// <summary>
/// Sets the price of the deck to the lowest possible value.
/// Sets the price of the deck to the lowest possible value.
/// </summary>
private void SetPriceToLowest()
{
Expand All @@ -213,7 +219,7 @@ private void SetPriceToLowest()
}

/// <summary>
/// Grabs the price of the deck from Moxfield.
/// Grabs the price of the deck from Moxfield.
/// </summary>
/// <returns>The Moxfield deck price.</returns>
private string GetPriceField()
Expand All @@ -222,7 +228,7 @@ private string GetPriceField()
}

/// <summary>
/// Checks if the currency is set to Euro (€) on Moxfield. If it is not, it changes it.
/// Checks if the currency is set to Euro (€) on Moxfield. If it is not, it changes it.
/// </summary>
private async Task CheckCurrency()
{
Expand All @@ -236,7 +242,6 @@ private async Task CheckCurrency()

// Try to find the "up" arrow to change currency to Euro using Cardmarket
while (true)
{
try
{
var upButton = _driver.FindElement(By.CssSelector("#affiliate-control-cardmarket-up"));
Expand All @@ -255,7 +260,6 @@ private async Task CheckCurrency()
Log.Debug("Cardmarket affiliate is listed at the top");
break;
}
}

var saveSettingsBox = _driver.FindElement(By.CssSelector(
"#maincontent > div > div.row > div.col-lg-8.pe-lg-5.order-2.order-lg-1 > form > " +
Expand All @@ -272,7 +276,7 @@ private async Task CheckCurrency()
}

/// <summary>
/// Gets the price for the deck when it falls under the target price given.
/// Gets the price for the deck when it falls under the target price given.
/// </summary>
/// <param name="targetPrice">The target price which we aim to fall under.</param>
/// <param name="updateFrequency">How often we check for a price update in seconds.</param>
Expand Down Expand Up @@ -307,7 +311,7 @@ private async Task<decimal> GetPrice(decimal targetPrice, int updateFrequency, C
}

/// <summary>
/// Saves a screenshot of the deck page as proof of the optimal price found.
/// Saves a screenshot of the deck page as proof of the optimal price found.
/// </summary>
/// <param name="imagePath">The path to the screenshot image.</param>
private void SaveImageProof(string imagePath = "proof.jpeg")
Expand Down

0 comments on commit 294fc0a

Please sign in to comment.