From 82ea36f76a4a8e6d52dcadca414bcedc7004d4dd Mon Sep 17 00:00:00 2001 From: KarmaKamikaze Date: Wed, 25 Sep 2024 15:46:57 +0200 Subject: [PATCH] Move non-root user below apt-get --- MoxfieldPriceScraper/Dockerfile | 6 +-- MoxfieldPriceScraper/MoxfieldScraper.cs | 49 ++++++++++--------------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/MoxfieldPriceScraper/Dockerfile b/MoxfieldPriceScraper/Dockerfile index 7c85916..1cf4fa2 100644 --- a/MoxfieldPriceScraper/Dockerfile +++ b/MoxfieldPriceScraper/Dockerfile @@ -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 \ @@ -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"] diff --git a/MoxfieldPriceScraper/MoxfieldScraper.cs b/MoxfieldPriceScraper/MoxfieldScraper.cs index b9d851f..55b2390 100644 --- a/MoxfieldPriceScraper/MoxfieldScraper.cs +++ b/MoxfieldPriceScraper/MoxfieldScraper.cs @@ -1,8 +1,8 @@ -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; @@ -10,13 +10,13 @@ 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) { @@ -25,7 +25,7 @@ public MoxfieldScraper(string deckUrl, ISettings settings) InitializeWebDriver(); } - /// + /// public async Task ScrapeAsync(CancellationToken cancellationToken) { await _driver!.Navigate().GoToUrlAsync(_deckUrl); @@ -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"); - } } } /// - /// Disposes of the WebDriver instance. + /// Disposes of the WebDriver instance. /// public void Dispose() { @@ -84,7 +80,7 @@ public void Dispose() } /// - /// Disposes of the WebDriver instance. + /// Disposes of the WebDriver instance. /// /// Determines if the function is called from Dispose. protected virtual void Dispose(bool disposing) @@ -102,7 +98,7 @@ protected virtual void Dispose(bool disposing) } /// - /// Initializes the WebDriver with the required settings. + /// Initializes the WebDriver with the required settings. /// private void InitializeWebDriver() { @@ -127,7 +123,7 @@ private void InitializeWebDriver() } /// - /// Gets the location of the Chrome/Chromium browser. + /// Gets the location of the Chrome/Chromium browser. /// /// Returns the path to the browser binary. private static string GetChromeLocation() @@ -140,7 +136,7 @@ private static string GetChromeLocation() } /// - /// Logs in to Moxfield with the provided credentials. + /// Logs in to Moxfield with the provided credentials. /// /// Moxfield username for login. /// Moxfield password for login. @@ -186,7 +182,7 @@ private void LoginToMoxfieldAsync(string username, string password) } /// - /// Sets the price of the deck to the lowest possible value. + /// Sets the price of the deck to the lowest possible value. /// private void SetPriceToLowest() { @@ -213,7 +209,7 @@ private void SetPriceToLowest() } /// - /// Grabs the price of the deck from Moxfield. + /// Grabs the price of the deck from Moxfield. /// /// The Moxfield deck price. private string GetPriceField() @@ -222,7 +218,7 @@ private string GetPriceField() } /// - /// 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. /// private async Task CheckCurrency() { @@ -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")); @@ -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 > " + @@ -272,7 +266,7 @@ private async Task CheckCurrency() } /// - /// 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. /// /// The target price which we aim to fall under. /// How often we check for a price update in seconds. @@ -296,10 +290,7 @@ private async Task 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); @@ -307,7 +298,7 @@ private async Task GetPrice(decimal targetPrice, int updateFrequency, C } /// - /// 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. /// /// The path to the screenshot image. private void SaveImageProof(string imagePath = "proof.jpeg") @@ -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);