- Monitoring chapters
- possibilities for ToolBarButton.html.twig to have tailwind classes see ChapterListToolbar.php
- Makefile scheduler command
- Makefile make:message command
This commit is contained in:
Jérémy Guillot
2024-07-20 19:40:48 +02:00
parent 7fc2f15f6b
commit ff59aa5d77
21 changed files with 818 additions and 283 deletions

View File

@@ -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 ###

View File

@@ -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

View File

@@ -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...");
}

View File

@@ -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",

812
composer.lock generated
View File

@@ -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",

View File

@@ -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:

View File

@@ -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

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240717211909 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->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');
}
}

View File

@@ -16,6 +16,7 @@
</testsuite>
</testsuites>
<extensions>
<extension class="Symfony\Component\Panther\ServerExtension" />
<bootstrap class="Zenstruck\Browser\Test\BrowserExtension"/>
</extensions>
<source>

View File

@@ -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([

View File

@@ -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;
}
}

View File

@@ -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())

View File

@@ -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']],

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Message;
final class RefreshAndDownloadChapters
{
/*
* Add whatever properties and methods you need
* to hold the data for this message class.
*/
// private $name;
// public function __construct(string $name)
// {
// $this->name = $name;
// }
// public function getName(): string
// {
// return $this->name;
// }
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\MessageHandler;
use App\Entity\Chapter;
use App\Entity\Manga;
use App\Message\DownloadChapter;
use App\Message\RefreshAndDownloadChapters;
use App\Repository\MangaRepository;
use App\Service\MangadexProvider;
use App\Service\NotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Messenger\MessageBusInterface;
#[AsMessageHandler]
final readonly class RefreshAndDownloadChaptersHandler
{
public function __construct(
private MangaRepository $mangaRepository,
private MangadexProvider $mangadexProvider,
private EntityManagerInterface $entityManager,
private MessageBusInterface $bus
)
{
}
public function __invoke(RefreshAndDownloadChapters $message): void
{
$mangas = $this->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;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Scheduler;
use App\Message\RefreshAndDownloadChapters;
use Symfony\Component\Scheduler\Attribute\AsSchedule;
use Symfony\Component\Scheduler\RecurringMessage;
use Symfony\Component\Scheduler\Schedule;
use Symfony\Component\Scheduler\ScheduleProviderInterface;
use Symfony\Contracts\Cache\CacheInterface;
#[AsSchedule]
class MainSchedule implements ScheduleProviderInterface
{
public function __construct(private CacheInterface $cache)
{
}
#[\Override] public function getSchedule(): Schedule
{
return (new Schedule())->add(
RecurringMessage::every('6 hours', new RefreshAndDownloadChapters())
)
->stateful($this->cache);
}
}

View File

@@ -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;

View File

@@ -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": {

View File

@@ -6,7 +6,7 @@
text="{{ text }}"
action="dropdown#toggle"
data-dropdown-target="button"
controller="dropdown"
controller=""
/>
<div class="absolute left-0 mt-2 w-max z-10 bg-gray-800 rounded-sm shadow-lg hidden"
data-dropdown-target="menu">

View File

@@ -1,21 +1,25 @@
{# templates/components/ToolbarButton.html.twig #}
{% set buttonAttributes = {} %}
{% set buttonClass = 'text-white' %}
{% if data is defined and data is not empty %}
{% for key, value in data %}
{% set dataAttribute = 'data-' ~ key|replace({'_': '-'})|lower ~ '=' ~ value %}
{% set buttonAttributes = buttonAttributes|merge({dataAttribute}) %}
{% set dataKey = 'data-' ~ key|replace({'_': '-'})|lower %}
{% set buttonAttributes = buttonAttributes|merge({ (dataKey): value }) %}
{% endfor %}
{% if data['buttonClass'] is defined %}
{% set buttonClass = data['buttonClass'] %}
{% endif %}
{% endif %}
<div {{ attributes }}>
<button class="flex flex-col justify-around min-h-14 w-min ml-4 items-center text-white group"
{% if action %}
<button class="flex flex-col justify-around min-h-14 w-min ml-4 items-center group {{ buttonClass }}"
data-controller="{{ controller }}"
data-action="{{ action }}"
{% endif %}
{{ buttonAttributes|join(' ') }}
{% for attrName, attrValue in buttonAttributes %}
{{ attrName }}="{{ attrValue }}"
{% endfor %}
>
<i data-toolbar-target="icon" class="fas fa-{{ icon }} text-xl group-hover:text-green-500"></i>
<span class="text-xs">{{ text }}</span>
<i data-{{ controller }}-target="icon" class="fas fa-{{ icon }} text-xl group-hover:text-green-500"></i>
<span data-{{ controller }}-target="text" class="text-xs">{{ text }}</span>
</button>
</div>

View File

@@ -4,10 +4,12 @@
<div class="flex mr-2 items-center">
{% for element in toolbar.leftGroup %}
{% if element.type == 'button' %}
{% set actionParts = element.action|split('#') %}
<twig:ToolBarButton
icon="{{ element.icon }}"
text="{{ element.text }}"
action="{{ element.action }}"
controller="{{ actionParts[0] }}"
data="{{ element.additionalProperties.data }}"
/>
{% elseif element.type == 'divider' %}
@@ -25,10 +27,12 @@
<div class="flex mr-2 items-center">
{% for element in toolbar.rightGroup %}
{% if element.type == 'button' %}
{% set actionParts = element.action|split('#') %}
<twig:ToolBarButton
icon="{{ element.icon }}"
text="{{ element.text }}"
action="{{ element.action }}"
controller="{{ actionParts[0] }}"
data="{{ element.additionalProperties.data }}"
/>
{% elseif element.type == 'divider' %}