Skip to content

Commit

Permalink
Move non-root user below apt-get
Browse files Browse the repository at this point in the history
  • Loading branch information
KarmaKamikaze committed Sep 25, 2024
1 parent 4b899a2 commit 82ea36f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 32 deletions.
6 changes: 3 additions & 3 deletions MoxfieldPriceScraper/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ RUN DOTNET_EnableWriteXorExecute=0 dotnet publish -c $BUILD_CONFIGURATION -o out
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS runtime
WORKDIR /app

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

# Install chromium and dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
Expand All @@ -32,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
49 changes: 20 additions & 29 deletions MoxfieldPriceScraper/MoxfieldScraper.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
using System.Globalization;
using System.Drawing;
using System.Globalization;
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 +25,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 @@ -60,22 +60,18 @@ public async Task ScrapeAsync(CancellationToken cancellationToken)
if (!string.IsNullOrEmpty(_settings.SenderEmailAddress) &&
!string.IsNullOrEmpty(_settings.SenderEmailPassword) &&
!string.IsNullOrEmpty(_settings.ReceiverEmailAddress))
{
await EmailService.SendEmailWithEmbeddedImageAsync(_settings.SenderEmailAddress,
_settings.SenderEmailPassword,
_settings.ReceiverEmailAddress, $"Moxfield Scraper Success on {_deckTitle}!",
$"Optimal price found for {_deckTitle}: €{finalPrice}! See attachment proof...",
Path.Combine(dataDirectory, $"{_deckTitle}_proof.png"));
}
else
{
Log.Warning("Email notification settings are not fully configured");
}
}
}

/// <summary>
/// Disposes of the WebDriver instance.
/// Disposes of the WebDriver instance.
/// </summary>
public void Dispose()
{
Expand All @@ -84,7 +80,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,7 +98,7 @@ 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()
{
Expand All @@ -127,7 +123,7 @@ private void InitializeWebDriver()
}

/// <summary>
/// Gets the location of the Chrome/Chromium browser.
/// Gets the location of the Chrome/Chromium browser.
/// </summary>
/// <returns>Returns the path to the browser binary.</returns>
private static string GetChromeLocation()
Expand All @@ -140,7 +136,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 +182,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 +209,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 +218,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 +232,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 +250,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 +266,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 All @@ -296,18 +290,15 @@ private async Task<decimal> GetPrice(decimal targetPrice, int updateFrequency, C
Log.Information("{Time}\tPrice Before: [€{BeforePrice}]\tNow: [€{NewPrice}]",
DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"), price, newPrice);
price = newPrice;
if (price > targetPrice)
{
Thread.Sleep(TimeSpan.FromSeconds(updateFrequency));
}
if (price > targetPrice) Thread.Sleep(TimeSpan.FromSeconds(updateFrequency));
}

Log.Information("Optimal price found: €{Price}!", price);
return price;
}

/// <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 All @@ -316,15 +307,15 @@ private void SaveImageProof(string imagePath = "proof.jpeg")
var originalSize = _driver!.Manage().Window.Size;
Log.Debug("Original window size is [{Width},{Height}]", originalSize.Width, originalSize.Height);
var requiredWidth =
Convert.ToInt32((long) _driver.ExecuteScript("return document.body.parentNode.scrollWidth"));
Convert.ToInt32((long)_driver.ExecuteScript("return document.body.parentNode.scrollWidth"));
var requiredHeight =
Convert.ToInt32((long) _driver.ExecuteScript("return document.body.parentNode.scrollHeight"));
Convert.ToInt32((long)_driver.ExecuteScript("return document.body.parentNode.scrollHeight"));
_driver.Manage().Window.Size = new Size(requiredWidth, requiredHeight);
Log.Debug("Window size set to full page screenshot size [{Width},{Height}]", requiredWidth,
requiredHeight);

//_driver.GetScreenshot().SaveAsFile(imagePath); // has scrollbar
((ITakesScreenshot) _driver.FindElement(By.TagName("body"))).GetScreenshot()
((ITakesScreenshot)_driver.FindElement(By.TagName("body"))).GetScreenshot()
.SaveAsFile(imagePath); // avoids scrollbar
Log.Debug("Screenshot saved as [{ImagePath}]", imagePath);

Expand Down

0 comments on commit 82ea36f

Please sign in to comment.