Files
DatBrowser/app/Browser/Jobs/HellcaseBattles/HellcaseBattlesJob.php
Matthias Guillitte fadb4d2748
All checks were successful
Push image to registry / build-image (push) Successful in 4m29s
Added job artifacts, dealing with cancelled battle & fixed and improved notification
2025-03-20 19:16:00 +01:00

168 lines
6.0 KiB
PHP

<?php
namespace App\Browser\Jobs\HellcaseBattles;
use App\Browser\JobDebugScreenshot;
use App\Browser\Jobs\Hellcase\HellcaseJob;
use App\Models\HellcaseBattle;
use App\Models\Job;
use App\Models\JobArtifact;
use App\Models\JobRun;
use App\Notification\Notifications\JobDebugNotification;
use App\Notification\Providers\AllNotification;
use Exception;
use Facebook\WebDriver\WebDriver;
use Facebook\WebDriver\WebDriverBy;
use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Laravel\Dusk\Browser;
class HellcaseBattlesJob extends HellcaseJob implements ShouldBeUniqueUntilProcessing
{
private Collection $jobInfos;
private array $battlesToAdd = [];
private array $battlesSent = [];
public function __construct()
{
Log::info("Constructing HellcaseBattlesJob");
parent::__construct(3);
}
public function run(Browser $browser): ?JobRun
{
$this->jobInfos = Job::find($this->jobId)->jobInfosTable();
Log::info("Running HellcaseBattlesJob");
$this->jobRun = new JobRun([
"job_id" => $this->jobId,
"success" => false,
]);
$this->jobRun->save();
$browser->visit('https://hellcase.com');
$browser->waitForText("CASES", 30, true);
$this->removePopups($browser);
sleep(5);
$this->signin($browser);
$this->saveInterestingBattles($browser);
$this->sendFinishedBattles($browser);
$this->jobRun->addArtifact(new JobArtifact([
"name" => count($this->battlesSent) . " battailles envoyées",
]));
$this->createNewBattles();
$this->jobRun->addArtifact(new JobArtifact([
"name" => count($this->battlesToAdd) . " nouvelles battailles ajoutées pour surveillage",
]));
$this->jobRun->success = true;
$this->jobRun->save();
Log::info("HellcaseBattlesJob run ended");
return $this->jobRun;
}
/**
* Save current cases battles to database for later processing
* @param \Laravel\Dusk\Browser $browser
* @return void
*/
private function saveInterestingBattles(Browser $browser)
{
$battleIndex = 0; // Index of the battle to get info from
$running = true;
while ($running) {
$browser->visit('https://hellcase.com/casebattle');
$browser->waitForText("CASES", 30, true);
// Sort by price
try {
$sortByPriceDiv = $browser->driver->findElement(WebDriverBy::xpath("//*[span[contains(text(), 'Value')]]"));
$sortByPriceDiv->click();
} catch (Exception $e) {
$browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
AllNotification::send(new JobDebugNotification($this->jobId, "Failed to sort by price"));
return;
}
sleep(5);
$battles = $browser->driver->findElements(WebDriverBy::xpath("//*[contains(@class, 'casebattle-table__item')]"));
$battle = $battles[$battleIndex];
$battleIndex++;
$browser->scrollIntoView(".casebattle-table__item:nth-child(" . max($battleIndex -1, 1) . ")");
sleep(2);
$battleValue = floatval(
explode(
"\n",
$battle->findElement(WebDriverBy::xpath("./div/div[contains(@class, 'core-price')]"))->getDomProperty("innerText")
)[1]
);
if ($battleValue < floatval($this->jobInfos->get("hellcase_battles_minimum_value"))) {
$running = false;
break;
}
$battleLinkButton = $battle->findElement(WebDriverBy::xpath('./div//button[text() = "watch"]'));
$battleLinkButton->sendKeys("\n");
sleep(3);
try { // If we still are on the casebattle page, it means the battle was cancelled or something else
$browser->waitForLocation("https://hellcase.com/casebattle/", 3);
} catch (Exception $e) {
$battleLink = $browser->driver->getCurrentURL();
$this->battlesToAdd[$battleLink] = $battleValue;
}
}
}
private function sendFinishedBattles(Browser $browser) {
// foreach battle that we didn"t already planned to add with $this->battlesToAdd
foreach (HellcaseBattle::all() as $battle) {
if (!array_key_exists($battle->getUrl(), $this->battlesToAdd)) {
$browser->visit($battle->getUrl());
sleep(2);
$browser->waitForText("Case Battle");
if ($this->findElementContainingText($browser, "Started at:") != null) { // battle is finished
// Send the battle
$this->sendBattle($browser, $battle);
}
$battle->delete();
}
}
}
private function sendBattle(Browser $browser, HellcaseBattle $battle) {
try {
$battleHeader = $browser->driver->findElement(WebDriverBy::xpath("//*[contains(@class, 'case-battle-game__header')]"));
sleep(2); // Wait for the animations to finish
$battleHeader->takeElementScreenshot(HellcaseBattleScreenshot::getImgFileAbsolutePath());
} catch (Exception $e) {
$browser->screenshot(JobDebugScreenshot::getFileName($this->jobId));
AllNotification::send(new JobDebugNotification($this->jobId, "Failed to screenshot battle"));
}
$this->battlesSent[$battle->getUrl()] = $battle->value;
AllNotification::send(new HellcaseBattlesNofication($this->jobId, $battle));
}
private function createNewBattles() {
foreach ($this->battlesToAdd as $battleLink => $battleValue) {
$battleLink = explode("/", $battleLink);
HellcaseBattle::firstOrCreate([
"battle_id" => $battleLink[count($battleLink) - 1],
"value" => $battleValue,
]);
}
}
}