diff --git a/Dockerfile b/Dockerfile index 930f6a4..0764b62 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,20 @@ RUN set -eux; \ ENV COMPOSER_ALLOW_SUPERUSER=1 ###> recipes ### +###> symfony/panther ### +# Chromium and ChromeDriver +ENV PANTHER_NO_SANDBOX 1 +# Not mandatory, but recommended +ENV PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage' +RUN apt-get update && apt-get install -y --no-install-recommends chromium chromium-driver && rm -rf /var/lib/apt/lists/* + +# Firefox and geckodriver +#ARG GECKODRIVER_VERSION=0.34.0 +#RUN apt-get update && apt-get install -y --no-install-recommends firefox && rm -rf /var/lib/apt/lists/* +#RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-aarch64.tar.gz; \ +# tar -zxf geckodriver-v$GECKODRIVER_VERSION-aarch64.tar.gz -C /usr/bin; \ +# rm geckodriver-v$GECKODRIVER_VERSION-aarch64.tar.gz +###< symfony/panther ### ###> doctrine/doctrine-bundle ### RUN install-php-extensions pdo_pgsql ###< doctrine/doctrine-bundle ### diff --git a/Makefile b/Makefile index 0e37c0c..9abd6c1 100644 --- a/Makefile +++ b/Makefile @@ -141,6 +141,12 @@ stimulus: ## Create a new stimulus controller consume: ## Consume messages @$(SYMFONY) messenger:consume async -vv +consume-schedule: ## Consume schedule messages + @$(SYMFONY) messenger:consume async -vv scheduler_default + +message: ## Create a new message and handler + @$(SYMFONY) make:message + ## —— Webpack Encore ————————————————————————————————————————————————————————————— npm-install: ## Install npm dependencies @$(DOCKER_COMP) exec node npm install --force diff --git a/assets/controllers/toolbar_controller.js b/assets/controllers/toolbar_controller.js index 0242c4a..31e591b 100644 --- a/assets/controllers/toolbar_controller.js +++ b/assets/controllers/toolbar_controller.js @@ -3,7 +3,7 @@ import { Controller } from "@hotwired/stimulus" import { visit } from "@hotwired/turbo" export default class extends Controller { - static targets = ["dropdown", "icon"] + static targets = ["dropdown", "icon", "text"] static values = { currentSort: String, currentOrder: String, @@ -51,6 +51,40 @@ export default class extends Controller { console.log("Importing..."); } + monitoring(event){ + const mangaId = event.currentTarget.dataset.mangaid; + const currentTarget = event.currentTarget; + + const url = `/toggle_monitored`; + + fetch(url, { + method: 'POST', + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ mangaId: mangaId }) + }) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }).then(data => { + if(data.isMonitored === true){ + currentTarget.classList.remove('text-white'); + currentTarget.classList.add('text-green-500'); + this.textTarget.innerHTML = "Monitored"; + }else if(data.isMonitored === false){ + currentTarget.classList.remove('text-green-500'); + currentTarget.classList.add('text-white'); + this.textTarget.innerHTML = "Monitoring"; + } + // console.log(data.isMonitored); + }); + + } + editMangas() { console.log("Editing mangas..."); } diff --git a/composer.json b/composer.json index 554973a..1db3f69 100644 --- a/composer.json +++ b/composer.json @@ -35,9 +35,11 @@ "symfony/messenger": "7.0.*", "symfony/mime": "7.0.*", "symfony/monolog-bundle": "^3.10", + "symfony/panther": "^2.1", "symfony/property-access": "7.0.*", "symfony/property-info": "7.0.*", "symfony/runtime": "7.0.*", + "symfony/scheduler": "7.0.*", "symfony/security-bundle": "7.0.*", "symfony/serializer": "7.0.*", "symfony/stimulus-bundle": "^2.17", @@ -101,6 +103,7 @@ } }, "require-dev": { + "dbrekelmans/bdi": "^1.3", "doctrine/doctrine-fixtures-bundle": "^3.5", "friendsofphp/php-cs-fixer": "^3.48", "mtdowling/jmespath.php": "^2.7", diff --git a/composer.lock b/composer.lock index a5472ee..3d6d6dd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "821989b8a12af699869b3885cb6c3660", + "content-hash": "2533b3293b9694632fddb7de78675af4", "packages": [ { "name": "api-platform/core", @@ -2029,6 +2029,73 @@ ], "time": "2024-04-11T23:07:54+00:00" }, + { + "name": "masterminds/html5", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + }, + "time": "2023-05-10T11:58:31+00:00" + }, { "name": "monolog/monolog", "version": "3.5.0", @@ -2192,6 +2259,72 @@ }, "time": "2023-11-30T16:41:19+00:00" }, + { + "name": "php-webdriver/webdriver", + "version": "1.15.1", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "cd52d9342c5aa738c2e75a67e47a1b6df97154e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/cd52d9342c5aa738c2e75a67e47a1b6df97154e8", + "reference": "cd52d9342c5aa738c2e75a67e47a1b6df97154e8", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^7.3 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^5.0 || ^6.0 || ^7.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.20.0", + "ondram/ci-detector": "^4.0", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^5.0 || ^6.0" + }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Exception/TimeoutException.php" + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", + "homepage": "https://github.com/php-webdriver/php-webdriver", + "keywords": [ + "Chromedriver", + "geckodriver", + "php", + "selenium", + "webdriver" + ], + "support": { + "issues": "https://github.com/php-webdriver/php-webdriver/issues", + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.15.1" + }, + "time": "2023-10-20T12:21:20+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -3038,6 +3171,74 @@ ], "time": "2024-01-23T15:02:46+00:00" }, + { + "name": "symfony/browser-kit", + "version": "v7.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "725d5b15681685ac17b20b575254c75639722488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/725d5b15681685ac17b20b575254c75639722488", + "reference": "725d5b15681685ac17b20b575254c75639722488", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/dom-crawler": "^6.4|^7.0" + }, + "require-dev": { + "symfony/css-selector": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/browser-kit/tree/v7.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T15:02:46+00:00" + }, { "name": "symfony/cache", "version": "v7.0.2", @@ -3777,6 +3978,73 @@ ], "time": "2024-05-31T14:55:39+00:00" }, + { + "name": "symfony/dom-crawler", + "version": "v7.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6cb272cbec4dc7a30a853d2931766b03bea92dda", + "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda", + "shasum": "" + }, + "require": { + "masterminds/html5": "^2.6", + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v7.0.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-02-12T11:15:03+00:00" + }, { "name": "symfony/dotenv", "version": "v7.0.2", @@ -5501,6 +5769,95 @@ ], "time": "2023-08-08T10:20:21+00:00" }, + { + "name": "symfony/panther", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/panther.git", + "reference": "ef9a6f2393ac9679af03a93d3f508e4aa65c15b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/panther/zipball/ef9a6f2393ac9679af03a93d3f508e4aa65c15b5", + "reference": "ef9a6f2393ac9679af03a93d3f508e4aa65c15b5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": ">=8.0", + "php-webdriver/webdriver": "^1.8.2", + "symfony/browser-kit": "^5.3 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.3 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.4 || ^3", + "symfony/dom-crawler": "^5.3 || ^6.0 || ^7.0", + "symfony/http-client": "^5.3 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.3 || ^6.0 || ^7.0", + "symfony/process": "^5.3 || ^6.0 || ^7.0" + }, + "require-dev": { + "symfony/css-selector": "^5.3 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^5.3 || ^6.0 || ^7.0", + "symfony/mime": "^5.3 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^5.3 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Panther\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com", + "homepage": "https://dunglas.fr" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A browser testing and web scraping library for PHP and Symfony.", + "homepage": "https://dunglas.fr", + "keywords": [ + "e2e", + "scraping", + "selenium", + "symfony", + "testing", + "webdriver" + ], + "support": { + "issues": "https://github.com/symfony/panther/issues", + "source": "https://github.com/symfony/panther/tree/v2.1.1" + }, + "funding": [ + { + "url": "https://www.panthera.org/donate", + "type": "custom" + }, + { + "url": "https://github.com/dunglas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/panther", + "type": "tidelift" + } + ], + "time": "2023-12-03T22:17:31+00:00" + }, { "name": "symfony/password-hasher", "version": "v7.0.3", @@ -6069,6 +6426,67 @@ ], "time": "2023-08-16T06:22:46+00:00" }, + { + "name": "symfony/process", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", + "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.0.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-12-24T09:15:37+00:00" + }, { "name": "symfony/property-access", "version": "v7.0.3", @@ -6388,6 +6806,86 @@ ], "time": "2023-10-20T16:35:23+00:00" }, + { + "name": "symfony/scheduler", + "version": "v7.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/scheduler.git", + "reference": "91a0c028f2183b111e92e32061bb9db9a9599133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/scheduler/zipball/91a0c028f2183b111e92e32061bb9db9a9599133", + "reference": "91a0c028f2183b111e92e32061bb9db9a9599133", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/clock": "^6.4|^7.0" + }, + "require-dev": { + "dragonmantank/cron-expression": "^3.1", + "symfony/cache": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Scheduler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sergey Rabochiy", + "email": "upyx.00@gmail.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides scheduling through Symfony Messenger", + "homepage": "https://symfony.com", + "keywords": [ + "cron", + "schedule", + "scheduler" + ], + "support": { + "source": "https://github.com/symfony/scheduler/tree/v7.0.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-02T15:49:03+00:00" + }, { "name": "symfony/security-bundle", "version": "v7.0.3", @@ -8697,6 +9195,55 @@ ], "time": "2022-02-25T21:32:43+00:00" }, + { + "name": "dbrekelmans/bdi", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/dbrekelmans/bdi.git", + "reference": "46e5f8ec09bac842ab569c02e64476408aa46ef8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dbrekelmans/bdi/zipball/46e5f8ec09bac842ab569c02e64476408aa46ef8", + "reference": "46e5f8ec09bac842ab569c02e64476408aa46ef8", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-zip": "*", + "ext-zlib": "*", + "php": "^8.1" + }, + "bin": [ + "bdi", + "bdi.phar" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniël Brekelmans", + "homepage": "https://github.com/dbrekelmans" + }, + { + "name": "Contributors", + "homepage": "https://github.com/dbrekelmans/bdi/graphs/contributors" + } + ], + "description": "PHAR distribution of dbrekelmans/browser-driver-installer.", + "homepage": "https://github.com/dbrekelmans/bdi", + "keywords": [ + "browser-driver-installer" + ], + "support": { + "source": "https://github.com/dbrekelmans/bdi/tree/1.3.0" + }, + "time": "2024-02-22T15:29:35+00:00" + }, { "name": "doctrine/data-fixtures", "version": "1.7.0", @@ -9022,73 +9569,6 @@ ], "time": "2024-01-19T21:44:39+00:00" }, - { - "name": "masterminds/html5", - "version": "2.8.1", - "source": { - "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Masterminds\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Butcher", - "email": "technosophos@gmail.com" - }, - { - "name": "Matt Farina", - "email": "matt@mattfarina.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - } - ], - "description": "An HTML5 parser and serializer.", - "homepage": "http://masterminds.github.io/html5-php", - "keywords": [ - "HTML5", - "dom", - "html", - "parser", - "querypath", - "serializer", - "xml" - ], - "support": { - "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" - }, - "time": "2023-05-10T11:58:31+00:00" - }, { "name": "mtdowling/jmespath.php", "version": "2.7.0", @@ -10864,74 +11344,6 @@ ], "time": "2023-02-07T11:34:05+00:00" }, - { - "name": "symfony/browser-kit", - "version": "v7.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/browser-kit.git", - "reference": "725d5b15681685ac17b20b575254c75639722488" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/725d5b15681685ac17b20b575254c75639722488", - "reference": "725d5b15681685ac17b20b575254c75639722488", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/dom-crawler": "^6.4|^7.0" - }, - "require-dev": { - "symfony/css-selector": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/mime": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\BrowserKit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/browser-kit/tree/v7.0.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-23T15:02:46+00:00" - }, { "name": "symfony/css-selector", "version": "v7.0.3", @@ -10997,73 +11409,6 @@ ], "time": "2024-01-23T15:02:46+00:00" }, - { - "name": "symfony/dom-crawler", - "version": "v7.0.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6cb272cbec4dc7a30a853d2931766b03bea92dda", - "reference": "6cb272cbec4dc7a30a853d2931766b03bea92dda", - "shasum": "" - }, - "require": { - "masterminds/html5": "^2.6", - "php": ">=8.2", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Eases DOM navigation for HTML and XML documents", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.0.4" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-02-12T11:15:03+00:00" - }, { "name": "symfony/maker-bundle", "version": "v1.52.0", @@ -11237,67 +11582,6 @@ ], "time": "2024-02-08T19:22:56+00:00" }, - { - "name": "symfony/process", - "version": "v7.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", - "reference": "acd3eb5cb02382c1cb0287ba29b2908cc6ffa83a", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/process/tree/v7.0.2" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-12-24T09:15:37+00:00" - }, { "name": "symfony/web-profiler-bundle", "version": "v7.0.3", diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 8005ebd..9e6fddf 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -16,6 +16,7 @@ framework: # Route your messages to the transports 'App\Message\DownloadChapter': async 'App\Message\RefreshMetadata': async + App\Message\RefreshAndDownloadChapters: async # when@test: # framework: diff --git a/config/services.yaml b/config/services.yaml index 5dc95d6..f6bfd50 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -4,6 +4,7 @@ # Put parameters here that don't need to change on each machine where the app is deployed # https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration parameters: + cache_adapter: 'cache.adapter.filesystem' services: # default configuration for services in *this* file diff --git a/migrations/Version20240717211909.php b/migrations/Version20240717211909.php new file mode 100644 index 0000000..1d76943 --- /dev/null +++ b/migrations/Version20240717211909.php @@ -0,0 +1,32 @@ +addSql('ALTER TABLE manga ADD monitored BOOLEAN NOT NULL default FALSE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('ALTER TABLE manga DROP monitored'); + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e273dc1..73f7b8b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,6 +16,7 @@ + diff --git a/src/Controller/MangaController.php b/src/Controller/MangaController.php index 3f3b71c..aa0fc3c 100644 --- a/src/Controller/MangaController.php +++ b/src/Controller/MangaController.php @@ -81,7 +81,7 @@ class MangaController extends AbstractController return $this->render('manga/show_chapters.html.twig', [ 'manga' => $manga, - 'toolbar' => $this->toolbarFactory->createToolbar('chapter_list', ['mangaId' => $manga->getId()])->getGroups(), + 'toolbar' => $this->toolbarFactory->createToolbar('chapter_list', ['mangaId' => $manga->getId(), 'isMonitored' => (int) $manga->isMonitored()])->getGroups(), ]); } @@ -388,6 +388,22 @@ class MangaController extends AbstractController return new JsonResponse(['success' => 'Metadata refresh started...'], 200); } + #[Route('/toggle_monitored', name: 'toggle_monitored')] + public function toogleMonitored(Request $request): JsonResponse + { + $id = json_decode($request->getContent(), true)['mangaId']; + $manga = $this->mangaRepository->find($id); + if (!$manga) { + return new JsonResponse(['error' => 'Manga Not Found.'], 400); + } + + $manga->setMonitored(!$manga->isMonitored()); + $this->entityManager->persist($manga); + $this->entityManager->flush(); + + return new JsonResponse(['success' => 'Monitored status updated.', 'isMonitored' => $manga->isMonitored()], 200); + } + private function isFullVolume(Chapter $chapter): bool { $volumeChapters = $this->chapterRepository->findBy([ diff --git a/src/Entity/Manga.php b/src/Entity/Manga.php index 72a271a..41cf847 100644 --- a/src/Entity/Manga.php +++ b/src/Entity/Manga.php @@ -56,6 +56,9 @@ class Manga #[ORM\Column(length: 255, nullable: true)] private ?string $thumbnailUrl = null; + #[ORM\Column] + private ?bool $monitored = null; + public function __construct() { $this->chapters = new ArrayCollection(); @@ -250,4 +253,16 @@ class Manga return $this; } + + public function isMonitored(): ?bool + { + return $this->monitored; + } + + public function setMonitored(bool $monitored): static + { + $this->monitored = $monitored; + + return $this; + } } diff --git a/src/Manager/Toolbar/Definition/ChapterListToolbar.php b/src/Manager/Toolbar/Definition/ChapterListToolbar.php index 654ad65..928b3ea 100644 --- a/src/Manager/Toolbar/Definition/ChapterListToolbar.php +++ b/src/Manager/Toolbar/Definition/ChapterListToolbar.php @@ -9,6 +9,9 @@ class ChapterListToolbar extends Toolbar { public function __construct(array $contextData = []) { + $monitoredTitle = $contextData['isMonitored'] ? 'Monitored' : 'Monitoring'; + $monitoredColor = $contextData['isMonitored'] ? 'text-green-500' : 'text-white'; + $this ->addToLeftGroup(new ToolbarButton('arrows-rotate', 'Refresh metadata', 'toolbar#refreshMetadata', $contextData)) ->addToLeftGroup(new ToolbarDivider()) @@ -17,7 +20,7 @@ class ChapterListToolbar extends Toolbar ->addToLeftGroup(new ToolbarButton('history', 'History', 'toolbar#history', $contextData)) - ->addToRightGroup(new ToolbarButton('bookmark', 'Monitoring', 'toolbar#monitoring', $contextData)) + ->addToRightGroup(new ToolbarButton('bookmark', $monitoredTitle, 'toolbar#monitoring', array_merge($contextData, ['buttonClass' => $monitoredColor]))) ->addToRightGroup(new ToolbarButton('wrench', 'Edit', 'toolbar#editManga', $contextData)) ->addToRightGroup(new ToolbarButton('trash-can', 'Delete', 'toolbar#deleteManga', $contextData)) ->addToRightGroup(new ToolbarDivider()) diff --git a/src/Manager/Toolbar/Definition/MangaListToolbar.php b/src/Manager/Toolbar/Definition/MangaListToolbar.php index b827b6c..7f3c561 100644 --- a/src/Manager/Toolbar/Definition/MangaListToolbar.php +++ b/src/Manager/Toolbar/Definition/MangaListToolbar.php @@ -10,10 +10,10 @@ class MangaListToolbar extends Toolbar { public function __construct(array $contextData = []) { - $this->addToLeftGroup(new ToolbarButton('arrows-rotate', 'Refresh', 'refreshMetadata')) - ->addToLeftGroup(new ToolbarButton('search', 'Search', 'searchLastChapter')) + $this->addToLeftGroup(new ToolbarButton('arrows-rotate', 'Refresh', 'toolbar#refreshMetadata')) + ->addToLeftGroup(new ToolbarButton('search', 'Search', 'toolbar#searchLastChapter')) - ->addToRightGroup(new ToolbarButton('th-large', 'Options', 'options')) + ->addToRightGroup(new ToolbarButton('th-large', 'Options', 'toolbar#options')) ->addToRightGroup(new ToolbarDivider()) ->addToRightGroup(new ToolbarDropdown('eye', 'View', 'changeView', [ ['text' => 'Poster View', 'action' => 'changeView', 'data' => ['view' => 'poster']], diff --git a/src/Message/RefreshAndDownloadChapters.php b/src/Message/RefreshAndDownloadChapters.php new file mode 100644 index 0000000..88648e4 --- /dev/null +++ b/src/Message/RefreshAndDownloadChapters.php @@ -0,0 +1,23 @@ +name = $name; +// } + +// public function getName(): string +// { +// return $this->name; +// } +} diff --git a/src/MessageHandler/RefreshAndDownloadChaptersHandler.php b/src/MessageHandler/RefreshAndDownloadChaptersHandler.php new file mode 100644 index 0000000..323d2e6 --- /dev/null +++ b/src/MessageHandler/RefreshAndDownloadChaptersHandler.php @@ -0,0 +1,61 @@ +mangaRepository->findBy(['monitored' => true]); + + foreach ($mangas as $manga) { + $chapters = $this->refreshMangas($manga); + + if (empty($chapters)) { + continue; + } + + /** @var Chapter $chapter */ + foreach ($chapters as $chapter) { + $this->bus->dispatch(new DownloadChapter($chapter->getId())); + } + } + + } + + private function refreshMangas(Manga $manga): array + { + $lastChapters = $this->mangadexProvider->addAllChaptersToManga($manga); + + foreach ($lastChapters as $chapter) { + $this->entityManager->persist($chapter); + } + + $this->entityManager->persist($manga); + $this->entityManager->flush(); + + return $lastChapters; + } +} diff --git a/src/Scheduler/MainSchedule.php b/src/Scheduler/MainSchedule.php new file mode 100644 index 0000000..80793c6 --- /dev/null +++ b/src/Scheduler/MainSchedule.php @@ -0,0 +1,27 @@ +add( + RecurringMessage::every('6 hours', new RefreshAndDownloadChapters()) + ) + ->stateful($this->cache); + } +} diff --git a/src/Service/MangaScraperService.php b/src/Service/MangaScraperService.php index 20186f1..ba4db85 100644 --- a/src/Service/MangaScraperService.php +++ b/src/Service/MangaScraperService.php @@ -12,9 +12,6 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\RequestException; use Symfony\Component\DomCrawler\Crawler; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\Exception\HttpException; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Matcher\UrlMatcher; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Route; diff --git a/symfony.lock b/symfony.lock index 3ce88f9..ea48aa6 100644 --- a/symfony.lock +++ b/symfony.lock @@ -178,6 +178,15 @@ "config/packages/monolog.yaml" ] }, + "symfony/panther": { + "version": "2.1", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.0", + "ref": "673836afb0eac2b0ec36c44f2ff0379e5a4b2177" + } + }, "symfony/phpunit-bridge": { "version": "7.0", "recipe": { diff --git a/templates/components/DropdownMenu.html.twig b/templates/components/DropdownMenu.html.twig index 04b2d88..723b2a2 100644 --- a/templates/components/DropdownMenu.html.twig +++ b/templates/components/DropdownMenu.html.twig @@ -6,7 +6,7 @@ text="{{ text }}" action="dropdown#toggle" data-dropdown-target="button" - controller="dropdown" + controller="" />