Compare commits
5 Commits
basic-broa
...
7079206658
Author | SHA1 | Date | |
---|---|---|---|
7079206658 | |||
db9d65f445 | |||
a1219b92ce | |||
ce13d1b0dd | |||
a80a32eee8 |
47
app/Browser/Components/Hellcase/EpicGamesLogin.php
Normal file
47
app/Browser/Components/Hellcase/EpicGamesLogin.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Browser\Components\Hellcase;
|
||||||
|
|
||||||
|
use Laravel\Dusk\Browser;
|
||||||
|
use Laravel\Dusk\Component as BaseComponent;
|
||||||
|
|
||||||
|
class EpicGamesLogin extends BaseComponent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the root selector for the component.
|
||||||
|
*/
|
||||||
|
public function selector(): string
|
||||||
|
{
|
||||||
|
return 'form';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that the browser page contains the component.
|
||||||
|
*/
|
||||||
|
public function assert(Browser $browser): void
|
||||||
|
{
|
||||||
|
$browser->assertVisible($this->selector());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the element shortcuts for the component.
|
||||||
|
*
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
public function elements(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'@email' => 'input#email',
|
||||||
|
'@password' => 'input#password',
|
||||||
|
'@signin-button' => 'button[type="submit"]',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fillForm(Browser $browser, $email, $password) {
|
||||||
|
$browser->type('@email', $email);
|
||||||
|
sleep(1);
|
||||||
|
$browser->type('@password', $password);
|
||||||
|
sleep(1);
|
||||||
|
$browser->click('@signin-button');
|
||||||
|
}
|
||||||
|
}
|
133
app/Browser/Jobs/EpicGames/EpicGamesJob.php
Normal file
133
app/Browser/Jobs/EpicGames/EpicGamesJob.php
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Browser\Jobs\EpicGames;
|
||||||
|
|
||||||
|
use App\Browser\BrowserJob;
|
||||||
|
use App\Browser\Components\Hellcase\EpicGamesLogin;
|
||||||
|
use App\Browser\Components\Hellcase\MainNav;
|
||||||
|
use App\Browser\Jobs\Hellcase\HellcaseLoginQrCode;
|
||||||
|
use App\Models\JobArtifact;
|
||||||
|
use App\Models\JobInfo;
|
||||||
|
use App\Models\JobRun;
|
||||||
|
use App\Notification\NotificationBody\Hellcase\HellcaseNotificationDailyFreeBody;
|
||||||
|
use App\Notification\NotificationBody\Hellcase\HellcaseNotificationLoginBody;
|
||||||
|
use App\Notification\Notifications\Hellcase\HellcaseNotificationDailyFree;
|
||||||
|
use App\Notification\Notifications\Hellcase\HellcaseNotificationLogin;
|
||||||
|
use App\Notification\Providers\AllNotification;
|
||||||
|
use Exception;
|
||||||
|
use Facebook\WebDriver\WebDriverBy;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Laravel\Dusk\Browser;
|
||||||
|
|
||||||
|
class EpicGamesJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
|
||||||
|
{
|
||||||
|
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
|
||||||
|
|
||||||
|
private const WEBSITE_URL = "https://www.epicgames.com/store/en-US/";
|
||||||
|
|
||||||
|
private JobRun $jobRun;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
Log::info("Constructing " . self::class);
|
||||||
|
parent::__construct(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run(Browser $browser): ?JobRun
|
||||||
|
{
|
||||||
|
sleep(40);
|
||||||
|
Log::info("Running " . self::class);
|
||||||
|
$this->jobRun = new JobRun([
|
||||||
|
"job_id" => $this->jobId,
|
||||||
|
"success" => false,
|
||||||
|
]);
|
||||||
|
$this->jobRun->save();
|
||||||
|
|
||||||
|
$this->goToEpicGamesWebsite($browser);
|
||||||
|
$this->removePopups($browser);
|
||||||
|
sleep(5);
|
||||||
|
$this->signin($browser);
|
||||||
|
$this->getFreeGames($browser);
|
||||||
|
|
||||||
|
$this->jobRun->success = true;
|
||||||
|
$this->jobRun->save();
|
||||||
|
|
||||||
|
Log::info( self::class . " run ended");
|
||||||
|
|
||||||
|
return $this->jobRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function runTest(Browser $browser): ?JobRun
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->goToEpicGamesWebsite($browser);
|
||||||
|
sleep(2);
|
||||||
|
$this->removePopups($browser);
|
||||||
|
sleep(2);
|
||||||
|
$this->signin($browser);
|
||||||
|
return $this->makeSimpleJobRun(
|
||||||
|
true,
|
||||||
|
"Connexion réussie",
|
||||||
|
"Datboi a réussi à se connecter sur EpicGames"
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->makeSimpleJobRun(
|
||||||
|
true,
|
||||||
|
"Connexion échouée",
|
||||||
|
"Datboi n'a pas réussi à se connecter sur EpicGames :\n" . $e->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function goToEpicGamesWebsite(Browser $browser)
|
||||||
|
{
|
||||||
|
sleep(3);
|
||||||
|
$browser->visit(self::WEBSITE_URL);
|
||||||
|
sleep(3);
|
||||||
|
$this->assertNotDetected($browser);
|
||||||
|
$browser->waitForText("Store", 30, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function signin(Browser $browser)
|
||||||
|
{
|
||||||
|
$browser->visit("https://store.epicgames.com/login?state=%2Fen-US%2F");
|
||||||
|
sleep(5);
|
||||||
|
$this->assertNotDetected($browser);
|
||||||
|
$browser->waitForText("Sign In", 30, true);
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
|
$jobInfos = JobInfo::where("job_id", $this->jobId)->get();
|
||||||
|
$email = $jobInfos->where("key", "email")->first()->value;
|
||||||
|
$password = $jobInfos->where("key", "password")->first()->value;
|
||||||
|
$browser->within(new EpicGamesLogin, function (Browser $browser) use ($email, $password) {
|
||||||
|
$browser->fillForm($email, $password);
|
||||||
|
});
|
||||||
|
|
||||||
|
sleep(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFreeGames(Browser $browser)
|
||||||
|
{
|
||||||
|
$browser->visit('https://www.epicgames.com/store/en-US/free-games');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function removePopups(Browser $browser)
|
||||||
|
{
|
||||||
|
// $browser->script('document.querySelector("div.app-modal")[0].remove();');
|
||||||
|
// $browser->driver->executeScript('document.querySelector("div.app-modal")[0].remove();');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function assertNotDetected(Browser $browser)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$browser->waitForText("One more step", 10, true);
|
||||||
|
} catch (Exception $_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Exception("Détecté par cloudflare");
|
||||||
|
}
|
||||||
|
}
|
@ -21,26 +21,27 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
|
|||||||
{
|
{
|
||||||
private const STEAM_LOGIN_THRESHOLD = 5 * 60; // 5 minutes
|
private const STEAM_LOGIN_THRESHOLD = 5 * 60; // 5 minutes
|
||||||
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
|
private const APPROXIMATIVE_RUNNING_MINUTES = 2;
|
||||||
|
private const WEBSITE_URL = "https://hellcase.com";
|
||||||
|
|
||||||
private JobRun $jobRun;
|
private JobRun $jobRun;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
Log::info("Constructing HellcaseJob");
|
Log::info("Constructing " . self::class);
|
||||||
parent::__construct(2);
|
parent::__construct(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run(Browser $browser): ?JobRun
|
public function run(Browser $browser): ?JobRun
|
||||||
{
|
{
|
||||||
Log::info("Running HellcaseJob");
|
Log::info("Running " . self::class);
|
||||||
$this->jobRun = new JobRun([
|
$this->jobRun = new JobRun([
|
||||||
"job_id" => $this->jobId,
|
"job_id" => $this->jobId,
|
||||||
"success" => false,
|
"success" => false,
|
||||||
]);
|
]);
|
||||||
$this->jobRun->save();
|
$this->jobRun->save();
|
||||||
|
|
||||||
$browser->visit('https://hellcase.com');
|
$browser->visit(self::WEBSITE_URL);
|
||||||
$browser->waitForText("Store", 30, true);
|
$browser->waitForText("CASES", 30, true);
|
||||||
$this->removePopups($browser);
|
$this->removePopups($browser);
|
||||||
sleep(5);
|
sleep(5);
|
||||||
$this->signin($browser);
|
$this->signin($browser);
|
||||||
@ -50,7 +51,7 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
|
|||||||
$this->jobRun->success = true;
|
$this->jobRun->success = true;
|
||||||
$this->jobRun->save();
|
$this->jobRun->save();
|
||||||
|
|
||||||
Log::info("HellcaseJob run ended");
|
Log::info(self::class . " run ended");
|
||||||
|
|
||||||
return $this->jobRun;
|
return $this->jobRun;
|
||||||
}
|
}
|
||||||
@ -61,7 +62,7 @@ class HellcaseJob extends BrowserJob implements ShouldBeUniqueUntilProcessing
|
|||||||
public function runTest(Browser $browser): ?JobRun
|
public function runTest(Browser $browser): ?JobRun
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$browser->visit('https://hellcase.com');
|
$browser->visit(self::WEBSITE_URL);
|
||||||
$browser->waitForText("CASES", 30, true);
|
$browser->waitForText("CASES", 30, true);
|
||||||
$this->removePopups($browser);
|
$this->removePopups($browser);
|
||||||
sleep(2);
|
sleep(2);
|
||||||
|
35
app/Jobs/PruneOldJobRuns.php
Normal file
35
app/Jobs/PruneOldJobRuns.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Models\Job;
|
||||||
|
use App\Models\JobRun;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Queue\Queueable;
|
||||||
|
|
||||||
|
class PruneOldJobRuns implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*/
|
||||||
|
public function handle(): void
|
||||||
|
{
|
||||||
|
// For each job, keep only the last N runs
|
||||||
|
foreach (Job::all() as $job) {
|
||||||
|
$job->jobRuns()
|
||||||
|
->orderByDesc('id')
|
||||||
|
->skip(config('jobs.pruneOldJobRuns.max_runs_per_job'))
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -75,6 +75,10 @@ return [
|
|||||||
|
|
||||||
'links' => [
|
'links' => [
|
||||||
public_path('storage') => storage_path('app/public'),
|
public_path('storage') => storage_path('app/public'),
|
||||||
|
public_path('console') => base_path('app/Browser/console'),
|
||||||
|
public_path('downloads') => base_path('app/Browser/downloads'),
|
||||||
|
public_path('screenshots') => base_path('app/Browser/screenshots'),
|
||||||
|
public_path('source') => base_path('app/Browser/source'),
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
20
config/jobs.php
Normal file
20
config/jobs.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Laravel\Telescope\Http\Middleware\Authorize;
|
||||||
|
use Laravel\Telescope\Watchers;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove old job runs from the database.
|
||||||
|
*/
|
||||||
|
'pruneOldJobRuns' => [
|
||||||
|
'enabled' => true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How many job runs a job can keep before we start pruning old ones.
|
||||||
|
*/
|
||||||
|
'max_runs_per_job' => 50,
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
44
database/migrations/2025_02_27_180246_add_epic_games_job.php
Normal file
44
database/migrations/2025_02_27_180246_add_epic_games_job.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$jobId = 3;
|
||||||
|
\App\Models\Job::forcecreate([
|
||||||
|
'id' => $jobId,
|
||||||
|
'name' => 'Jeu gratuit Epic Games',
|
||||||
|
'description' => 'Prends le jeu gratuit Epic games. Tourne tous les jours.',
|
||||||
|
]);
|
||||||
|
\App\Models\JobInfo::forceCreate([
|
||||||
|
"key" => "epicgames_account_email",
|
||||||
|
"name" => "E-mail",
|
||||||
|
"description" => "L'adresse e-mail utilisée pour votre compte Epic Games.",
|
||||||
|
"job_info_type_id" => 2,
|
||||||
|
"job_id" => $jobId,
|
||||||
|
], );
|
||||||
|
\App\Models\JobInfo::forceCreate([
|
||||||
|
"key" => "epicgames_account_password",
|
||||||
|
"name" => "Mot de passe",
|
||||||
|
"description" => "Le mot de passe utilisé pour votre compte Epic Games.",
|
||||||
|
"job_info_type_id" => 3,
|
||||||
|
"job_id" => $jobId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
\App\Models\Job::find(3)->delete();
|
||||||
|
\App\Models\JobInfo::where('job_id', 3)->delete();
|
||||||
|
}
|
||||||
|
};
|
1
public/console
Symbolic link
1
public/console
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/home/ninluc/Documents/codage/DatBrowser/app/Browser/console
|
1
public/downloads
Symbolic link
1
public/downloads
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/home/ninluc/Documents/codage/DatBrowser/app/Browser/downloads
|
1
public/screenshots
Symbolic link
1
public/screenshots
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/home/ninluc/Documents/codage/DatBrowser/app/Browser/screenshots
|
1
public/source
Symbolic link
1
public/source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/home/ninluc/Documents/codage/DatBrowser/app/Browser/source
|
@ -11,7 +11,7 @@ const jobs = ref<Job[]>([]);
|
|||||||
|
|
||||||
async function fetchJobs() {
|
async function fetchJobs() {
|
||||||
let jobsRaw = await httpApi<Job[]>("/jobs");
|
let jobsRaw = await httpApi<Job[]>("/jobs");
|
||||||
jobs.value = jobsRaw.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
jobs.value = jobsRaw.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(fetchJobs);
|
onMounted(fetchJobs);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Browser\Jobs\EpicGames\EpicGamesJob;
|
||||||
use App\Browser\Jobs\Hellcase\HellcaseJob;
|
use App\Browser\Jobs\Hellcase\HellcaseJob;
|
||||||
use App\Models\Job;
|
use App\Jobs\PruneOldJobRuns;
|
||||||
use App\Services\BrowserJobsInstances;
|
use App\Services\BrowserJobsInstances;
|
||||||
use Illuminate\Foundation\Inspiring;
|
use Illuminate\Foundation\Inspiring;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
@ -13,6 +14,14 @@ Artisan::command('inspire', function () {
|
|||||||
// Telescope
|
// Telescope
|
||||||
Schedule::command('telescope:prune')->monthly();
|
Schedule::command('telescope:prune')->monthly();
|
||||||
|
|
||||||
|
// Prune old job runs
|
||||||
|
Schedule::job(new PruneOldJobRuns)->monthly()->onOneServer()->withoutOverlapping()->name('prune-old-job-runs')->description('Prune old job runs')->skip(function () {
|
||||||
|
return !config('jobs.pruneOldJobRuns.enabled');
|
||||||
|
});
|
||||||
|
|
||||||
// Jobs
|
// Jobs
|
||||||
Schedule::job(new HellcaseJob)->daily()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
|
Schedule::job(new HellcaseJob)->daily()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
|
||||||
// Schedule::job(new HellcaseJob)->everyMinute()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
|
// Schedule::job(new HellcaseJob)->everyMinute()->onOneServer()->withoutOverlapping()->name('hellcase')->description('Hellcase job');
|
||||||
|
|
||||||
|
Schedule::job(new EpicGamesJob())->daily()->onOneServer()->withoutOverlapping()->name('epic-games')->description('Epic Games job');
|
||||||
|
|
||||||
|
4
todo.md
4
todo.md
@ -7,10 +7,10 @@
|
|||||||
- → Notification
|
- → Notification
|
||||||
- Ou ajouter des images base64 dans les jobRun
|
- Ou ajouter des images base64 dans les jobRun
|
||||||
- Risque de devenir volumineux
|
- Risque de devenir volumineux
|
||||||
- Sauf avec le jobqui enlève les vieilles jobRun
|
- Sauf avec le job qui enlève les vieilles jobRun
|
||||||
- Notification live websocket
|
- Notification live websocket
|
||||||
|
- Websocket installé
|
||||||
- Serveur php plus propre (nginx, apache, n'importe)
|
- Serveur php plus propre (nginx, apache, n'importe)
|
||||||
- Job qui supprime les vieilles JobRun
|
|
||||||
- Epic games
|
- Epic games
|
||||||
|
|
||||||
## Pour deploy Lama
|
## Pour deploy Lama
|
||||||
|
Reference in New Issue
Block a user