diff --git a/.env b/.env index 6737c6d..a59ee2e 100644 --- a/.env +++ b/.env @@ -17,6 +17,7 @@ ###> symfony/framework-bundle ### APP_ENV=dev APP_SECRET=EDITME +APP_KEY=EDITME ###< symfony/framework-bundle ### ###> doctrine/doctrine-bundle ### @@ -45,22 +46,81 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###< symfony/crowdin-translation-provider ### # YGGtracker -APP_VERSION='2.0.0' +# Application version, used for API and media cache +APP_VERSION=2.6.2 + +# Application name APP_NAME=YGGtracker +# Default locale APP_LOCALE=en -APP_LOCALES=en|cs|eo|fr|ka|de|he|it|lv|pl|pt|ru|es|uk +# Supported locales for interface and content filters +APP_LOCALES=en|cs|nl|eo|fr|ja|ka|de|he|it|lv|pl|pt|ru|es|uk + +# Content categories, lowercase, enabled by default for new users +# src/Twig/AppExtension.php:transCategory +APP_CATEGORIES=movie|series|tv|animation|music|game|audiobook|podcast|book|archive|picture|software|other + +# Items per page on pagination APP_PAGINATION=10 +# Default application theme APP_THEME=default + +# Additional themes, stored in /src/templates, /public/asset APP_THEMES=default -APP_SENSITIVE=0 -APP_APPROVED=0 +# Default sensitive status for new users +APP_SENSITIVE=1 + +# Default approved status for new users +APP_APPROVED=1 + +# Default Yggdrasil filters status for new users APP_YGGDRASIL=1 +# Default posters status for new users +APP_POSTERS=1 + +# Build-in trackers append to downloads APP_TRACKERS=http://[201:23b4:991a:634d:8359:4521:5576:15b7]:2023/announce|http://[200:1e2f:e608:eb3a:2bf:1e62:87ba:e2f7]/announce|http://[316:c51a:62a3:8b9::5]/announce -APP_TORRENT_FILE_SIZE_MAX=1024000 \ No newline at end of file +# List of crawlers where ignored in actions and activity features +APP_CRAWLERS=201:23b4:991a:634d:8359:4521:5576:15b7|30a:5fad::e|202:f2bc:f800:7cc4:c109:7857:5cae:6630|200:1554:e730:4030:605b:47be:6fb6:7b11 + +# Max torrent filesize for uploads (check upload_max_filesize in the php.ini) +APP_TORRENT_FILE_SIZE_MAX=1024000 + +# Max torrent poster filesize for uploads (check upload_max_filesize in the php.ini) +APP_TORRENT_POSTER_FILE_SIZE_MAX=10240000 + +# Store wanted torrent files in /app/var/ftp by /app/crontab/torrent/scrape/{key} +APP_TORRENT_WANTED_FTP_ENABLED=1 +APP_TORRENT_WANTED_FTP_FOLDER=/yggtracker +APP_TORRENT_WANTED_FTP_APPROVED_ONLY=1 + +# Enable search index for torrent name +APP_INDEX_TORRENT_NAME_ENABLED=1 + +# Enable search index for torrent info hash v1 +APP_INDEX_TORRENT_HASH_V1_ENABLED=1 + +# Enable search index for torrent info hash v2 +APP_INDEX_TORRENT_HASH_V2_ENABLED=1 + +# Enable search index for torrent filenames +APP_INDEX_TORRENT_FILENAMES_ENABLED=1 + +# Enable search index for torrent source +APP_INDEX_TORRENT_SOURCE_ENABLED=1 + +# Enable search index for torrent comment +APP_INDEX_TORRENT_COMMENT_ENABLED=1 + +# Enable search index for words length greater than N chars +APP_INDEX_WORD_LENGTH_MIN=3 + +# Enable search index for words length not greater than N chars +APP_INDEX_WORD_LENGTH_MAX=255 \ No newline at end of file diff --git a/README.md b/README.md index 7843119..6ab362a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,15 @@ # YGGtracker -BitTorrent Registry for Yggdrasil +> [!NOTE] +> Take a look at [βtracker](https://github.com/yggverse/btracker) - the modern aggregation alternative written in Rust! -YGGtracker uses [Yggdrasil](https://github.com/yggdrasil-network/yggdrasil-go) IPv6 addresses to identify users without registration. +A social-oriented BitTorrent catalog for the [Yggdrasil](https://github.com/yggdrasil-network) network, written in the Symfony framework. + +YGGtracker is a manually operated catalog and social network that allows users to share their torrents in the local network. Engine uses IPv6 `0200::/7` addresses to identify users without registration. + +#### [Showcase](https://github.com/YGGverse/YGGtracker/wiki/Showcase) + +![Pasted image 1](https://github.com/YGGverse/YGGtracker/assets/108541346/962f7850-01e1-4add-9dbe-c11b80108a75) #### Installation @@ -45,13 +52,11 @@ php bin/console doctrine:migrations:migrate ##### Crontab -* `* * * * * /crontab/torrent/scrape` - update seeding stats +* `* * * * * /crontab/torrent/scrape/{%app.key%}` - update seeding stats -##### Routing +##### FTP -YGGtracker uses sub-directory prefix by default, -if your instance running in the document root, please change `prefix` value to `/` in file -`/config/routes.yaml` +Setup anonymous read-only access to `/var/ftp` catalog ([read more](https://github.com/YGGverse/YGGtracker/wiki/Features#the-wanted)) ##### App settings @@ -59,7 +64,11 @@ Custom settings could be provided in the `/.env.local` file by overwriting defau #### Localization -* Join community translations by [Crowdin](https://crowdin.com/project/yggtracker) +[![Crowdin](https://badges.crowdin.net/yggtracker/localized.svg)](https://crowdin.com/project/yggtracker) + +#### API + +[Wiki reference](https://github.com/YGGverse/YGGtracker/wiki/API) #### Contribution @@ -70,37 +79,40 @@ git checkout main git checkout -b my-pr-branch-name ``` -#### Donate to contributors - -* @d47081: - - + ![wakatime](https://wakatime.com/badge/user/0b7fe6c1-b091-4c98-b930-75cfee17c7a5/project/059ec567-2c65-4c65-a48e-51dcc366f1a0.svg) - + [BTC](https://www.blockchain.com/explorer/addresses/btc/bc1qngdf2kwty6djjqpk0ynkpq9wmlrmtm7e0c534y) | [LTC](https://live.blockcypher.com/ltc/address/LUSiqzKsfB1vBLvpu515DZktG9ioKqLyj7) | [XMR](835gSR1Uvka19gnWPkU2pyRozZugRZSPHDuFL6YajaAqjEtMwSPr4jafM8idRuBWo7AWD3pwFQSYRMRW9XezqrK4BEXBgXE) | [ZEPH](ZEPHsADHXqnhfWhXrRcXnyBQMucE3NM7Ng5ZVB99XwA38PTnbjLKpCwcQVgoie8EJuWozKgBiTmDFW4iY7fNEgSEWyAy4dotqtX) - + Support our server by order [Linux VPS](https://www.yourserver.se/portal/aff.php?aff=610) - + Inspiration by [SomaFM Deep Space One](https://somafm.com/deepspaceone/) - #### License * Engine sources [MIT License](https://github.com/YGGverse/YGGtracker/blob/main/LICENSE) +#### Versioning + +[Semantic Versioning 2.0.0](https://semver.org/#semantic-versioning-200) + #### Components * [Symfony Framework](https://symfony.com) * [SVG icons](https://icons.getbootstrap.com) * [Scrapper](https://github.com/medariox/scrapeer) / [Composer Edition](https://github.com/YGGverse/scrapeer) -* [Bencode Library](https://github.com/Rhilip/Bencode) +* [Bencode](https://github.com/Rhilip/Bencode) +* [Transliteration](https://github.com/ashtokalo/php-translit) * [Identicons](https://github.com/dmester/jdenticon-php) -#### Feedback +#### Support -[https://github.com/YGGverse/YGGtracker/issues](https://github.com/YGGverse/YGGtracker/issues) +* [Issues](https://github.com/YGGverse/YGGtracker/issues) +* [Documentation](https://github.com/YGGverse/YGGtracker/wiki) +* [HowTo Yggdrasil](https://ygg.work.gd/yggdrasil:bittorrent:yggtracker) -#### Community +#### Blog * [Mastodon](https://mastodon.social/@YGGverse) +#### Integrations + +* [YGGtracker Search Plugin for qBittorrent](https://github.com/YGGverse/qbittorrent-yggtracker-search-plugin) +* [Crontab script that allows to receive wanted torrents from multiple YGGtracker nodes](https://github.com/YGGverse/yggtracker-wanted-torrents-receiver) + #### See also * [YGGo - YGGo! Distributed Web Search Engine ](https://github.com/YGGverse/YGGo) * [YGGwave ~ The Radio Catalog](https://github.com/YGGverse/YGGwave) -* [YGGstate - Yggdrasil Network Explorer](https://github.com/YGGverse/YGGstate) \ No newline at end of file +* [YGGstate - Yggdrasil Network Explorer](https://github.com/YGGverse/YGGstate) diff --git a/composer.json b/composer.json index c0d3e3c..0126d61 100644 --- a/composer.json +++ b/composer.json @@ -9,11 +9,13 @@ "php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", + "ashtokalo/php-translit": "^0.2.0", "doctrine/annotations": "^2.0", "doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.16", "jdenticon/jdenticon": "^1.0", + "league/commonmark": "^2.4", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpdoc-parser": "^1.24", "rhilip/bencode": "^2.3", @@ -44,8 +46,9 @@ "symfony/validator": "6.3.*", "symfony/web-link": "6.3.*", "symfony/yaml": "6.3.*", - "twig/extra-bundle": "^2.12|^3.0", + "twig/extra-bundle": "^3.7", "twig/intl-extra": "^3.7", + "twig/markdown-extra": "^3.7", "twig/string-extra": "^3.7", "twig/twig": "^2.12|^3.0", "yggverse/scrapeer": "^0.5.4" diff --git a/composer.lock b/composer.lock index e3eddf2..efca9a6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,126 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3770ffcd80695bc10a22f8ece4f68d1f", + "content-hash": "99ad25219a6bff24126d6f83ebd1756a", "packages": [ + { + "name": "ashtokalo/php-translit", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/ashtokalo/php-translit.git", + "reference": "8ced36cbcd0ed8befb1388ef51935eb53bcfe5b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ashtokalo/php-translit/zipball/8ced36cbcd0ed8befb1388ef51935eb53bcfe5b3", + "reference": "8ced36cbcd0ed8befb1388ef51935eb53bcfe5b3", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "~7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ashtokalo\\translit\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP library to convert text from one script to another.", + "keywords": [ + "latinization", + "romanization", + "translit", + "transliteration" + ], + "support": { + "issues": "https://github.com/ashtokalo/php-translit/issues", + "source": "https://github.com/ashtokalo/php-translit/tree/0.2.0" + }, + "time": "2022-09-26T09:05:24+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, { "name": "doctrine/annotations", "version": "2.0.1", @@ -354,16 +472,16 @@ }, { "name": "doctrine/dbal", - "version": "3.7.0", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0ac3c270590e54910715e9a1a044cc368df282b2", + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2", "shasum": "" }, "require": { @@ -379,7 +497,7 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.35", + "phpstan/phpstan": "1.10.42", "phpstan/phpstan-strict-rules": "^1.5", "phpunit/phpunit": "9.6.13", "psalm/plugin-phpunit": "0.18.4", @@ -447,7 +565,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.7.0" + "source": "https://github.com/doctrine/dbal/tree/3.7.2" }, "funding": [ { @@ -463,7 +581,7 @@ "type": "tidelift" } ], - "time": "2023-09-26T20:56:55+00:00" + "time": "2023-11-19T08:06:58+00:00" }, { "name": "doctrine/deprecations", @@ -514,56 +632,59 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.10.2", + "version": "2.11.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "f28b1f78de3a2938ff05cfe751233097624cc756" + "reference": "4089f1424b724786c062aea50aae5f773449b94b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/f28b1f78de3a2938ff05cfe751233097624cc756", - "reference": "f28b1f78de3a2938ff05cfe751233097624cc756", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/4089f1424b724786c062aea50aae5f773449b94b", + "reference": "4089f1424b724786c062aea50aae5f773449b94b", "shasum": "" }, "require": { "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^3.6.0", + "doctrine/dbal": "^3.7.0 || ^4.0", "doctrine/persistence": "^2.2 || ^3", "doctrine/sql-formatter": "^1.0.1", "php": "^7.4 || ^8.0", - "symfony/cache": "^5.4 || ^6.0", - "symfony/config": "^5.4 || ^6.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", "symfony/deprecation-contracts": "^2.1 || ^3", - "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7", - "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" }, "conflict": { "doctrine/annotations": ">=3.0", - "doctrine/orm": "<2.11 || >=3.0", + "doctrine/orm": "<2.14 || >=4.0", "twig/twig": "<1.34 || >=2.0 <2.4" }, "require-dev": { "doctrine/annotations": "^1 || ^2", - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^12", "doctrine/deprecations": "^1.0", - "doctrine/orm": "^2.11 || ^3.0", + "doctrine/orm": "^2.14 || ^3.0", "friendsofphp/proxy-manager-lts": "^1.0", "phpunit/phpunit": "^9.5.26 || ^10.0", "psalm/plugin-phpunit": "^0.18.4", "psalm/plugin-symfony": "^4", "psr/log": "^1.1.4 || ^2.0 || ^3.0", - "symfony/phpunit-bridge": "^6.1", - "symfony/property-info": "^5.4 || ^6.0", - "symfony/proxy-manager-bridge": "^5.4 || ^6.0", - "symfony/security-bundle": "^5.4 || ^6.0", - "symfony/twig-bridge": "^5.4 || ^6.0", - "symfony/validator": "^5.4 || ^6.0", - "symfony/web-profiler-bundle": "^5.4 || ^6.0", - "symfony/yaml": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/property-info": "^5.4 || ^6.0 || ^7.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^5.4 || ^6.2 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", "twig/twig": "^1.34 || ^2.12 || ^3.0", "vimeo/psalm": "^4.30" }, @@ -610,7 +731,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.10.2" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.11.1" }, "funding": [ { @@ -626,38 +747,44 @@ "type": "tidelift" } ], - "time": "2023-08-06T09:31:40+00:00" + "time": "2023-11-15T20:01:50+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", - "version": "3.2.4", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "94e6b0fe1a50901d52f59dbb9b4b0737718b2c1e" + "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/94e6b0fe1a50901d52f59dbb9b4b0737718b2c1e", - "reference": "94e6b0fe1a50901d52f59dbb9b4b0737718b2c1e", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/1dd42906a5fb9c5960723e2ebb45c68006493835", + "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835", "shasum": "" }, "require": { - "doctrine/doctrine-bundle": "~1.0|~2.0", + "doctrine/doctrine-bundle": "^2.4", "doctrine/migrations": "^3.2", "php": "^7.2|^8.0", - "symfony/framework-bundle": "~3.4|~4.0|~5.0|~6.0" + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "doctrine/orm": "^2.6", - "doctrine/persistence": "^1.3||^2.0", + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.6 || ^3", + "doctrine/persistence": "^2.0 || ^3 ", "phpstan/phpstan": "^1.4", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan-symfony": "^1.3", "phpunit/phpunit": "^8.5|^9.5", - "vimeo/psalm": "^4.22" + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^3 || ^5", + "symfony/phpunit-bridge": "^6.3 || ^7", + "symfony/var-exporter": "^5.4 || ^6 || ^7", + "vimeo/psalm": "^4.30 || ^5.15" }, "type": "symfony-bundle", "autoload": { @@ -695,7 +822,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", - "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.2.4" + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.0" }, "funding": [ { @@ -711,7 +838,7 @@ "type": "tidelift" } ], - "time": "2023-06-02T08:19:26+00:00" + "time": "2023-11-13T19:44:41+00:00" }, { "name": "doctrine/event-manager", @@ -1045,47 +1172,47 @@ }, { "name": "doctrine/migrations", - "version": "3.6.0", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059" + "reference": "47af29eef49f29ebee545947e8b2a4b3be318c8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/e542ad8bcd606d7a18d0875babb8a6d963c9c059", - "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/47af29eef49f29ebee545947e8b2a4b3be318c8a", + "reference": "47af29eef49f29ebee545947e8b2a4b3be318c8a", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/dbal": "^3.5.1", + "doctrine/dbal": "^3.5.1 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2.0", "php": "^8.1", "psr/log": "^1.1.3 || ^2 || ^3", - "symfony/console": "^4.4.16 || ^5.4 || ^6.0", - "symfony/stopwatch": "^4.4 || ^5.4 || ^6.0", - "symfony/var-exporter": "^6.2" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.2 || ^7.0" }, "conflict": { - "doctrine/orm": "<2.12" + "doctrine/orm": "<2.12 || >=4" }, "require-dev": { - "doctrine/coding-standard": "^9", - "doctrine/orm": "^2.13", + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.13 || ^3", "doctrine/persistence": "^2 || ^3", "doctrine/sql-formatter": "^1.0", "ext-pdo_sqlite": "*", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.1", - "phpstan/phpstan-symfony": "^1.1", - "phpunit/phpunit": "^9.5.24", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/process": "^4.4 || ^5.4 || ^6.0", - "symfony/yaml": "^4.4 || ^5.4 || ^6.0" + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.4", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^10.3", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "doctrine/sql-formatter": "Allows to generate formatted SQL with the diff command.", @@ -1127,7 +1254,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.6.0" + "source": "https://github.com/doctrine/migrations/tree/3.7.2" }, "funding": [ { @@ -1143,20 +1270,20 @@ "type": "tidelift" } ], - "time": "2023-02-15T18:49:46+00:00" + "time": "2023-12-05T11:35:05+00:00" }, { "name": "doctrine/orm", - "version": "2.16.2", + "version": "2.17.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "17500f56eaa930f5cd14d765bc2cd851c7d37cc0" + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/17500f56eaa930f5cd14d765bc2cd851c7d37cc0", - "reference": "17500f56eaa930f5cd14d765bc2cd851c7d37cc0", + "url": "https://api.github.com/repos/doctrine/orm/zipball/1a4fe6e0bb67762370937a7e6cee3da40a9122d1", + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1", "shasum": "" }, "require": { @@ -1174,7 +1301,7 @@ "ext-ctype": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, @@ -1185,14 +1312,14 @@ "doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.28", + "phpstan/phpstan": "~1.4.10 || 1.10.35", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.14.1" + "vimeo/psalm": "4.30.0 || 5.15.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -1242,9 +1369,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.16.2" + "source": "https://github.com/doctrine/orm/tree/2.17.1" }, - "time": "2023-08-27T18:21:56+00:00" + "time": "2023-11-17T06:25:40+00:00" }, { "name": "doctrine/persistence", @@ -1513,17 +1640,205 @@ "time": "2022-10-30T17:15:02+00:00" }, { - "name": "monolog/monolog", - "version": "3.4.0", + "name": "league/commonmark", + "version": "2.4.1", "source": { "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "e2392369686d420ca32df3803de28b5d6f76867d" + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e2392369686d420ca32df3803de28b5d6f76867d", - "reference": "e2392369686d420ca32df3803de28b5d6f76867d", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2023-08-30T16:55:00+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", "shasum": "" }, "require": { @@ -1599,7 +1914,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.4.0" + "source": "https://github.com/Seldaek/monolog/tree/3.5.0" }, "funding": [ { @@ -1611,7 +1926,155 @@ "type": "tidelift" } ], - "time": "2023-06-21T08:46:11+00:00" + "time": "2023-10-27T15:32:31+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.5", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/0462f0166e823aad657c9224d0f849ecac1ba10a", + "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": "7.1 - 8.3" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.5" + }, + "time": "2023-10-05T20:37:59+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/a9d127dd6a203ce6d255b2e2db49759f7506e015", + "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015", + "shasum": "" + }, + "require": { + "php": ">=8.0 <8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.3" + }, + "time": "2023-10-29T21:02:13+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1783,16 +2246,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.2", + "version": "1.24.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "bcad8d995980440892759db0c32acae7c8e79442" + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442", - "reference": "bcad8d995980440892759db0c32acae7c8e79442", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", "shasum": "" }, "require": { @@ -1824,9 +2287,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.4" }, - "time": "2023-09-26T12:28:12+00:00" + "time": "2023-11-26T18:29:22+00:00" }, { "name": "psr/cache", @@ -2136,22 +2599,23 @@ }, { "name": "rhilip/bencode", - "version": "v2.3.3", + "version": "v2.4.2", "source": { "type": "git", "url": "https://github.com/Rhilip/Bencode.git", - "reference": "fd37d13bb745352d40879dbbfa6da85af91e49f1" + "reference": "d5b51d02f73017834c53aa76aff2403fb753ac97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Rhilip/Bencode/zipball/fd37d13bb745352d40879dbbfa6da85af91e49f1", - "reference": "fd37d13bb745352d40879dbbfa6da85af91e49f1", + "url": "https://api.github.com/repos/Rhilip/Bencode/zipball/d5b51d02f73017834c53aa76aff2403fb753ac97", + "reference": "d5b51d02f73017834c53aa76aff2403fb753ac97", "shasum": "" }, "require": { "php": "^7.3|^8.0" }, "require-dev": { + "ext-json": "*", "phpunit/phpunit": "^9.0" }, "suggest": { @@ -2181,22 +2645,22 @@ ], "support": { "issues": "https://github.com/Rhilip/Bencode/issues", - "source": "https://github.com/Rhilip/Bencode/tree/v2.3.3" + "source": "https://github.com/Rhilip/Bencode/tree/v2.4.2" }, - "time": "2023-05-27T01:47:00+00:00" + "time": "2023-11-05T11:24:41+00:00" }, { "name": "symfony/asset", - "version": "v6.3.0", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "b77a4cc8e266b7e0db688de740f9ee7253aa411c" + "reference": "b2382a403f2111836301623d89e9af3d84989525" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/b77a4cc8e266b7e0db688de740f9ee7253aa411c", - "reference": "b77a4cc8e266b7e0db688de740f9ee7253aa411c", + "url": "https://api.github.com/repos/symfony/asset/zipball/b2382a403f2111836301623d89e9af3d84989525", + "reference": "b2382a403f2111836301623d89e9af3d84989525", "shasum": "" }, "require": { @@ -2236,7 +2700,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v6.3.0" + "source": "https://github.com/symfony/asset/tree/v6.3.8" }, "funding": [ { @@ -2252,20 +2716,20 @@ "type": "tidelift" } ], - "time": "2023-04-21T14:41:17+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/cache", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "6c1a3ea078c4d88ee892530945df63a87981b2da" + "reference": "8c6e84272e4febbb1fed3c5b9f3c722537c2bd55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/6c1a3ea078c4d88ee892530945df63a87981b2da", - "reference": "6c1a3ea078c4d88ee892530945df63a87981b2da", + "url": "https://api.github.com/repos/symfony/cache/zipball/8c6e84272e4febbb1fed3c5b9f3c722537c2bd55", + "reference": "8c6e84272e4febbb1fed3c5b9f3c722537c2bd55", "shasum": "" }, "require": { @@ -2274,7 +2738,7 @@ "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3", - "symfony/var-exporter": "^6.2.10" + "symfony/var-exporter": "^6.3.6" }, "conflict": { "doctrine/dbal": "<2.13.1", @@ -2289,7 +2753,7 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/dbal": "^2.13.1|^3.0", + "doctrine/dbal": "^2.13.1|^3|^4", "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", "symfony/config": "^5.4|^6.0", @@ -2332,7 +2796,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.3.5" + "source": "https://github.com/symfony/cache/tree/v6.3.9" }, "funding": [ { @@ -2348,20 +2812,20 @@ "type": "tidelift" } ], - "time": "2023-09-26T15:48:55+00:00" + "time": "2023-11-24T13:24:35+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b" + "reference": "1d74b127da04ffa87aa940abe15446fa89653778" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ad945640ccc0ae6e208bcea7d7de4b39b569896b", - "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1d74b127da04ffa87aa940abe15446fa89653778", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778", "shasum": "" }, "require": { @@ -2408,7 +2872,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/cache-contracts/tree/v3.4.0" }, "funding": [ { @@ -2424,7 +2888,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-09-25T12:52:38+00:00" }, { "name": "symfony/clock", @@ -2501,16 +2965,16 @@ }, { "name": "symfony/config", - "version": "v6.3.2", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + "reference": "b7a63887960359e5b59b15826fa9f9be10acbe88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", - "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "url": "https://api.github.com/repos/symfony/config/zipball/b7a63887960359e5b59b15826fa9f9be10acbe88", + "reference": "b7a63887960359e5b59b15826fa9f9be10acbe88", "shasum": "" }, "require": { @@ -2556,7 +3020,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.3.2" + "source": "https://github.com/symfony/config/tree/v6.3.8" }, "funding": [ { @@ -2572,20 +3036,20 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:22:16+00:00" + "time": "2023-11-09T08:28:21+00:00" }, { "name": "symfony/console", - "version": "v6.3.4", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" + "reference": "0566dbd051f8648d980592c7849f5d90d2c7c60c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6", - "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", + "url": "https://api.github.com/repos/symfony/console/zipball/0566dbd051f8648d980592c7849f5d90d2c7c60c", + "reference": "0566dbd051f8648d980592c7849f5d90d2c7c60c", "shasum": "" }, "require": { @@ -2646,7 +3110,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.4" + "source": "https://github.com/symfony/console/tree/v6.3.9" }, "funding": [ { @@ -2662,7 +3126,7 @@ "type": "tidelift" } ], - "time": "2023-08-16T10:10:12+00:00" + "time": "2023-11-20T16:36:29+00:00" }, { "name": "symfony/crowdin-translation-provider", @@ -2739,16 +3203,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.3.5", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2ed62b3bf98346e1f45529a7b6be2196739bb993" + "reference": "51383a1d9d7e93d5c3c76ddc32672de1b3e82c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2ed62b3bf98346e1f45529a7b6be2196739bb993", - "reference": "2ed62b3bf98346e1f45529a7b6be2196739bb993", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51383a1d9d7e93d5c3c76ddc32672de1b3e82c77", + "reference": "51383a1d9d7e93d5c3c76ddc32672de1b3e82c77", "shasum": "" }, "require": { @@ -2800,7 +3264,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.3.5" + "source": "https://github.com/symfony/dependency-injection/tree/v6.3.10" }, "funding": [ { @@ -2816,11 +3280,11 @@ "type": "tidelift" } ], - "time": "2023-09-25T16:46:40+00:00" + "time": "2023-12-01T14:25:58+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -2867,7 +3331,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -2887,16 +3351,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "9977eb1adf999ceded213e88c1ac6dff7a1a0306" + "reference": "8842d289d41320a0f725e996b4e58d84af398a9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/9977eb1adf999ceded213e88c1ac6dff7a1a0306", - "reference": "9977eb1adf999ceded213e88c1ac6dff7a1a0306", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/8842d289d41320a0f725e996b4e58d84af398a9e", + "reference": "8842d289d41320a0f725e996b4e58d84af398a9e", "shasum": "" }, "require": { @@ -2929,8 +3393,8 @@ "doctrine/annotations": "^1.13.1|^2", "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.13.1|^3.0", - "doctrine/orm": "^2.12", + "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/orm": "^2.12|^3", "psr/log": "^1|^2|^3", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", @@ -2977,7 +3441,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.3.5" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.3.8" }, "funding": [ { @@ -2993,24 +3457,24 @@ "type": "tidelift" } ], - "time": "2023-09-29T16:16:03+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v6.3.1", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "f1c253e24ae6d2bc4939b1439e074e6d2e73ecdb" + "reference": "b225f860450a34291bc5983f87d57fb7b9ef18b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/f1c253e24ae6d2bc4939b1439e074e6d2e73ecdb", - "reference": "f1c253e24ae6d2bc4939b1439e074e6d2e73ecdb", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/b225f860450a34291bc5983f87d57fb7b9ef18b8", + "reference": "b225f860450a34291bc5983f87d57fb7b9ef18b8", "shasum": "" }, "require": { - "doctrine/dbal": "^2.13|^3.0", + "doctrine/dbal": "^2.13|^3|^4", "php": ">=8.1", "symfony/messenger": "^5.4|^6.0", "symfony/service-contracts": "^2.5|^3" @@ -3049,7 +3513,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v6.3.1" + "source": "https://github.com/symfony/doctrine-messenger/tree/v6.3.10" }, "funding": [ { @@ -3065,20 +3529,20 @@ "type": "tidelift" } ], - "time": "2023-06-24T11:51:27+00:00" + "time": "2023-12-01T09:24:52+00:00" }, { "name": "symfony/dotenv", - "version": "v6.3.0", + "version": "v6.3.7", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "ceadb434fe2a6763a03d2d110441745834f3dd1e" + "reference": "7dfbe2976f3c1b7cfa8fac2212a050bfa9bd7d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/ceadb434fe2a6763a03d2d110441745834f3dd1e", - "reference": "ceadb434fe2a6763a03d2d110441745834f3dd1e", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/7dfbe2976f3c1b7cfa8fac2212a050bfa9bd7d9e", + "reference": "7dfbe2976f3c1b7cfa8fac2212a050bfa9bd7d9e", "shasum": "" }, "require": { @@ -3123,7 +3587,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.3.0" + "source": "https://github.com/symfony/dotenv/tree/v6.3.7" }, "funding": [ { @@ -3139,7 +3603,7 @@ "type": "tidelift" } ], - "time": "2023-04-21T14:41:17+00:00" + "time": "2023-10-26T18:15:14+00:00" }, { "name": "symfony/error-handler", @@ -3297,7 +3761,7 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -3353,7 +3817,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -3564,16 +4028,16 @@ }, { "name": "symfony/flex", - "version": "v2.3.3", + "version": "v2.4.2", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "9c402af768c6c9f8126a9ffa192ecf7c16581e35" + "reference": "67ee785f1aedada76461de7a7ec10cd7f8ff8d36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/9c402af768c6c9f8126a9ffa192ecf7c16581e35", - "reference": "9c402af768c6c9f8126a9ffa192ecf7c16581e35", + "url": "https://api.github.com/repos/symfony/flex/zipball/67ee785f1aedada76461de7a7ec10cd7f8ff8d36", + "reference": "67ee785f1aedada76461de7a7ec10cd7f8ff8d36", "shasum": "" }, "require": { @@ -3609,7 +4073,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v2.3.3" + "source": "https://github.com/symfony/flex/tree/v2.4.2" }, "funding": [ { @@ -3625,20 +4089,20 @@ "type": "tidelift" } ], - "time": "2023-08-04T09:02:35+00:00" + "time": "2023-12-05T14:09:35+00:00" }, { "name": "symfony/form", - "version": "v6.3.5", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "0f9ad8600c1021983d096512066ee54332aa3139" + "reference": "5afc7334b9d60dd0799612faf3d103b25bc60ae4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/0f9ad8600c1021983d096512066ee54332aa3139", - "reference": "0f9ad8600c1021983d096512066ee54332aa3139", + "url": "https://api.github.com/repos/symfony/form/zipball/5afc7334b9d60dd0799612faf3d103b25bc60ae4", + "reference": "5afc7334b9d60dd0799612faf3d103b25bc60ae4", "shasum": "" }, "require": { @@ -3706,7 +4170,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v6.3.5" + "source": "https://github.com/symfony/form/tree/v6.3.10" }, "funding": [ { @@ -3722,20 +4186,20 @@ "type": "tidelift" } ], - "time": "2023-09-10T17:47:23+00:00" + "time": "2023-11-30T11:08:22+00:00" }, { "name": "symfony/framework-bundle", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "567cafcfc08e3076b47290a7558b0ca17a98b0ce" + "reference": "f83d20092e98c3ae8b5874b8f0787546c5c61cda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/567cafcfc08e3076b47290a7558b0ca17a98b0ce", - "reference": "567cafcfc08e3076b47290a7558b0ca17a98b0ce", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/f83d20092e98c3ae8b5874b8f0787546c5c61cda", + "reference": "f83d20092e98c3ae8b5874b8f0787546c5c61cda", "shasum": "" }, "require": { @@ -3850,7 +4314,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.3.5" + "source": "https://github.com/symfony/framework-bundle/tree/v6.3.9" }, "funding": [ { @@ -3866,20 +4330,20 @@ "type": "tidelift" } ], - "time": "2023-09-29T10:45:15+00:00" + "time": "2023-11-24T10:25:33+00:00" }, { "name": "symfony/http-client", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "213e564da4cbf61acc9728d97e666bcdb868c10d" + "reference": "0314e2d49939a9831929d6fc81c01c6df137fd0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/213e564da4cbf61acc9728d97e666bcdb868c10d", - "reference": "213e564da4cbf61acc9728d97e666bcdb868c10d", + "url": "https://api.github.com/repos/symfony/http-client/zipball/0314e2d49939a9831929d6fc81c01c6df137fd0a", + "reference": "0314e2d49939a9831929d6fc81c01c6df137fd0a", "shasum": "" }, "require": { @@ -3942,7 +4406,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.3.5" + "source": "https://github.com/symfony/http-client/tree/v6.3.8" }, "funding": [ { @@ -3958,20 +4422,20 @@ "type": "tidelift" } ], - "time": "2023-09-29T15:57:12+00:00" + "time": "2023-11-06T18:31:59+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb" + "reference": "1ee70e699b41909c209a0c930f11034b93578654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3b66325d0176b4ec826bffab57c9037d759c31fb", - "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", + "reference": "1ee70e699b41909c209a0c930f11034b93578654", "shasum": "" }, "require": { @@ -4020,7 +4484,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" }, "funding": [ { @@ -4036,20 +4500,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "b50f5e281d722cb0f4c296f908bacc3e2b721957" + "reference": "49a04fd3a21edc9ce503ab78e9f342805fefe780" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b50f5e281d722cb0f4c296f908bacc3e2b721957", - "reference": "b50f5e281d722cb0f4c296f908bacc3e2b721957", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/49a04fd3a21edc9ce503ab78e9f342805fefe780", + "reference": "49a04fd3a21edc9ce503ab78e9f342805fefe780", "shasum": "" }, "require": { @@ -4059,12 +4523,12 @@ "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.2" + "symfony/cache": "<6.3" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3.0", + "doctrine/dbal": "^2.13.1|^3|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^5.4|^6.0", + "symfony/cache": "^6.3", "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", @@ -4097,7 +4561,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.3.5" + "source": "https://github.com/symfony/http-foundation/tree/v6.3.9" }, "funding": [ { @@ -4113,20 +4577,20 @@ "type": "tidelift" } ], - "time": "2023-09-04T21:33:54+00:00" + "time": "2023-11-20T16:36:29+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.3.5", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9f991a964368bee8d883e8d57ced4fe9fff04dfc" + "reference": "8d8e7aa60593fd0a2e3c1cea08cc687314841b61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9f991a964368bee8d883e8d57ced4fe9fff04dfc", - "reference": "9f991a964368bee8d883e8d57ced4fe9fff04dfc", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8d8e7aa60593fd0a2e3c1cea08cc687314841b61", + "reference": "8d8e7aa60593fd0a2e3c1cea08cc687314841b61", "shasum": "" }, "require": { @@ -4210,7 +4674,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.3.5" + "source": "https://github.com/symfony/http-kernel/tree/v6.3.10" }, "funding": [ { @@ -4226,20 +4690,20 @@ "type": "tidelift" } ], - "time": "2023-09-30T06:37:04+00:00" + "time": "2023-12-01T16:57:27+00:00" }, { "name": "symfony/intl", - "version": "v6.3.2", + "version": "v6.3.7", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "1f8cb145c869ed089a8531c51a6a4b31ed0b3c69" + "reference": "4cc98c05f2c55150a6aa5b3e20667f7a6d06cca9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/1f8cb145c869ed089a8531c51a6a4b31ed0b3c69", - "reference": "1f8cb145c869ed089a8531c51a6a4b31ed0b3c69", + "url": "https://api.github.com/repos/symfony/intl/zipball/4cc98c05f2c55150a6aa5b3e20667f7a6d06cca9", + "reference": "4cc98c05f2c55150a6aa5b3e20667f7a6d06cca9", "shasum": "" }, "require": { @@ -4292,7 +4756,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.3.2" + "source": "https://github.com/symfony/intl/tree/v6.3.7" }, "funding": [ { @@ -4308,7 +4772,7 @@ "type": "tidelift" } ], - "time": "2023-07-20T07:43:09+00:00" + "time": "2023-10-28T23:11:45+00:00" }, { "name": "symfony/mailer", @@ -4392,22 +4856,23 @@ }, { "name": "symfony/messenger", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "fb29632c2abdc52f4f10f9402f8f93ebb8938234" + "reference": "096b151f955d5ac56cc61a3ca0e16b38ff093805" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/fb29632c2abdc52f4f10f9402f8f93ebb8938234", - "reference": "fb29632c2abdc52f4f10f9402f8f93ebb8938234", + "url": "https://api.github.com/repos/symfony/messenger/zipball/096b151f955d5ac56cc61a3ca0e16b38ff093805", + "reference": "096b151f955d5ac56cc61a3ca0e16b38ff093805", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/clock": "^6.3" + "symfony/clock": "^6.3", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "symfony/console": "<6.3", @@ -4421,7 +4886,6 @@ "psr/cache": "^1.0|^2.0|^3.0", "symfony/console": "^6.3", "symfony/dependency-injection": "^5.4|^6.0", - "symfony/deprecation-contracts": "^2.5|^3", "symfony/event-dispatcher": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", "symfony/process": "^5.4|^6.0", @@ -4459,7 +4923,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v6.3.5" + "source": "https://github.com/symfony/messenger/tree/v6.3.9" }, "funding": [ { @@ -4475,7 +4939,7 @@ "type": "tidelift" } ], - "time": "2023-09-29T16:11:24+00:00" + "time": "2023-11-22T19:13:10+00:00" }, { "name": "symfony/mime", @@ -4563,16 +5027,16 @@ }, { "name": "symfony/monolog-bridge", - "version": "v6.3.1", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "04b04b8e465e0fa84940e5609b6796a8b4e51bf1" + "reference": "2bbfc8bd9d6f966b69eda20c66762580a0410c78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/04b04b8e465e0fa84940e5609b6796a8b4e51bf1", - "reference": "04b04b8e465e0fa84940e5609b6796a8b4e51bf1", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/2bbfc8bd9d6f966b69eda20c66762580a0410c78", + "reference": "2bbfc8bd9d6f966b69eda20c66762580a0410c78", "shasum": "" }, "require": { @@ -4621,7 +5085,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v6.3.1" + "source": "https://github.com/symfony/monolog-bridge/tree/v6.3.8" }, "funding": [ { @@ -4637,34 +5101,34 @@ "type": "tidelift" } ], - "time": "2023-06-08T11:13:32+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/monolog-bundle", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bundle.git", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d" + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", "shasum": "" }, "require": { - "monolog/monolog": "^1.22 || ^2.0 || ^3.0", - "php": ">=7.1.3", - "symfony/config": "~4.4 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "~4.4 || ^5.0 || ^6.0", - "symfony/monolog-bridge": "~4.4 || ^5.0 || ^6.0" + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "symfony/console": "~4.4 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0", - "symfony/yaml": "~4.4 || ^5.0 || ^6.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "type": "symfony-bundle", "extra": { @@ -4702,7 +5166,7 @@ ], "support": { "issues": "https://github.com/symfony/monolog-bundle/issues", - "source": "https://github.com/symfony/monolog-bundle/tree/v3.8.0" + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0" }, "funding": [ { @@ -4718,20 +5182,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T14:24:36+00:00" + "time": "2023-11-06T17:08:13+00:00" }, { "name": "symfony/notifier", - "version": "v6.3.0", + "version": "v6.3.6", "source": { "type": "git", "url": "https://github.com/symfony/notifier.git", - "reference": "a30aee1bf767835d7948138c1629e310cee26a8b" + "reference": "2e39d4a9a96e25d127ffe30171127f6ef73934df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/notifier/zipball/a30aee1bf767835d7948138c1629e310cee26a8b", - "reference": "a30aee1bf767835d7948138c1629e310cee26a8b", + "url": "https://api.github.com/repos/symfony/notifier/zipball/2e39d4a9a96e25d127ffe30171127f6ef73934df", + "reference": "2e39d4a9a96e25d127ffe30171127f6ef73934df", "shasum": "" }, "require": { @@ -4780,7 +5244,7 @@ "notifier" ], "support": { - "source": "https://github.com/symfony/notifier/tree/v6.3.0" + "source": "https://github.com/symfony/notifier/tree/v6.3.6" }, "funding": [ { @@ -4796,7 +5260,7 @@ "type": "tidelift" } ], - "time": "2023-05-12T10:17:15+00:00" + "time": "2023-10-07T07:32:05+00:00" }, { "name": "symfony/options-resolver", @@ -4867,16 +5331,16 @@ }, { "name": "symfony/password-hasher", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "278d3a49715073879f75e372ad80b8cfeca949d3" + "reference": "82161c4bebf77900372083ec6e484b5f055b0cba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/278d3a49715073879f75e372ad80b8cfeca949d3", - "reference": "278d3a49715073879f75e372ad80b8cfeca949d3", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/82161c4bebf77900372083ec6e484b5f055b0cba", + "reference": "82161c4bebf77900372083ec6e484b5f055b0cba", "shasum": "" }, "require": { @@ -4919,7 +5383,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v6.3.5" + "source": "https://github.com/symfony/password-hasher/tree/v6.3.8" }, "funding": [ { @@ -4935,7 +5399,7 @@ "type": "tidelift" } ], - "time": "2023-09-25T17:05:16+00:00" + "time": "2023-11-06T10:58:05+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -5579,16 +6043,16 @@ }, { "name": "symfony/property-info", - "version": "v6.3.0", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd" + "reference": "664ae7ad443d7cc591ff3e15496b954e4cefe729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/7f3a03716112269741fe2a809f8f791a371d1fcd", - "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd", + "url": "https://api.github.com/repos/symfony/property-info/zipball/664ae7ad443d7cc591ff3e15496b954e4cefe729", + "reference": "664ae7ad443d7cc591ff3e15496b954e4cefe729", "shasum": "" }, "require": { @@ -5642,7 +6106,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.3.0" + "source": "https://github.com/symfony/property-info/tree/v6.3.9" }, "funding": [ { @@ -5658,20 +6122,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T08:06:44+00:00" + "time": "2023-11-24T11:57:32+00:00" }, { "name": "symfony/routing", - "version": "v6.3.5", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31" + "reference": "cb7404232d49dd11cc971b832fcbd49e7c22b049" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/82616e59acd3e3d9c916bba798326cb7796d7d31", - "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31", + "url": "https://api.github.com/repos/symfony/routing/zipball/cb7404232d49dd11cc971b832fcbd49e7c22b049", + "reference": "cb7404232d49dd11cc971b832fcbd49e7c22b049", "shasum": "" }, "require": { @@ -5725,7 +6189,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.3.5" + "source": "https://github.com/symfony/routing/tree/v6.3.10" }, "funding": [ { @@ -5741,7 +6205,7 @@ "type": "tidelift" } ], - "time": "2023-09-20T16:05:51+00:00" + "time": "2023-12-01T14:25:58+00:00" }, { "name": "symfony/runtime", @@ -5824,16 +6288,16 @@ }, { "name": "symfony/security-bundle", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "2df460eacceb11b9287cfafddda4d27023dd9001" + "reference": "57889ebb1ac3403d550c787c4fde127261abacb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/2df460eacceb11b9287cfafddda4d27023dd9001", - "reference": "2df460eacceb11b9287cfafddda4d27023dd9001", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/57889ebb1ac3403d550c787c4fde127261abacb6", + "reference": "57889ebb1ac3403d550c787c4fde127261abacb6", "shasum": "" }, "require": { @@ -5850,7 +6314,8 @@ "symfony/password-hasher": "^5.4|^6.0", "symfony/security-core": "^6.2", "symfony/security-csrf": "^5.4|^6.0", - "symfony/security-http": "^6.3.4" + "symfony/security-http": "^6.3.6", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { "symfony/browser-kit": "<5.4", @@ -5914,7 +6379,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v6.3.5" + "source": "https://github.com/symfony/security-bundle/tree/v6.3.8" }, "funding": [ { @@ -5930,20 +6395,20 @@ "type": "tidelift" } ], - "time": "2023-09-25T17:05:55+00:00" + "time": "2023-11-09T09:33:10+00:00" }, { "name": "symfony/security-core", - "version": "v6.3.5", + "version": "v6.3.7", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "ec8f24dc1195f46483510892271d01a5202bba70" + "reference": "7ceb30fed93f5ea40ccde3173d1f7712527c0d62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/ec8f24dc1195f46483510892271d01a5202bba70", - "reference": "ec8f24dc1195f46483510892271d01a5202bba70", + "url": "https://api.github.com/repos/symfony/security-core/zipball/7ceb30fed93f5ea40ccde3173d1f7712527c0d62", + "reference": "7ceb30fed93f5ea40ccde3173d1f7712527c0d62", "shasum": "" }, "require": { @@ -5999,7 +6464,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v6.3.5" + "source": "https://github.com/symfony/security-core/tree/v6.3.7" }, "funding": [ { @@ -6015,7 +6480,7 @@ "type": "tidelift" } ], - "time": "2023-09-10T17:47:23+00:00" + "time": "2023-10-28T23:11:45+00:00" }, { "name": "symfony/security-csrf", @@ -6087,16 +6552,16 @@ }, { "name": "symfony/security-http", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "47058ea557a4c64ba86e9249651222842bd52e2a" + "reference": "19f7b5f5d20879a976d6d376e359bc975dfc6002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/47058ea557a4c64ba86e9249651222842bd52e2a", - "reference": "47058ea557a4c64ba86e9249651222842bd52e2a", + "url": "https://api.github.com/repos/symfony/security-http/zipball/19f7b5f5d20879a976d6d376e359bc975dfc6002", + "reference": "19f7b5f5d20879a976d6d376e359bc975dfc6002", "shasum": "" }, "require": { @@ -6106,7 +6571,8 @@ "symfony/http-kernel": "^6.3", "symfony/polyfill-mbstring": "~1.0", "symfony/property-access": "^5.4|^6.0", - "symfony/security-core": "^6.3" + "symfony/security-core": "^6.3", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { "symfony/clock": "<6.3", @@ -6154,7 +6620,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v6.3.5" + "source": "https://github.com/symfony/security-http/tree/v6.3.8" }, "funding": [ { @@ -6170,20 +6636,20 @@ "type": "tidelift" } ], - "time": "2023-08-30T06:30:46+00:00" + "time": "2023-11-09T21:20:12+00:00" }, { "name": "symfony/serializer", - "version": "v6.3.5", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "855fc058c8bdbb69f53834f2fdb3876c9bc0ab7c" + "reference": "6eee0fd95f5caa1e77cab29552620ebf8e5b1a5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/855fc058c8bdbb69f53834f2fdb3876c9bc0ab7c", - "reference": "855fc058c8bdbb69f53834f2fdb3876c9bc0ab7c", + "url": "https://api.github.com/repos/symfony/serializer/zipball/6eee0fd95f5caa1e77cab29552620ebf8e5b1a5f", + "reference": "6eee0fd95f5caa1e77cab29552620ebf8e5b1a5f", "shasum": "" }, "require": { @@ -6248,7 +6714,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.3.5" + "source": "https://github.com/symfony/serializer/tree/v6.3.10" }, "funding": [ { @@ -6264,20 +6730,20 @@ "type": "tidelift" } ], - "time": "2023-09-29T16:18:53+00:00" + "time": "2023-12-01T14:25:58+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "shasum": "" }, "require": { @@ -6330,7 +6796,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" }, "funding": [ { @@ -6346,7 +6812,7 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/stopwatch", @@ -6412,16 +6878,16 @@ }, { "name": "symfony/string", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339" + "reference": "56427887aeaf540e9bbd121ad6c43f14ad3ce136" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339", - "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339", + "url": "https://api.github.com/repos/symfony/string/zipball/56427887aeaf540e9bbd121ad6c43f14ad3ce136", + "reference": "56427887aeaf540e9bbd121ad6c43f14ad3ce136", "shasum": "" }, "require": { @@ -6478,7 +6944,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.5" + "source": "https://github.com/symfony/string/tree/v6.3.9" }, "funding": [ { @@ -6494,20 +6960,20 @@ "type": "tidelift" } ], - "time": "2023-09-18T10:38:32+00:00" + "time": "2023-11-28T20:40:29+00:00" }, { "name": "symfony/translation", - "version": "v6.3.3", + "version": "v6.3.7", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd" + "reference": "30212e7c87dcb79c83f6362b00bde0e0b1213499" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd", - "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd", + "url": "https://api.github.com/repos/symfony/translation/zipball/30212e7c87dcb79c83f6362b00bde0e0b1213499", + "reference": "30212e7c87dcb79c83f6362b00bde0e0b1213499", "shasum": "" }, "require": { @@ -6573,7 +7039,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.3.3" + "source": "https://github.com/symfony/translation/tree/v6.3.7" }, "funding": [ { @@ -6589,20 +7055,20 @@ "type": "tidelift" } ], - "time": "2023-07-31T07:08:24+00:00" + "time": "2023-10-28T23:11:45+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86" + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", "shasum": "" }, "require": { @@ -6651,7 +7117,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" }, "funding": [ { @@ -6667,20 +7133,20 @@ "type": "tidelift" } ], - "time": "2023-05-30T17:17:10+00:00" + "time": "2023-07-25T15:08:44+00:00" }, { "name": "symfony/twig-bridge", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "18f2cbe1d46ad43c4d3bd45e5e6279172068e064" + "reference": "c51407623959a626784ff302419026f56dc4e1ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/18f2cbe1d46ad43c4d3bd45e5e6279172068e064", - "reference": "18f2cbe1d46ad43c4d3bd45e5e6279172068e064", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/c51407623959a626784ff302419026f56dc4e1ba", + "reference": "c51407623959a626784ff302419026f56dc4e1ba", "shasum": "" }, "require": { @@ -6759,7 +7225,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.3.5" + "source": "https://github.com/symfony/twig-bridge/tree/v6.3.8" }, "funding": [ { @@ -6775,20 +7241,20 @@ "type": "tidelift" } ], - "time": "2023-09-12T06:57:20+00:00" + "time": "2023-11-09T21:20:12+00:00" }, { "name": "symfony/twig-bundle", - "version": "v6.3.0", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "d0cd4d1675c0582d27c2e8bb0dc27c0303d8e3ea" + "reference": "82429320fe931dd50825ec08140c54b3a315bf79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/d0cd4d1675c0582d27c2e8bb0dc27c0303d8e3ea", - "reference": "d0cd4d1675c0582d27c2e8bb0dc27c0303d8e3ea", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/82429320fe931dd50825ec08140c54b3a315bf79", + "reference": "82429320fe931dd50825ec08140c54b3a315bf79", "shasum": "" }, "require": { @@ -6844,7 +7310,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v6.3.0" + "source": "https://github.com/symfony/twig-bundle/tree/v6.3.8" }, "funding": [ { @@ -6860,20 +7326,20 @@ "type": "tidelift" } ], - "time": "2023-05-06T09:53:41+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/validator", - "version": "v6.3.5", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "48e815ba3b5eb72e632588dbf7ea2dc4e608ee47" + "reference": "c118889931856af47b0732b609f3ac2ddccd1da6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/48e815ba3b5eb72e632588dbf7ea2dc4e608ee47", - "reference": "48e815ba3b5eb72e632588dbf7ea2dc4e608ee47", + "url": "https://api.github.com/repos/symfony/validator/zipball/c118889931856af47b0732b609f3ac2ddccd1da6", + "reference": "c118889931856af47b0732b609f3ac2ddccd1da6", "shasum": "" }, "require": { @@ -6940,7 +7406,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.3.5" + "source": "https://github.com/symfony/validator/tree/v6.3.9" }, "funding": [ { @@ -6956,20 +7422,20 @@ "type": "tidelift" } ], - "time": "2023-09-29T07:41:15+00:00" + "time": "2023-11-29T07:44:47+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5" + "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3d9999376be5fea8de47752837a3e1d1c5f69ef5", - "reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/81acabba9046550e89634876ca64bfcd3c06aa0a", + "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a", "shasum": "" }, "require": { @@ -7024,7 +7490,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.3.5" + "source": "https://github.com/symfony/var-dumper/tree/v6.3.8" }, "funding": [ { @@ -7040,20 +7506,20 @@ "type": "tidelift" } ], - "time": "2023-09-12T10:11:35+00:00" + "time": "2023-11-08T10:42:36+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.3.4", + "version": "v6.3.10", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691" + "reference": "7bfcf232a9c7e4acad00e96774e340eb86d10bf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/df1f8aac5751871b83d30bf3e2c355770f8f0691", - "reference": "df1f8aac5751871b83d30bf3e2c355770f8f0691", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/7bfcf232a9c7e4acad00e96774e340eb86d10bf0", + "reference": "7bfcf232a9c7e4acad00e96774e340eb86d10bf0", "shasum": "" }, "require": { @@ -7098,7 +7564,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.3.4" + "source": "https://github.com/symfony/var-exporter/tree/v6.3.10" }, "funding": [ { @@ -7114,7 +7580,7 @@ "type": "tidelift" } ], - "time": "2023-08-16T18:14:47+00:00" + "time": "2023-11-29T16:00:50+00:00" }, { "name": "symfony/web-link", @@ -7201,16 +7667,16 @@ }, { "name": "symfony/yaml", - "version": "v6.3.3", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add" + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e23292e8c07c85b971b44c1c4b87af52133e2add", - "reference": "e23292e8c07c85b971b44c1c4b87af52133e2add", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3493af8a8dad7fa91c77fa473ba23ecd95334a92", + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92", "shasum": "" }, "require": { @@ -7253,7 +7719,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.3.3" + "source": "https://github.com/symfony/yaml/tree/v6.3.8" }, "funding": [ { @@ -7269,31 +7735,31 @@ "type": "tidelift" } ], - "time": "2023-07-31T07:08:24+00:00" + "time": "2023-11-06T10:58:05+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.7.1", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3" + "reference": "32807183753de0388c8e59f7ac2d13bb47311140" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3", - "reference": "f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/32807183753de0388c8e59f7ac2d13bb47311140", + "reference": "32807183753de0388c8e59f7ac2d13bb47311140", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/twig-bundle": "^5.4|^6.0", - "twig/twig": "^2.7|^3.0" + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "twig/twig": "^3.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4|^6.3", + "symfony/phpunit-bridge": "^6.4|^7.0", "twig/cache-extra": "^3.0", "twig/cssinliner-extra": "^2.12|^3.0", "twig/html-extra": "^2.12|^3.0", @@ -7331,7 +7797,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.7.1" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.8.0" }, "funding": [ { @@ -7343,29 +7809,29 @@ "type": "tidelift" } ], - "time": "2023-07-29T15:34:56+00:00" + "time": "2023-11-21T14:02:01+00:00" }, { "name": "twig/intl-extra", - "version": "v3.7.1", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "4f4fe572f635534649cc069e1dafe4a8ad63774d" + "reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/4f4fe572f635534649cc069e1dafe4a8ad63774d", - "reference": "4f4fe572f635534649cc069e1dafe4a8ad63774d", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/7b3db67c700735f473a265a97e1adaeba3e6ca0c", + "reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/intl": "^5.4|^6.0", - "twig/twig": "^2.7|^3.0" + "php": ">=7.2.5", + "symfony/intl": "^5.4|^6.0|^7.0", + "twig/twig": "^3.0" }, "require-dev": { - "symfony/phpunit-bridge": "^5.4|^6.3" + "symfony/phpunit-bridge": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7395,7 +7861,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.7.1" + "source": "https://github.com/twigphp/intl-extra/tree/v3.8.0" }, "funding": [ { @@ -7407,30 +7873,98 @@ "type": "tidelift" } ], - "time": "2023-07-29T15:34:56+00:00" + "time": "2023-11-21T17:27:48+00:00" }, { - "name": "twig/string-extra", - "version": "v3.7.1", + "name": "twig/markdown-extra", + "version": "v3.8.0", "source": { "type": "git", - "url": "https://github.com/twigphp/string-extra.git", - "reference": "7230d630a25e91cd91a2bd8e2f0e872962507eab" + "url": "https://github.com/twigphp/markdown-extra.git", + "reference": "b6e4954ab60030233df5d293886b5404558daac8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/string-extra/zipball/7230d630a25e91cd91a2bd8e2f0e872962507eab", - "reference": "7230d630a25e91cd91a2bd8e2f0e872962507eab", + "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/b6e4954ab60030233df5d293886b5404558daac8", + "reference": "b6e4954ab60030233df5d293886b5404558daac8", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/string": "^5.4|^6.0", - "symfony/translation-contracts": "^1.1|^2|^3", - "twig/twig": "^2.7|^3.0" + "twig/twig": "^3.0" }, "require-dev": { - "symfony/phpunit-bridge": "^5.4|^6.3" + "erusev/parsedown": "^1.7", + "league/commonmark": "^1.0|^2.0", + "league/html-to-markdown": "^4.8|^5.0", + "michelf/php-markdown": "^1.8|^2.0", + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Twig\\Extra\\Markdown\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for Markdown", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "markdown", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/markdown-extra/tree/v3.8.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2023-11-21T14:02:01+00:00" + }, + { + "name": "twig/string-extra", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/string-extra.git", + "reference": "b0c9037d96baff79abe368dc092a59b726517548" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/string-extra/zipball/b0c9037d96baff79abe368dc092a59b726517548", + "reference": "b0c9037d96baff79abe368dc092a59b726517548", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7462,7 +7996,7 @@ "unicode" ], "support": { - "source": "https://github.com/twigphp/string-extra/tree/v3.7.1" + "source": "https://github.com/twigphp/string-extra/tree/v3.8.0" }, "funding": [ { @@ -7474,30 +8008,31 @@ "type": "tidelift" } ], - "time": "2023-07-29T15:34:56+00:00" + "time": "2023-11-21T14:02:01+00:00" }, { "name": "twig/twig", - "version": "v3.7.1", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554" + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554", - "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3" + "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" }, "type": "library", "autoload": { @@ -7533,7 +8068,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.7.1" + "source": "https://github.com/twigphp/Twig/tree/v3.8.0" }, "funding": [ { @@ -7545,7 +8080,7 @@ "type": "tidelift" } ], - "time": "2023-08-28T11:09:02+00:00" + "time": "2023-11-21T18:54:41+00:00" }, { "name": "webmozart/assert", @@ -8262,16 +8797,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.13", + "version": "9.6.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", "shasum": "" }, "require": { @@ -8345,7 +8880,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" }, "funding": [ { @@ -8361,7 +8896,7 @@ "type": "tidelift" } ], - "time": "2023-09-19T05:39:22+00:00" + "time": "2023-12-01T16:55:19+00:00" }, { "name": "sebastian/cli-parser", @@ -9329,16 +9864,16 @@ }, { "name": "symfony/browser-kit", - "version": "v6.3.2", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "ca4a988488f61ac18f8f845445eabdd36f89aa8d" + "reference": "e270297dbee59168274c2b535ab1bccd593e6ffe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/ca4a988488f61ac18f8f845445eabdd36f89aa8d", - "reference": "ca4a988488f61ac18f8f845445eabdd36f89aa8d", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e270297dbee59168274c2b535ab1bccd593e6ffe", + "reference": "e270297dbee59168274c2b535ab1bccd593e6ffe", "shasum": "" }, "require": { @@ -9377,7 +9912,7 @@ "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/v6.3.2" + "source": "https://github.com/symfony/browser-kit/tree/v6.3.8" }, "funding": [ { @@ -9393,7 +9928,7 @@ "type": "tidelift" } ], - "time": "2023-07-06T06:56:43+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/css-selector", @@ -9536,16 +10071,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v6.3.4", + "version": "v6.3.9", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1" + "reference": "b7065c123ae977a008568a3d016a17a110df7a8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1", - "reference": "3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b7065c123ae977a008568a3d016a17a110df7a8e", + "reference": "b7065c123ae977a008568a3d016a17a110df7a8e", "shasum": "" }, "require": { @@ -9583,7 +10118,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.3.4" + "source": "https://github.com/symfony/dom-crawler/tree/v6.3.9" }, "funding": [ { @@ -9599,20 +10134,20 @@ "type": "tidelift" } ], - "time": "2023-08-01T07:43:40+00:00" + "time": "2023-11-20T16:36:29+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.51.1", + "version": "v1.52.0", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "0890fd3cf1e2a5221f9b3c6ee1769c537aef683d" + "reference": "112f9466c94a46ca33dc441eee59a12cd1790757" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/0890fd3cf1e2a5221f9b3c6ee1769c537aef683d", - "reference": "0890fd3cf1e2a5221f9b3c6ee1769c537aef683d", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/112f9466c94a46ca33dc441eee59a12cd1790757", + "reference": "112f9466c94a46ca33dc441eee59a12cd1790757", "shasum": "" }, "require": { @@ -9675,7 +10210,7 @@ ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.51.1" + "source": "https://github.com/symfony/maker-bundle/tree/v1.52.0" }, "funding": [ { @@ -9691,20 +10226,20 @@ "type": "tidelift" } ], - "time": "2023-09-18T18:17:31+00:00" + "time": "2023-10-31T18:23:49+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.3.2", + "version": "v6.4.1", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "e020e1efbd1b42cb670fcd7d19a25abbddba035d" + "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/e020e1efbd1b42cb670fcd7d19a25abbddba035d", - "reference": "e020e1efbd1b42cb670fcd7d19a25abbddba035d", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/cca5373a41d45edbeaf38b7b67f376da2205ff95", + "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95", "shasum": "" }, "require": { @@ -9715,7 +10250,7 @@ }, "require-dev": { "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/error-handler": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/polyfill-php81": "^1.27" }, "bin": [ @@ -9756,7 +10291,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.3.2" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.1" }, "funding": [ { @@ -9772,26 +10307,26 @@ "type": "tidelift" } ], - "time": "2023-07-12T16:00:22+00:00" + "time": "2023-12-01T09:25:07+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.3.2", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "6101b5ab7857c373d237e121f9060c68b32e1373" + "reference": "4167c20cbdbb1152007fa731718c8c0362f28617" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/6101b5ab7857c373d237e121f9060c68b32e1373", - "reference": "6101b5ab7857c373d237e121f9060c68b32e1373", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/4167c20cbdbb1152007fa731718c8c0362f28617", + "reference": "4167c20cbdbb1152007fa731718c8c0362f28617", "shasum": "" }, "require": { "php": ">=8.1", "symfony/config": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", + "symfony/framework-bundle": "^5.4|^6.0,<6.4", "symfony/http-kernel": "^6.3", "symfony/routing": "^5.4|^6.0", "symfony/twig-bundle": "^5.4|^6.0", @@ -9837,7 +10372,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.3.2" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.3.8" }, "funding": [ { @@ -9853,20 +10388,20 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:17:28+00:00" + "time": "2023-10-31T14:41:59+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -9895,7 +10430,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -9903,7 +10438,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" } ], "aliases": [], diff --git a/config/packages/monolog.yaml b/config/packages/monolog.yaml index 8c9efa9..2b3726f 100644 --- a/config/packages/monolog.yaml +++ b/config/packages/monolog.yaml @@ -48,9 +48,10 @@ when@prod: buffer_size: 50 # How many messages should be saved? Prevent memory leaks nested: type: stream - path: php://stderr + # path: php://stderr + path: "%kernel.logs_dir%/%kernel.environment%.log" level: debug - formatter: monolog.formatter.json + # formatter: monolog.formatter.json console: type: console process_psr_3_messages: false diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml index bd2fce8..210ba05 100644 --- a/config/packages/translation.yaml +++ b/config/packages/translation.yaml @@ -8,7 +8,7 @@ framework: crowdin: dsn: '%env(CROWDIN_DSN)%' domains: ['messages'] - locales: ['en','cs','eo','fr','ka','de','he','it','lv','pl','pt','ru','es','uk'] + locales: ['en','cs','nl','eo','fr', 'ja', 'ka','de','he','it','lv','pl','pt','ru','es','uk'] # loco: # dsn: '%env(LOCO_DSN)%' # lokalise: diff --git a/config/routes.yaml b/config/routes.yaml index 5394777..41ef814 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -3,6 +3,3 @@ controllers: path: ../src/Controller/ namespace: App\Controller type: attribute - # this prefix using in official build URLs. - # replace to / if you hosted YGGtracker instance in the document root - prefix: '/yggtracker' diff --git a/config/services.yaml b/config/services.yaml index 4831621..b515a42 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -6,16 +6,32 @@ parameters: app.version: '%env(APP_VERSION)%' app.name: '%env(APP_NAME)%' + app.key: '%env(APP_KEY)%' app.pagination: '%env(APP_PAGINATION)%' app.trackers: '%env(APP_TRACKERS)%' + app.crawlers: '%env(APP_CRAWLERS)%' app.locales: '%env(APP_LOCALES)%' + app.categories: '%env(APP_CATEGORIES)%' app.themes: '%env(APP_THEMES)%' app.locale: '%env(APP_LOCALE)%' app.theme: '%env(APP_THEME)%' app.sensitive: '%env(APP_SENSITIVE)%' app.approved: '%env(APP_APPROVED)%' app.yggdrasil: '%env(APP_YGGDRASIL)%' + app.posters: '%env(APP_POSTERS)%' app.torrent.size.max: '%env(APP_TORRENT_FILE_SIZE_MAX)%' + app.torrent.poster.size.max: '%env(APP_TORRENT_POSTER_FILE_SIZE_MAX)%' + app.torrent.wanted.ftp.enabled: '%env(APP_TORRENT_WANTED_FTP_ENABLED)%' + app.torrent.wanted.ftp.folder: '%env(APP_TORRENT_WANTED_FTP_FOLDER)%' + app.torrent.wanted.ftp.approved: '%env(APP_TORRENT_WANTED_FTP_APPROVED_ONLY)%' + app.index.torrent.name.enabled: '%env(APP_INDEX_TORRENT_NAME_ENABLED)%' + app.index.torrent.filenames.enabled: '%env(APP_INDEX_TORRENT_FILENAMES_ENABLED)%' + app.index.torrent.hash.v1.enabled: '%env(APP_INDEX_TORRENT_HASH_V1_ENABLED)%' + app.index.torrent.hash.v2.enabled: '%env(APP_INDEX_TORRENT_HASH_V2_ENABLED)%' + app.index.torrent.source.enabled: '%env(APP_INDEX_TORRENT_SOURCE_ENABLED)%' + app.index.torrent.comment.enabled: '%env(APP_INDEX_TORRENT_COMMENT_ENABLED)%' + app.index.word.length.min: '%env(APP_INDEX_WORD_LENGTH_MIN)%' + app.index.word.length.max: '%env(APP_INDEX_WORD_LENGTH_MAX)%' services: # default configuration for services in *this* file diff --git a/migrations/Version20231026163131.php b/migrations/Version20231026163131.php new file mode 100644 index 0000000..51c0288 --- /dev/null +++ b/migrations/Version20231026163131.php @@ -0,0 +1,37 @@ +addSql('ALTER TABLE torrent ADD COLUMN status BOOLEAN DEFAULT 1'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TEMPORARY TABLE __temp__torrent AS SELECT id, user_id, added, scraped, locales, sensitive, approved, md5file, keywords, seeders, peers, leechers FROM torrent'); + $this->addSql('DROP TABLE torrent'); + $this->addSql('CREATE TABLE torrent (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, user_id INTEGER NOT NULL, added INTEGER NOT NULL, scraped INTEGER DEFAULT NULL, locales CLOB NOT NULL --(DC2Type:simple_array) + , sensitive BOOLEAN NOT NULL, approved BOOLEAN NOT NULL, md5file VARCHAR(32) NOT NULL, keywords CLOB DEFAULT NULL --(DC2Type:simple_array) + , seeders INTEGER DEFAULT NULL, peers INTEGER DEFAULT NULL, leechers INTEGER DEFAULT NULL)'); + $this->addSql('INSERT INTO torrent (id, user_id, added, scraped, locales, sensitive, approved, md5file, keywords, seeders, peers, leechers) SELECT id, user_id, added, scraped, locales, sensitive, approved, md5file, keywords, seeders, peers, leechers FROM __temp__torrent'); + $this->addSql('DROP TABLE __temp__torrent'); + } +} diff --git a/migrations/Version20231029184600.php b/migrations/Version20231029184600.php new file mode 100644 index 0000000..634e2a1 --- /dev/null +++ b/migrations/Version20231029184600.php @@ -0,0 +1,35 @@ +addSql('CREATE TABLE torrent_poster (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, torrent_id INTEGER NOT NULL, user_id INTEGER NOT NULL, added INTEGER NOT NULL, approved BOOLEAN NOT NULL, md5file VARCHAR(32) NOT NULL)'); + $this->addSql('ALTER TABLE user ADD COLUMN posters BOOLEAN NOT NULL DEFAULT 1'); + $this->addSql('ALTER TABLE torrent ADD COLUMN torrent_poster_id BOOLEAN NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE torrent_poster'); + $this->addSql('ALTER TABLE user DROP COLUMN posters'); + $this->addSql('ALTER TABLE torrent DROP COLUMN torrent_poster_id'); + } +} diff --git a/migrations/Version20231030225418.php b/migrations/Version20231030225418.php new file mode 100644 index 0000000..e43e71d --- /dev/null +++ b/migrations/Version20231030225418.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE torrent_poster ADD COLUMN position BOOLEAN NOT NULL DEFAULT "center"'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE torrent_poster DROP COLUMN position'); + } +} diff --git a/migrations/Version20231103235504.php b/migrations/Version20231103235504.php new file mode 100644 index 0000000..1ec3213 --- /dev/null +++ b/migrations/Version20231103235504.php @@ -0,0 +1,37 @@ +addSql('CREATE TABLE torrent_categories (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, torrent_id INTEGER NOT NULL, user_id INTEGER NOT NULL, added INTEGER NOT NULL, value CLOB NOT NULL --(DC2Type:simple_array) + , approved BOOLEAN NOT NULL)'); + $this->addSql('ALTER TABLE user ADD COLUMN categories CLOB DEFAULT "other"'); + $this->addSql('ALTER TABLE torrent ADD COLUMN categories CLOB DEFAULT "other"'); + $this->addSql('UPDATE user SET categories = "movie,series,tv,animation,music,game,audiobook,podcast,book,archive,picture,software,other"'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE torrent_categories'); + $this->addSql('ALTER TABLE user DROP COLUMN categories'); + $this->addSql('ALTER TABLE torrent DROP COLUMN categories'); + } +} diff --git a/public/asset/default/css/framework.css b/public/asset/default/css/framework.css index 0a90826..0ca71e6 100644 --- a/public/asset/default/css/framework.css +++ b/public/asset/default/css/framework.css @@ -15,6 +15,18 @@ float: left; } +.word-break { + word-break: break-word; +} + +.overflow-auto { + overflow: auto; +} + +.float-left { + float: left; +} + .float-right { float: right; } @@ -148,10 +160,6 @@ a.button-green:hover { vertical-align: middle; } -.top--2-px { - top: -2px; -} - .top-2-px { top: 2px; } @@ -189,21 +197,36 @@ a.button-green:hover { } .border-color-default { - border: 1px #5d627d solid; + border: 1px rgba(93, 98, 125, .6) solid; } .border-bottom-default { - border-bottom: 1px #5d627d solid; + border-bottom: 1px rgba(93, 98, 125, .6) solid; } .border-top-default { - border-top: 1px #5d627d solid; + border-top: 1px rgba(93, 98, 125, .6) solid; +} + +.border-bottom-dashed { + border-bottom: 1px rgba(93, 98, 125, .6) dashed; +} + +.border-top-dashed { + border-top: 1px rgba(93, 98, 125, .6) dashed; } .border-width-2-px { border-width: 2px; } +.background-poster { + background-position: center; + background-repeat: no-repeat; + background-size: cover; + background-blend-mode: soft-light; +} + .background-color-night { background-color: #34384f; } @@ -354,6 +377,15 @@ a:visited.background-color-hover-night-light:hover { padding-right: 24px; } +.padding-y-24-px { + padding-top: 24px; + padding-bottom: 24px; +} + +.margin-t-4-px { + margin-top: 4px; +} + .margin-l-4-px { margin-left: 4px; } diff --git a/src/Controller/ActivityController.php b/src/Controller/ActivityController.php index 643371e..c8bb152 100644 --- a/src/Controller/ActivityController.php +++ b/src/Controller/ActivityController.php @@ -17,6 +17,9 @@ class ActivityController extends AbstractController #[Route( '/{_locale}/activity', name: 'activity_all', + requirements: [ + '_locale' => '%app.locales%' + ], methods: [ 'GET' @@ -64,9 +67,6 @@ class ActivityController extends AbstractController #[Route( '/{_locale}/rss/activity', name: 'rss_activity', - defaults: [ - '_locale' => '%app.locale%' - ], requirements: [ '_locale' => '%app.locales%' ], @@ -112,7 +112,6 @@ class ActivityController extends AbstractController '/{_locale}/rss/activity/user/{userId}', name: 'rss_activity_user', defaults: [ - '_locale' => '%app.locale%', 'userId' => 0 ], requirements: [ @@ -170,11 +169,8 @@ class ActivityController extends AbstractController #[Route( '/{_locale}/rss/activity/torrent/{torrentId}', name: 'rss_activity_torrent', - defaults: [ - '_locale' => '%app.locale%', - ], requirements: [ - '_locale' => '%app.locales%', + '_locale' => '%app.locales%', 'torrentId' => '\d+' ], methods: @@ -564,6 +560,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -610,6 +607,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -656,6 +654,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -703,6 +702,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -749,6 +749,141 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName() + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + // Torrent Wanted + case $activity::EVENT_TORRENT_WANTED_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/wanted/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName() + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + // Torrent Status + case $activity::EVENT_TORRENT_STATUS_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/status/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName() + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_STATUS_DELETE: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/status/delete' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -796,6 +931,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -848,6 +984,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -900,6 +1037,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -952,6 +1090,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -977,6 +1116,219 @@ class ActivityController extends AbstractController break; + /// Torrent Categories + case $activity::EVENT_TORRENT_CATEGORIES_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/categories/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'categories' => [ + 'id' => $activity->getData()['torrentCategoriesId'], + 'exist' => $torrentService->getTorrentCategories( + $activity->getData()['torrentCategoriesId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_CATEGORIES_DELETE: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/categories/delete' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'categories' => [ + 'id' => $activity->getData()['torrentCategoriesId'], + 'exist' => $torrentService->getTorrentCategories( + $activity->getData()['torrentCategoriesId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_CATEGORIES_APPROVE_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/categories/approve/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'categories' => [ + 'id' => $activity->getData()['torrentCategoriesId'], + 'exist' => $torrentService->getTorrentCategories( + $activity->getData()['torrentCategoriesId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_CATEGORIES_APPROVE_DELETE: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/categories/approve/delete' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'categories' => [ + 'id' => $activity->getData()['torrentCategoriesId'], + 'exist' => $torrentService->getTorrentCategories( + $activity->getData()['torrentCategoriesId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + /// Torrent Sensitive case $activity::EVENT_TORRENT_SENSITIVE_ADD: @@ -1005,6 +1357,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -1057,6 +1410,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -1109,6 +1463,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -1161,6 +1516,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName(), @@ -1186,6 +1542,219 @@ class ActivityController extends AbstractController break; + /// Torrent Poster + case $activity::EVENT_TORRENT_POSTER_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/poster/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'poster' => [ + 'id' => $activity->getData()['torrentPosterId'], + 'exist' => $torrentService->getTorrentPoster( + $activity->getData()['torrentPosterId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_POSTER_DELETE: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/poster/delete' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'poster' => [ + 'id' => $activity->getData()['torrentPosterId'], + 'exist' => $torrentService->getTorrentPoster( + $activity->getData()['torrentPosterId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_POSTER_APPROVE_ADD: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/poster/approve/add' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'poster' => [ + 'id' => $activity->getData()['torrentPosterId'], + 'exist' => $torrentService->getTorrentPoster( + $activity->getData()['torrentPosterId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + + case $activity::EVENT_TORRENT_POSTER_APPROVE_DELETE: + + // Init torrent + if (!$torrent = $torrentService->getTorrent($activity->getTorrentId())) + { + throw $this->createNotFoundException(); + } + + return $this->render( + 'default/activity/event/torrent/poster/approve/delete' . $extension, + [ + 'id' => $activity->getId(), + 'added' => $activity->getAdded(), + 'user' => + [ + 'id' => $activity->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $activity->getUserId() + )->getAddress() + ) + ], + 'torrent' => + [ + 'id' => $torrent->getId(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'name' => $torrentService->readTorrentFileByTorrentId( + $torrent->getId() + )->getName(), + 'poster' => [ + 'id' => $activity->getData()['torrentPosterId'], + 'exist' => $torrentService->getTorrentPoster( + $activity->getData()['torrentPosterId'] // could be deleted by moderator, remove links + ) + ] + ], + 'session' => + [ + 'user' => + [ + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), + ] + ] + ] + ); + + break; + /// Torrent star case $activity::EVENT_TORRENT_STAR_ADD: @@ -1214,6 +1783,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -1260,6 +1830,7 @@ class ActivityController extends AbstractController 'id' => $torrent->getId(), 'sensitive' => $torrent->isSensitive(), 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), 'name' => $torrentService->readTorrentFileByTorrentId( $torrent->getId() )->getName() @@ -1318,6 +1889,7 @@ class ActivityController extends AbstractController $this->getParameter('app.theme'), $this->getParameter('app.sensitive'), $this->getParameter('app.yggdrasil'), + $this->getParameter('app.posters'), $this->getParameter('app.approved') ); diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index 30b06b6..8cb63bc 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -9,19 +9,123 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use App\Service\UserService; +use App\Service\TorrentService; use App\Service\ActivityService; class SearchController extends AbstractController { public function module( - ?string $query, - ?string $type + Request $request, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService ): Response { + // Defaults + $locales = []; + $categories = []; + $sensitive = []; + + // Request + $query = $request->get('query') ? urldecode($request->get('query')) : ''; + $filter = $request->get('filter') ? true : false; + + // Extended search + if ($filter) + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Keywords + $keywords = explode(' ', $query); + + // Locales + foreach (explode('|', $this->getParameter('app.locales')) as $locale) + { + + if ($request->get('locales')) + { + $checked = in_array($locale, (array) $request->get('locales')); + } + + else + { + $checked = in_array($locale, $user->getLocales()); + } + + $locales[] = + [ + 'value' => $locale, + 'checked' => $checked, + 'total' => $torrentService->findTorrentsTotal( + 0, + $keywords, + [$locale], + $request->get('categories') ? $request->get('categories') : $user->getCategories(), + $request->get('sensitive') ? null : false, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, + ) + ]; + } + + // Categories + foreach (explode('|', $this->getParameter('app.categories')) as $category) + { + if ($request->get('categories')) + { + $checked = in_array($category, (array) $request->get('categories')); + } + + else + { + $checked = in_array($category, $user->getCategories()); + } + + $categories[] = + [ + 'value' => $category, + 'checked' => $checked, + 'total' => $torrentService->findTorrentsTotal( + 0, + $keywords, + $request->get('locales') ? $request->get('locales') : $user->getLocales(), + [$category], + $request->get('sensitive') ? null : false, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, + ) + ]; + } + + // Sensitive + $sensitive = + [ + 'checked' => $request->get('sensitive'), + 'total' => $torrentService->findTorrentsTotal( + 0, + $keywords, + $request->get('locales') ? $request->get('locales') : $user->getLocales(), + $request->get('categories') ? $request->get('categories') : $user->getCategories(), + true, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, + ) + ]; + } + return $this->render( 'default/search/module.html.twig', [ - 'query' => $query, + 'query' => $query, + 'filter' => $filter, + 'sensitive' => $sensitive, + 'locales' => $locales, + 'categories' => $categories, ] ); } @@ -44,6 +148,7 @@ class SearchController extends AbstractController $this->getParameter('app.theme'), $this->getParameter('app.sensitive'), $this->getParameter('app.yggdrasil'), + $this->getParameter('app.posters'), $this->getParameter('app.approved') ); diff --git a/src/Controller/TorrentController.php b/src/Controller/TorrentController.php index a1ea018..38205db 100644 --- a/src/Controller/TorrentController.php +++ b/src/Controller/TorrentController.php @@ -21,6 +21,7 @@ class TorrentController extends AbstractController name: 'torrent_info', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', ], methods: @@ -56,13 +57,17 @@ class TorrentController extends AbstractController } // Sensitive filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && $user->isSensitive()) + // @TODO add blur effect or sensitive notice instead of 404 on direct request #37 + /* + if (!$user->isModerator() && $user->isSensitive() && $torrent->isSensitive()) { throw $this->createNotFoundException(); } + */ - // Approved filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && !$torrent->isApproved()) + // Access filter + if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && + (!$torrent->isStatus() || !$torrent->isApproved())) { throw $this->createNotFoundException(); } @@ -104,17 +109,38 @@ class TorrentController extends AbstractController // Init page $page = $request->get('page') ? (int) $request->get('page') : 1; + // Poster + if ($user->isPosters() && $torrent->getTorrentPosterId()) + { + $torrentPoster = $torrentService->getTorrentPoster( + $torrent->getTorrentPosterId() + ); + + $poster = [ + 'position' => $torrentPoster->getPosition(), + 'url' => $request->getScheme() . '://' . + $request->getHttpHost() . + $request->getBasePath() . + $torrentService->getImageUriByTorrentPosterId( + $torrentPoster->getId() + ) + ]; + } + + else + { + $poster = false; + } + // Render template return $this->render('default/torrent/info.html.twig', [ 'session' => [ - 'user' => $user - ], - 'user' => - [ + 'user' => $user, 'id' => $user->getId(), - 'moderator' => $user->isModerator() + 'moderator' => $user->isModerator(), + 'owner' => $user->getId() === $torrent->getUserId(), ], 'torrent' => [ @@ -127,10 +153,13 @@ class TorrentController extends AbstractController 'peers' => (int) $torrent->getPeers(), 'leechers' => (int) $torrent->getLeechers(), ], - 'locales' => $torrent->getLocales(), - 'sensitive' => $torrent->isSensitive(), - 'approved' => $torrent->isApproved(), - 'download' => + 'keywords' => $torrent->getKeywords(), + 'locales' => $torrent->getLocales(), + 'categories' => $torrent->getCategories(), + 'sensitive' => $torrent->isSensitive(), + 'approved' => $torrent->isApproved(), + 'status' => $torrent->isStatus(), + 'download' => [ 'file' => [ @@ -153,7 +182,7 @@ class TorrentController extends AbstractController ) ] ], - 'star' => + 'star' => [ 'exist' => (bool) $torrentService->findTorrentStar( $torrent->getId(), @@ -163,7 +192,8 @@ class TorrentController extends AbstractController $torrent->getId() ) ], - 'contributors' => $contributors + 'contributors' => $contributors, + 'poster' => $poster ], 'file' => [ @@ -177,7 +207,9 @@ class TorrentController extends AbstractController 'private' => $file->isPrivate(), 'source' => $file->getSource(), 'comment' => $file->getComment(), - 'tree' => $file->getFileTree(), + 'tree' => $file->getFileTree( + \Rhilip\Bencode\TorrentFile::FILETREE_SORT_NATURAL // #34 @TODO cyrillic + ), //'trackers' => $file->getAnnounceList(), 'hash' => [ @@ -204,6 +236,10 @@ class TorrentController extends AbstractController #[Route( '/{_locale}/search', name: 'torrent_search', + requirements: + [ + '_locale' => '%app.locales%' + ], methods: [ 'GET' @@ -224,23 +260,29 @@ class TorrentController extends AbstractController ); // Init request - $query = $request->get('query') ? explode(' ', $request->get('query')) : []; + $query = $request->get('query') ? explode(' ', urldecode($request->get('query'))) : []; $page = $request->get('page') ? (int) $request->get('page') : 1; // Get total torrents $total = $torrentService->findTorrentsTotal( + $request->get('filter') ? 0 : $user->getId(), $query, - $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null, // show approved content only for regular users + $request->get('filter') ? (array) $request->get('locales') : $user->getLocales(), + $request->get('filter') ? (array) $request->get('categories') : $user->getCategories(), + $request->get('filter') ? ($request->get('sensitive') ? null : false) : ($user->isSensitive() ? false : null), + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, ); $torrents = []; foreach ($torrentService->findTorrents( + $request->get('filter') ? 0 : $user->getId(), $query, - $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null, // show approved content only for regular users + $request->get('filter') ? (array) $request->get('locales') : $user->getLocales(), + $request->get('filter') ? (array) $request->get('categories') : $user->getCategories(), + $request->get('filter') ? ($request->get('sensitive') ? null : false) : ($user->isSensitive() ? false : null), + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, $this->getParameter('app.pagination'), ($page - 1) * $this->getParameter('app.pagination') ) as $torrent) @@ -251,26 +293,69 @@ class TorrentController extends AbstractController throw $this->createNotFoundException(); // @TODO exception } - // Generate keywords + // Generate keywords by extension $keywords = []; - foreach ($torrent->getKeywords() as $keyword) + + foreach ($file->getFileList() as $item) { - if (in_array($keyword, $query)) + if ($keyword = pathinfo($item['path'], PATHINFO_EXTENSION)) { - $keywords[] = urlencode($keyword); + $keyword = mb_strtolower($keyword); + + if (isset($keywords[$keyword])) + { + $keywords[$keyword] = $keywords[$keyword] + (int) $item['size']; + } + + else + { + $keywords[$keyword] = 0; + } } } + arsort($keywords); + + // Poster + if ($user->isPosters() && $torrent->getTorrentPosterId()) + { + $torrentPoster = $torrentService->getTorrentPoster( + $torrent->getTorrentPosterId() + ); + + $poster = [ + 'position' => $torrentPoster->getPosition(), + 'url' => $request->getScheme() . '://' . + $request->getHttpHost() . + $request->getBasePath() . + $torrentService->getImageUriByTorrentPosterId( + $torrentPoster->getId() + ) + ]; + } + + else + { + $poster = false; + } + + // Push torrent $torrents[] = [ 'id' => $torrent->getId(), 'added' => $torrent->getAdded(), 'approved' => $torrent->isApproved(), 'sensitive' => $torrent->isSensitive(), + 'status' => $torrent->isStatus(), 'file' => [ 'name' => $file->getName(), 'size' => $file->getSize(), + 'hash' => + [ + 'v1' => $file->getInfoHashV1(false), + 'v2' => $file->getInfoHashV2(false) + ], ], 'scrape' => [ @@ -321,18 +406,29 @@ class TorrentController extends AbstractController $torrent->getId() ) ], + 'poster' => $poster ]; } return $this->render('default/torrent/list.html.twig', [ - 'query' => $request->query->get('query'), - 'torrents' => $torrents + 'query' => $request->get('query') ? urldecode($request->get('query')) : '', + 'torrents' => $torrents, + 'pagination' => + [ + 'page' => $page, + 'pages' => ceil($total / $this->getParameter('app.pagination')), + 'total' => $total + ] ]); } #[Route( '/{_locale}', name: 'torrent_recent', + requirements: + [ + '_locale' => '%app.locales%' + ], methods: [ 'GET' @@ -357,19 +453,25 @@ class TorrentController extends AbstractController // Get total torrents $total = $torrentService->findTorrentsTotal( + $user->getId(), [], $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null, // show approved content only for regular users + $user->getCategories(), + $user->isSensitive() ? false : null, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, ); // Create torrents list $torrents = []; foreach ($torrentService->findTorrents( + $user->getId(), [], $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null, // show approved content only for regular users + $user->getCategories(), + $user->isSensitive() ? false : null, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, $this->getParameter('app.pagination'), ($page - 1) * $this->getParameter('app.pagination') ) as $torrent) @@ -380,27 +482,69 @@ class TorrentController extends AbstractController throw $this->createNotFoundException(); // @TODO exception } - // Generate keywords + // Generate keywords by extension $keywords = []; - $query = explode(' ', mb_strtolower($request->query->get('query'))); - foreach ($torrent->getKeywords() as $keyword) + + foreach ($file->getFileList() as $item) { - if (in_array($keyword, $query)) + if ($keyword = pathinfo($item['path'], PATHINFO_EXTENSION)) { - $keywords[] = urlencode($keyword); + $keyword = mb_strtolower($keyword); + + if (isset($keywords[$keyword])) + { + $keywords[$keyword] = $keywords[$keyword] + (int) $item['size']; + } + + else + { + $keywords[$keyword] = 0; + } } } + arsort($keywords); + + // Poster + if ($user->isPosters() && $torrent->getTorrentPosterId()) + { + $torrentPoster = $torrentService->getTorrentPoster( + $torrent->getTorrentPosterId() + ); + + $poster = [ + 'position' => $torrentPoster->getPosition(), + 'url' => $request->getScheme() . '://' . + $request->getHttpHost() . + $request->getBasePath() . + $torrentService->getImageUriByTorrentPosterId( + $torrentPoster->getId() + ) + ]; + } + + else + { + $poster = false; + } + + // Push torrent $torrents[] = [ 'id' => $torrent->getId(), 'added' => $torrent->getAdded(), 'approved' => $torrent->isApproved(), 'sensitive' => $torrent->isSensitive(), + 'status' => $torrent->isStatus(), 'file' => [ 'name' => $file->getName(), 'size' => $file->getSize(), + 'hash' => + [ + 'v1' => $file->getInfoHashV1(false), + 'v2' => $file->getInfoHashV2(false) + ], ], 'scrape' => [ @@ -408,15 +552,6 @@ class TorrentController extends AbstractController 'peers' => (int) $torrent->getPeers(), 'leechers' => (int) $torrent->getLeechers(), ], - 'user' => - [ - 'id' => $torrent->getUserId(), - 'identicon' => $userService->identicon( - $userService->getUser( - $torrent->getUserId() - )->getAddress() - ) - ], 'keywords' => $keywords, 'download' => [ @@ -451,21 +586,24 @@ class TorrentController extends AbstractController $torrent->getId() ) ], + 'poster' => $poster ]; } return $this->render('default/torrent/list.html.twig', [ - 'query' => $request->query->get('query'), - 'torrents' => $torrents + 'torrents' => $torrents, + 'pagination' => + [ + 'page' => $page, + 'pages' => ceil($total / $this->getParameter('app.pagination')), + 'total' => $total + ] ]); } #[Route( '/{_locale}/rss/torrents', name: 'rss_torrents_recent', - defaults: [ - '_locale' => '%app.locale%' - ], requirements: [ '_locale' => '%app.locales%' ], @@ -488,23 +626,33 @@ class TorrentController extends AbstractController $activityService ); + // Init request + $query = $request->get('query') ? explode(' ', urldecode($request->get('query'))) : []; + $page = $request->get('page') ? (int) $request->get('page') : 1; + // Get total torrents $total = $torrentService->findTorrentsTotal( - [], - $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null // show approved content only for regular users + $request->get('filter') ? 0 : $user->getId(), + $query, + $request->get('filter') ? (array) $request->get('locales') : $user->getLocales(), + $request->get('filter') ? (array) $request->get('categories') : $user->getCategories(), + $request->get('filter') ? ($request->get('sensitive') ? null : false) : ($user->isSensitive() ? false : null), + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, ); // Create torrents list $torrents = []; foreach ($torrentService->findTorrents( - [], - $user->getLocales(), - !$user->isModerator() && $user->isSensitive() ? false : null, // hide on sensitive mode enabled or show all - !$user->isModerator() ? true : null, // show approved content only for regular users + $request->get('filter') ? 0 : $user->getId(), + $query, + $request->get('filter') ? (array) $request->get('locales') : $user->getLocales(), + $request->get('filter') ? (array) $request->get('categories') : $user->getCategories(), + $request->get('filter') ? ($request->get('sensitive') ? null : false) : ($user->isSensitive() ? false : null), + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, $this->getParameter('app.pagination'), - 0 + ($page - 1) * $this->getParameter('app.pagination') ) as $torrent) { // Read file @@ -515,9 +663,9 @@ class TorrentController extends AbstractController $torrents[] = [ - 'id' => $torrent->getId(), - 'added' => $torrent->getAdded(), - 'file' => + 'id' => $torrent->getId(), + 'added' => $torrent->getAdded(), + 'file' => [ 'name' => $file->getName(), ], @@ -534,17 +682,204 @@ class TorrentController extends AbstractController return $this->render( 'default/torrent/list.rss.twig', [ - 'query' => $request->query->get('query'), 'torrents' => $torrents ], $response ); } + // #25 + // https://github.com/YGGverse/YGGtracker/issues/25 + #[Route( + '/api/torrents', + methods: + [ + 'GET' + ] + )] + public function jsonRecent( + Request $request, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init request + $query = $request->get('query') ? + explode(' ', urldecode($request->get('query'))) : []; + + $page = $request->get('page') ? + (int) $request->get('page') : 1; + + $filter = $request->get('filter') ? + true : false; + + if ($request->get('locales')) + { + $locales = explode('|', $request->get('locales')); + } + + else + { + $locales = $user->getLocales(); + } + + if ($request->get('categories')) + { + $categories = explode('|', $request->get('categories')); + } + + else + { + $categories = $user->getCategories(); + } + + switch ($request->get('sensitive')) + { + case 'true': + $sensitive = true; + break; + case 'false': + $sensitive = false; + break; + default: + $sensitive = $user->isSensitive() ? false : null; + } + + switch ($request->get('yggdrasil')) + { + case 'true': + $yggdrasil = true; + break; + case 'false': + $yggdrasil = false; + break; + default: + $yggdrasil = $user->isYggdrasil(); + } + + // Init trackers + $trackers = explode('|', $this->getParameter('app.trackers')); + + // Get total torrents + $total = $torrentService->findTorrentsTotal( + $filter ? 0 : $user->getId(), + $query, + $locales, + $categories, + $sensitive, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, + ); + + // Create torrents list + $torrents = []; + foreach ($torrentService->findTorrents( + $filter ? 0 : $user->getId(), + $query, + $locales, + $categories, + $sensitive, + !$user->isModerator() ? true : null, + !$user->isModerator() ? true : null, + $this->getParameter('app.pagination'), + ($page - 1) * $this->getParameter('app.pagination') + ) as $torrent) + { + // Read file + if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId())) + { + throw $this->createNotFoundException(); // @TODO exception + } + + // Apply yggdrasil filters + $file = $this->filterYggdrasil($file, $yggdrasil); + + $torrents[] = + [ + 'torrent' => + [ + 'id' => $torrent->getId(), + 'added' => $torrent->getAdded(), + 'locales' => $torrent->getLocales(), + 'categories' => $torrent->getCategories(), + 'sensitive' => $torrent->isSensitive(), + 'file' => + [ + 'name' => $file->getName(), + 'size' => $file->getSize(), + 'url' => $this->generateUrl( + 'torrent_file', + [ + 'torrentId' => $torrent->getId() + ], + false + ) + ], + 'magnet' => + [ + 'url' => $this->generateUrl( + 'torrent_magnet', + [ + 'torrentId' => $torrent->getId() + ], + false + ), + //'urn' => $file->getMagnetLink() + ], + 'scrape' => + [ + 'seeders' => (int) $torrent->getSeeders(), + 'peers' => (int) $torrent->getPeers(), + 'leechers' => (int) $torrent->getLeechers(), + ], + 'url' => $this->generateUrl( + 'torrent_info', + [ + '_locale' => $user->getLocale(), + 'torrentId' => $torrent->getId(), + ], + false + ) + ], + ]; + } + + return $this->json( + [ + 'version' => time(), + 'tracker' => + [ + 'name' => $this->getParameter('app.name'), + 'version' => $this->getParameter('app.version'), + 'url' => $this->generateUrl( + 'torrent_recent', + [ + '_locale' => $user->getLocale() + ], + false + ) + ], + 'torrents' => $torrents + ] + ); + } + // Forms #[Route( '/{_locale}/submit', name: 'torrent_submit', + requirements: + [ + '_locale' => '%app.locales%' + ], methods: [ 'GET', @@ -585,6 +920,14 @@ class TorrentController extends AbstractController 'value' => $request->get('locales') ? $request->get('locales') : [$request->get('_locale')], ] ], + 'categories' => + [ + 'error' => [], + 'attribute' => + [ + 'value' => $request->get('categories') ? $request->get('categories') : [], + ] + ], 'torrent' => [ 'error' => [], @@ -621,6 +964,25 @@ class TorrentController extends AbstractController $form['locales']['error'][] = $translator->trans('At least one locale required'); } + /// Categories + $categories = []; + if ($request->get('categories')) + { + foreach ((array) $request->get('categories') as $locale) + { + if (in_array($locale, explode('|', $this->getParameter('app.categories')))) + { + $categories[] = $locale; + } + } + } + + //// At least one valid locale required + if (!$categories) + { + $form['categories']['error'][] = $translator->trans('At least one category required'); + } + /// Torrent if ($file = $request->files->get('torrent')) { @@ -649,16 +1011,29 @@ class TorrentController extends AbstractController } // Request is valid - if (empty($form['torrent']['error']) && empty($form['locales']['error'])) + if (empty($form['torrent']['error']) && empty($form['locales']['error']) && empty($form['categories']['error'])) { // Save data $torrent = $torrentService->add( + $file->getPathName(), + + (bool) $this->getParameter('app.index.torrent.name.enabled'), + (bool) $this->getParameter('app.index.torrent.filenames.enabled'), + (bool) $this->getParameter('app.index.torrent.hash.v1.enabled'), + (bool) $this->getParameter('app.index.torrent.hash.v2.enabled'), + (bool) $this->getParameter('app.index.torrent.source.enabled'), + (bool) $this->getParameter('app.index.torrent.comment.enabled'), + (int) $this->getParameter('app.index.word.length.min'), + (int) $this->getParameter('app.index.word.length.max'), + $user->getId(), time(), (array) $locales, + (array) $categories, (bool) $request->get('sensitive'), - $user->isApproved() + $user->isApproved(), + $user->isStatus() ); // Add activity event @@ -683,18 +1058,20 @@ class TorrentController extends AbstractController return $this->render( 'default/torrent/submit.html.twig', [ - 'locales' => explode('|', $this->getParameter('app.locales')), - 'form' => $form, + 'locales' => explode('|', $this->getParameter('app.locales')), + 'categories' => explode('|', $this->getParameter('app.categories')), + 'form' => $form, ] ); } - + // Torrent moderation #[Route( '/{_locale}/torrent/{torrentId}/approve/toggle', name: 'torrent_approve_toggle', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', ], methods: @@ -765,12 +1142,89 @@ class TorrentController extends AbstractController ); } + #[Route( + '/{_locale}/torrent/{torrentId}/status/toggle', + name: 'torrent_status_toggle', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + ], + methods: + [ + 'GET' + ] + )] + public function status( + Request $request, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Check permissions + if (!($user->isModerator() || $user->getId() == $torrent->getUserId())) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Register activity event + if (!$torrent->isStatus()) + { + $activityService->addEventTorrentStatusAdd( + $user->getId(), + $torrent->getId(), + time() + ); + } + + else + { + $activityService->addEventTorrentStatusDelete( + $user->getId(), + $torrent->getId(), + time() + ); + } + + // Update status + $torrentService->toggleTorrentStatus( + $torrent->getId() + ); + + // Redirect back to form + return $this->redirectToRoute( + 'torrent_info', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId() + ] + ); + } + // Torrent locales #[Route( '/{_locale}/torrent/{torrentId}/edit/locales/{torrentLocalesId}', name: 'torrent_locales_edit', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', 'torrentLocalesId' => '\d+', ], @@ -970,6 +1424,7 @@ class TorrentController extends AbstractController name: 'torrent_locales_approve', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', 'torrentLocalesId' => '\d+', ], @@ -1056,6 +1511,7 @@ class TorrentController extends AbstractController name: 'torrent_locales_delete', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', 'torrentLocalesId' => '\d+', ], @@ -1124,13 +1580,371 @@ class TorrentController extends AbstractController ); } + // Torrent categories + #[Route( + '/{_locale}/torrent/{torrentId}/edit/categories/{torrentCategoriesId}', + name: 'torrent_categories_edit', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentCategoriesId' => '\d+', + ], + defaults: + [ + 'torrentCategoriesId' => null, + ], + methods: + [ + 'GET', + 'POST' + ] + )] + public function editCategories( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + if (!$user->isStatus()) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init torrent categories + $torrentCategoriesCurrent = [ + 'userId' => null, + 'value' => [] + ]; + + // Get from edition version requested + if ($request->get('torrentCategoriesId')) + { + if ($torrentCategories = $torrentService->getTorrentCategories($request->get('torrentCategoriesId'))) + { + $torrentCategoriesCurrent['userId'] = $torrentCategories->getUserId(); + + foreach ($torrentCategories->getValue() as $value) + { + $torrentCategoriesCurrent['value'][] = $value; + } + } + + else + { + throw $this->createNotFoundException(); + } + } + + // Otherwise, get latest available + else + { + if ($torrentCategories = $torrentService->findLastTorrentCategoriesByTorrentId($torrent->getId())) + { + $torrentCategoriesCurrent['userId'] = $torrentCategories->getUserId(); + + foreach ($torrentCategories->getValue() as $value) + { + $torrentCategoriesCurrent['value'][] = $value; + } + + // Update active categories + $request->attributes->set('torrentCategoriesId', $torrentCategories->getId()); + } + } + + // Init edition history + $editions = []; + foreach ($torrentService->findTorrentCategoriesByTorrentId($torrent->getId()) as $torrentCategoriesEdition) + { + $editions[] = + [ + 'id' => $torrentCategoriesEdition->getId(), + 'added' => $torrentCategoriesEdition->getAdded(), + 'approved' => $torrentCategoriesEdition->isApproved(), + 'active' => $torrentCategoriesEdition->getId() == $request->get('torrentCategoriesId'), + 'user' => + [ + 'id' => $torrentCategoriesEdition->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $torrentCategoriesEdition->getUserId() + )->getAddress() + ), + ] + ]; + } + + // Init form + $form = + [ + 'categories' => + [ + 'error' => [], + 'attribute' => + [ + 'value' => $request->get('categories') ? $request->get('categories') : $torrentCategoriesCurrent['value'], + ] + ] + ]; + + // Process request + if ($request->isMethod('post')) + { + /// Categories + $categories = []; + if ($request->get('categories')) + { + foreach ((array) $request->get('categories') as $category) + { + if (in_array($category, explode('|', $this->getParameter('app.categories')))) + { + $categories[] = $category; + } + } + } + + //// At least one valid category required + if (!$categories) + { + $form['categories']['error'][] = $translator->trans('At least one category required'); + } + + // Request is valid + if (empty($form['categories']['error'])) + { + // Save data + $torrentCategories = $torrentService->addTorrentCategories( + $torrent->getId(), + $user->getId(), + time(), + $categories, + $user->isApproved() + ); + + // Register activity event + $activityService->addEventTorrentCategoriesAdd( + $user->getId(), + $torrent->getId(), + time(), + $torrentCategories->getId() + ); + + // Redirect to info page + return $this->redirectToRoute( + 'torrent_info', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId() + ] + ); + } + } + + // Render form template + return $this->render( + 'default/torrent/edit/categories.html.twig', + [ + 'torrentId' => $torrent->getId(), + 'categories' => explode('|', $this->getParameter('app.categories')), + 'editions' => $editions, + 'form' => $form, + 'session' => + [ + 'moderator' => $user->isModerator(), + 'owner' => $torrentCategoriesCurrent['userId'] === $user->getId(), + ] + ] + ); + } + + #[Route( + '/{_locale}/torrent/{torrentId}/approve/categories/{torrentCategoriesId}', + name: 'torrent_categories_approve', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentCategoriesId' => '\d+', + ], + methods: + [ + 'GET' + ] + )] + public function approveCategories( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init torrent categories + if (!$torrentCategories = $torrentService->getTorrentCategories($request->get('torrentCategoriesId'))) + { + throw $this->createNotFoundException(); + } + + // Check permissions + if (!$user->isModerator()) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Register activity event + if (!$torrentCategories->isApproved()) + { + $activityService->addEventTorrentCategoriesApproveAdd( + $user->getId(), + $torrent->getId(), + time(), + $torrentCategories->getId() + ); + } + + else + { + $activityService->addEventTorrentCategoriesApproveDelete( + $user->getId(), + $torrent->getId(), + time(), + $torrentCategories->getId() + ); + } + + // Update approved + $torrentService->toggleTorrentCategoriesApproved( + $torrentCategories->getId() + ); + + // Redirect back to form + return $this->redirectToRoute( + 'torrent_categories_edit', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId(), + 'torrentCategoriesId' => $torrentCategories->getId(), + ] + ); + } + + #[Route( + '/{_locale}/torrent/{torrentId}/delete/categories/{torrentCategoriesId}', + name: 'torrent_categories_delete', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentCategoriesId' => '\d+', + ], + methods: + [ + 'GET' + ] + )] + public function deleteCategories( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init torrent categories + if (!$torrentCategories = $torrentService->getTorrentCategories($request->get('torrentCategoriesId'))) + { + throw $this->createNotFoundException(); + } + + // Check permissions + if (!($user->isModerator() || $user->getId() === $torrentCategories->getUserId())) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Add activity event + $activityService->addEventTorrentCategoriesDelete( + $user->getId(), + $torrent->getId(), + time(), + $torrentCategories->getId() + ); + + // Update approved + $torrentService->deleteTorrentCategories( + $torrentCategories->getId() + ); + + // Redirect back to form + return $this->redirectToRoute( + 'torrent_categories_edit', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId(), + 'torrentCategoriesId' => $torrentCategories->getId(), + ] + ); + } + // Torrent sensitive #[Route( '/{_locale}/torrent/{torrentId}/edit/sensitive/{torrentSensitiveId}', name: 'torrent_sensitive_edit', requirements: [ - 'torrentId' => '\d+', + '_locale' => '%app.locales%', + 'torrentId' => '\d+', 'torrentSensitiveId' => '\d+', ], defaults: @@ -1299,6 +2113,7 @@ class TorrentController extends AbstractController name: 'torrent_sensitive_approve', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', 'torrentSensitiveId' => '\d+', ], @@ -1385,6 +2200,7 @@ class TorrentController extends AbstractController name: 'torrent_sensitive_delete', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', 'torrentSensitiveId' => '\d+', ], @@ -1453,12 +2269,403 @@ class TorrentController extends AbstractController ); } + // Torrent poster + #[Route( + '/{_locale}/torrent/{torrentId}/edit/poster/{torrentPosterId}', + name: 'torrent_poster_edit', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentPosterId' => '\d+', + ], + defaults: + [ + 'torrentPosterId' => null, + ], + methods: + [ + 'GET', + 'POST' + ] + )] + public function editPoster( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + if (!$user->isStatus()) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init poster value + if ($request->get('torrentPosterId')) + { + if ($torrentPoster = $torrentService->getTorrentPoster($request->get('torrentPosterId'))) + { + $torrentPosterCurrent = + [ + 'id' => $torrentPoster->getId(), + 'userId' => $torrentPoster->getUserId(), + 'value' => 'src' // @TODO + ]; + } + + else + { + throw $this->createNotFoundException(); + } + } + else + { + if ($torrentPoster = $torrentService->findLastTorrentPosterByTorrentId($torrent->getId())) + { + $torrentPosterCurrent = + [ + 'id' => $torrentPoster->getId(), + 'userId' => $torrentPoster->getUserId(), + 'value' => 'src' // @TODO + ]; + } + + else + { + $torrentPosterCurrent = + [ + 'id' => null, + 'userId' => null, + 'value' => false, + ]; + } + } + + // Init position + $position = in_array( + $request->get('position'), + [ + 'center', + 'top', + 'bottom' + ] + ) ? $request->get('position') : 'center'; + + // Init edition history + $editions = []; + foreach ($torrentService->findTorrentPosterByTorrentId($torrent->getId()) as $torrentPosterEdition) + { + $editions[] = + [ + 'id' => $torrentPosterEdition->getId(), + 'added' => $torrentPosterEdition->getAdded(), + 'position' => $torrentPosterEdition->getPosition(), + 'approved' => $torrentPosterEdition->isApproved(), + 'active' => $torrentPosterEdition->getId() == $torrentPosterCurrent['id'], + 'user' => + [ + 'id' => $torrentPosterEdition->getUserId(), + 'identicon' => $userService->identicon( + $userService->getUser( + $torrentPosterEdition->getUserId() + )->getAddress() + ), + ], + 'poster' => + $request->getScheme() . '://' . + $request->getHttpHost() . + $request->getBasePath() . + $torrentService->getImageUriByTorrentPosterId( + $torrentPosterEdition->getId() + ) + ]; + } + + // Init form + $form = + [ + 'poster' => + [ + 'error' => [] + ], + 'position' => + [ + 'error' => [], + 'attribute' => + [ + 'value' => $position + ] + ] + ]; + + // Process request + if ($request->isMethod('post')) + { + if ($request->get('id') && $torrentService->getTorrentPoster($request->get('id'))) + { + $filename = $torrentService->getStorageFilepathByTorrentPosterId( + $request->get('id') + ); + } + + else if ($file = $request->files->get('poster')) + { + //// Validate poster file + if (filesize($file->getPathName()) > $this->getParameter('app.torrent.poster.size.max')) + { + $form['poster']['error'][] = $translator->trans('Poster file out of size limit'); + } + + //// Validate image format + if (!@getimagesize($file->getPathName())) + { + $form['poster']['error'][] = $translator->trans('Image file not supported'); + } + + $filename = $file->getPathName(); + } + + else + { + $form['poster']['error'][] = $translator->trans('Poster file required'); + + $filename = false; + } + + // Request is valid + if (empty($form['poster']['error'])) + { + // Save data + $torrentPoster = $torrentService->addTorrentPoster( + $filename, + $position, + $torrent->getId(), + $user->getId(), + time(), + $user->isApproved() + ); + + // Add activity event + $activityService->addEventTorrentPosterAdd( + $user->getId(), + $torrent->getId(), + time(), + $torrentPoster->getId() + ); + + // Redirect to info page created + return $this->redirectToRoute( + 'torrent_info', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId() + ] + ); + } + } + + // Render form template + return $this->render( + 'default/torrent/edit/poster.html.twig', + [ + 'torrentId' => $torrent->getId(), + 'editions' => $editions, + 'form' => $form, + 'session' => + [ + 'moderator' => $user->isModerator(), + 'owner' => $torrentPosterCurrent['userId'] === $user->getId(), + ] + ] + ); + } + + #[Route( + '/{_locale}/torrent/{torrentId}/approve/poster/{torrentPosterId}', + name: 'torrent_poster_approve', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentPosterId' => '\d+', + ], + methods: + [ + 'GET' + ] + )] + public function approvePoster( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init torrent poster + if (!$torrentPoster = $torrentService->getTorrentPoster($request->get('torrentPosterId'))) + { + throw $this->createNotFoundException(); + } + + // Check permissions + if (!$user->isModerator()) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Add activity event + if (!$torrentPoster->isApproved()) + { + $activityService->addEventTorrentPosterApproveAdd( + $user->getId(), + $torrent->getId(), + time(), + $torrentPoster->getId() + ); + } + + else + { + $activityService->addEventTorrentPosterApproveDelete( + $user->getId(), + $torrent->getId(), + time(), + $torrentPoster->getId() + ); + } + + // Update approved + $torrentService->toggleTorrentPosterApproved( + $torrentPoster->getId() + ); + + // Redirect + return $this->redirectToRoute( + 'torrent_poster_edit', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId(), + 'torrentPosterId' => $torrentPoster->getId(), + ] + ); + } + + #[Route( + '/{_locale}/torrent/{torrentId}/delete/poster/{torrentPosterId}', + name: 'torrent_poster_delete', + requirements: + [ + '_locale' => '%app.locales%', + 'torrentId' => '\d+', + 'torrentPosterId' => '\d+', + ], + methods: + [ + 'GET' + ] + )] + public function deletePoster( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + // Init torrent poster + if (!$torrentPoster = $torrentService->getTorrentPoster($request->get('torrentPosterId'))) + { + throw $this->createNotFoundException(); + } + + // Check permissions + if (!($user->isModerator() || $user->getId() === $torrentPoster->getUserId())) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Add activity event + $activityService->addEventTorrentPosterDelete( + $user->getId(), + $torrent->getId(), + time(), + $torrentPoster->getId() + ); + + // Update approved + $torrentService->deleteTorrentPoster( + $torrentPoster->getId() + ); + + // Redirect + return $this->redirectToRoute( + 'torrent_poster_edit', + [ + '_locale' => $request->get('_locale'), + 'torrentId' => $torrent->getId(), + 'torrentPosterId' => $torrentPoster->getId(), + ] + ); + } + // Torrent star #[Route( '/{_locale}/torrent/{torrentId}/star/toggle', name: 'torrent_star_toggle', requirements: [ + '_locale' => '%app.locales%', 'torrentId' => '\d+', ], methods: @@ -1489,6 +2696,12 @@ class TorrentController extends AbstractController ); } + // Block crawler requests + if (in_array($request->getClientIp(), explode('|', $this->getParameter('app.crawlers')))) + { + throw $this->createNotFoundException(); + } + // Init torrent if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) { @@ -1533,11 +2746,11 @@ class TorrentController extends AbstractController // Torrent download file #[Route( - '/{_locale}/torrent/{torrentId}/download/file', - name: 'torrent_download_file', + '/torrent/{torrentId}/file', + name: 'torrent_file', requirements: [ - 'torrentId' => '\d+', + 'torrentId' => '\d+' ], methods: [ @@ -1567,6 +2780,12 @@ class TorrentController extends AbstractController ); } + // Block crawler requests + if (in_array($request->getClientIp(), explode('|', $this->getParameter('app.crawlers')))) + { + throw $this->createNotFoundException(); + } + // Init torrent if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) { @@ -1574,21 +2793,13 @@ class TorrentController extends AbstractController } if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId())) - { - // @TODO - throw new \Exception( - $translator->trans('File not found') - ); - } - - // Sensitive filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && $user->isSensitive()) { throw $this->createNotFoundException(); } - // Approved filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && !$torrent->isApproved()) + // Access filter + if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && + (!$torrent->isStatus() || !$torrent->isApproved())) { throw $this->createNotFoundException(); } @@ -1600,6 +2811,12 @@ class TorrentController extends AbstractController time() ); + // Request scrape + $torrentService->updateTorrentScraped( + $torrent->getId(), + 0 + ); + // Register download event $activityService->addEventTorrentDownloadFileAdd( $user->getId(), @@ -1607,16 +2824,13 @@ class TorrentController extends AbstractController $torrent->getId() ); - // Filter trackers - if ($user->isYggdrasil()) - { - $file->setAnnounceList( - [ - explode('|', $this->getParameter('app.trackers')) - ] - ); - } + // Apply filters + $file = $this->filterYggdrasil( + $file, + $user->isYggdrasil() + ); + // Get data $data = $file->dumpToString(); // Set headers @@ -1635,13 +2849,127 @@ class TorrentController extends AbstractController $response->headers->set( 'Content-Disposition', sprintf( - 'attachment; filename="%s.%s.torrent";', - mb_strtolower( - $this->getParameter('app.name') - ), - mb_strtolower( - $file->getName() - ) + 'attachment; filename="%s [%s#%s].torrent";', + $file->getName(), + $this->getParameter('app.name'), + $torrent->getId() + ) + ); + + $response->sendHeaders(); + + // Return file content + return $response->setContent($data); + } + + // Torrent download wanted file + #[Route( + '/torrent/{torrentId}/file/wanted', + name: 'torrent_file_wanted', + requirements: + [ + 'torrentId' => '\d+' + ], + methods: + [ + 'GET' + ] + )] + public function downloadFileWanted( + Request $request, + TranslatorInterface $translator, + UserService $userService, + TorrentService $torrentService, + ActivityService $activityService + ): Response + { + // Init user + $user = $this->initUser( + $request, + $userService, + $activityService + ); + + if (!$user->isStatus()) + { + // @TODO + throw new \Exception( + $translator->trans('Access denied') + ); + } + + // Block crawler requests + if (in_array($request->getClientIp(), explode('|', $this->getParameter('app.crawlers')))) + { + throw $this->createNotFoundException(); + } + + // Init torrent + if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) + { + throw $this->createNotFoundException(); + } + + if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId())) + { + throw $this->createNotFoundException(); + } + + // Access filter + if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && + (!$torrent->isStatus() || !$torrent->isApproved())) + { + throw $this->createNotFoundException(); + } + + // Register download + $torrentService->addTorrentDownloadFile( + $torrent->getId(), + $user->getId(), + time() + ); + + // Request scrape + $torrentService->updateTorrentScraped( + $torrent->getId(), + 0 + ); + + // Register download event + $activityService->addEventTorrentDownloadFileAdd( + $user->getId(), + time(), + $torrent->getId() + ); + + // Apply filters + $file = $this->filterYggdrasil( + $file, + false // wanted file downloading with original trackers + ); + + // Get data + $data = $file->dumpToString(); + + // Set headers + $response = new Response(); + + $response->headers->set( + 'Content-type', + 'application/x-bittorrent' + ); + + $response->headers->set( + 'Content-length', + strlen($data) + ); + + $response->headers->set( + 'Content-Disposition', + sprintf( + 'attachment; filename="%s [wanted#%s].torrent";', + $file->getName(), + $torrent->getId() ) ); @@ -1653,11 +2981,11 @@ class TorrentController extends AbstractController // Torrent download magnet #[Route( - '/{_locale}/torrent/{torrentId}/download/magnet', - name: 'torrent_download_magnet', + '/torrent/{torrentId}/magnet', + name: 'torrent_magnet', requirements: [ - 'torrentId' => '\d+', + 'torrentId' => '\d+' ], methods: [ @@ -1687,6 +3015,12 @@ class TorrentController extends AbstractController ); } + // Block crawler requests + if (in_array($request->getClientIp(), explode('|', $this->getParameter('app.crawlers')))) + { + throw $this->createNotFoundException(); + } + // Init torrent if (!$torrent = $torrentService->getTorrent($request->get('torrentId'))) { @@ -1694,21 +3028,13 @@ class TorrentController extends AbstractController } if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId())) - { - // @TODO - throw new \Exception( - $translator->trans('File not found') - ); - } - - // Sensitive filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && $user->isSensitive()) { throw $this->createNotFoundException(); } - // Approved filter - if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && !$torrent->isApproved()) + // Access filter + if (!$user->isModerator() && $user->getId() != $torrent->getUserId() && + (!$torrent->isStatus() || !$torrent->isApproved())) { throw $this->createNotFoundException(); } @@ -1720,6 +3046,12 @@ class TorrentController extends AbstractController time() ); + // Request scrape + $torrentService->updateTorrentScraped( + $torrent->getId(), + 0 + ); + // Register download event $activityService->addEventTorrentDownloadMagnetAdd( $user->getId(), @@ -1727,15 +3059,11 @@ class TorrentController extends AbstractController $torrent->getId() ); - // Filter trackers - if ($user->isYggdrasil()) - { - $file->setAnnounceList( - [ - explode('|', $this->getParameter('app.trackers')) - ] - ); - } + // Apply filters + $file = $this->filterYggdrasil( + $file, + $user->isYggdrasil() + ); // Return magnet link return $this->redirect( @@ -1745,7 +3073,10 @@ class TorrentController extends AbstractController // Tools #[Route( - '/crontab/torrent/scrape', + '/crontab/torrent/scrape/{key}', + requirements: [ + 'key' => '%app.key%' + ], methods: [ 'GET' @@ -1755,16 +3086,294 @@ class TorrentController extends AbstractController Request $request, TranslatorInterface $translator, TorrentService $torrentService, + ActivityService $activityService ): Response { - $torrentService->scrapeTorrentQueue( - explode('|', $this->getParameter('app.trackers')) + // Init Scraper + $scraper = new \Yggverse\Scrapeer\Scraper(); + + // Get next torrent in scrape queue + if (!$torrent = $torrentService->getTorrentScrapeQueue()) + { + throw $this->createNotFoundException(); + } + + // Get file + if (!$file = $torrentService->readTorrentFileByTorrentId($torrent->getId())) + { + throw $this->createNotFoundException(); + } + + // Filter yggdrasil trackers + $file = $this->filterYggdrasil($file, true); + + // Get trackers list + $trackers = []; + + if ($announce = $file->getAnnounce()) + { + $trackers[] = $announce; + } + + if ($announceList = $file->getAnnounceList()) + { + if (isset($announceList[0])) + { + foreach ($announceList[0] as $value) + { + $trackers[] = $value; + } + } + + if (isset($announceList[1])) + { + foreach ($announceList[1] as $value) + { + $trackers[] = $value; + } + } + } + + $trackers = array_unique($trackers); + + // Get info hashes + $hashes = []; + + if ($hash = $file->getInfoHashV1(false)) + { + $hashes[] = $hash; + } + + if ($hash = $file->getInfoHashV2(false)) + { + $hashes[] = $hash; + } + + // Get scrape + $seeders = 0; + $peers = 0; + $leechers = 0; + + if ($hashes && $trackers) + { + // Update scrape info + if ($results = $scraper->scrape($hashes, $trackers, null, 1)) + { + foreach ($results as $result) + { + if (isset($result['seeders'])) + { + $seeders = $seeders + (int) $result['seeders']; + } + + if (isset($result['completed'])) + { + $peers = $peers + (int) $result['completed']; + } + + if (isset($result['leechers'])) + { + $leechers = $leechers + (int) $result['leechers']; + } + } + } + } + + // Register activity event only on previous status changed + if ($leechers && !$seeders && + $leechers != (int) $torrent->getLeechers() && $seeders != (int) $torrent->getSeeders()) + { + $activityService->addEventTorrentWantedAdd( + $torrent->getUserId(), // just required field, let's relate with author, because we don't know which exactly user requires for seeders from crontab @TODO + time(), + $torrent->getId() + ); + } + + // Update DB + $torrentService->updateTorrentScrape( + $torrent->getId(), + $seeders, + $peers, + $leechers + ); + + // Update torrent wanted storage if enabled + if ($this->getParameter('app.torrent.wanted.ftp.enabled') === '1') + { + // Add wanted file + if ($leechers && !$seeders) + { + if ($this->getParameter('app.torrent.wanted.ftp.approved') === '0' || + ($this->getParameter('app.torrent.wanted.ftp.approved') === '1' && $torrent->isApproved())) + { + /// All + $torrentService->copyToFtpStorage( + $torrent->getId(), + sprintf( + '%s/torrents/wanted/all/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + + /// Sensitive + if ($torrent->isSensitive()) + { + $torrentService->copyToFtpStorage( + $torrent->getId(), + sprintf( + '%s/torrents/wanted/sensitive/yes/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + } + + else + { + $torrentService->copyToFtpStorage( + $torrent->getId(), + sprintf( + '%s/torrents/wanted/sensitive/no/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + } + + /// Locals + foreach ($torrent->getLocales() as $locale) + { + $torrentService->copyToFtpStorage( + $torrent->getId(), + sprintf( + '%s/torrents/wanted/locale/%s/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $locale, + $torrent->getId() + ) + ); + } + } + } + + // Remove not wanted files + else + { + /// All + $torrentService->removeFromFtpStorage( + sprintf( + '%s/torrents/wanted/all/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + + /// Sensitive + $torrentService->removeFromFtpStorage( + sprintf( + '%s/torrents/wanted/sensitive/yes/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + + $torrentService->removeFromFtpStorage( + sprintf( + '%s/torrents/wanted/sensitive/no/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $torrent->getId() + ) + ); + + /// Locals + foreach (explode('|', $this->getParameter('app.locales')) as $locale) + { + $torrentService->removeFromFtpStorage( + sprintf( + '%s/torrents/wanted/locale/%s/wanted#%s.torrent', + $this->getParameter('app.torrent.wanted.ftp.folder'), + $locale, + $torrent->getId() + ) + ); + } + } + } + + // Render response + return new Response(); // @TODO + } + + #[Route( + '/tool/torrent/reindex/{key}', + requirements: [ + 'key' => '%app.key%' + ], + methods: + [ + 'GET' + ] + )] + public function reindex( + TorrentService $torrentService + ): Response + { + // Reindex keywords + $torrentService->reindexTorrentKeywordsAll( + (bool) $this->getParameter('app.index.torrent.name.enabled'), + (bool) $this->getParameter('app.index.torrent.filenames.enabled'), + (bool) $this->getParameter('app.index.torrent.hash.v1.enabled'), + (bool) $this->getParameter('app.index.torrent.hash.v2.enabled'), + (bool) $this->getParameter('app.index.torrent.source.enabled'), + (bool) $this->getParameter('app.index.torrent.comment.enabled'), + (int) $this->getParameter('app.index.word.length.min'), + (int) $this->getParameter('app.index.word.length.max') ); // Render response return new Response(); // @TODO } + #[Route( + '/sitemap.xml', + methods: + [ + 'GET' + ] + )] + public function sitemap( + TorrentService $torrentService + ): Response + { + $locale = $this->getParameter('app.locale'); + $locales = explode('|', $this->getParameter('app.locales')); + + $response = new Response(); + $response->headers->set('Content-Type', 'text/xml'); + + return $this->render( + 'default/torrent/sitemap.xml.twig', + [ + 'locale' => $locale, + 'locales' => $locales, + 'torrents' => $torrentService->findTorrents( + 0, // no user session init, pass 0 + [], // without keywords filter + $locales, // all system locales + $categories, // all system locales + null, // all sensitive levels + true, // approved only + true, // enabled only + 1000, // @TODO limit + 0 // offset + ) + ], + $response + ); + } + private function initUser( Request $request, UserService $userService, @@ -1783,6 +3392,7 @@ class TorrentController extends AbstractController $this->getParameter('app.theme'), $this->getParameter('app.sensitive'), $this->getParameter('app.yggdrasil'), + $this->getParameter('app.posters'), $this->getParameter('app.approved') ); @@ -1795,4 +3405,82 @@ class TorrentController extends AbstractController return $user; } + + private function filterYggdrasil( + ?\Rhilip\Bencode\TorrentFile $file, bool $yggdrasil, string $regex = '/^0{0,1}[2-3][a-f0-9]{0,2}:/' + ): ?\Rhilip\Bencode\TorrentFile + { + // Init trackers registry + $allTrackers = []; + + // Get app trackers + $appTrackers = explode('|', $this->getParameter('app.trackers')); + + // Append app trackers + foreach ($appTrackers as $appTracker) + { + $allTrackers[] = $appTracker; + } + + // Get original file announcements + $announceList = $file->getAnnounceList(); + + // Append original file announcements + foreach ($announceList as $announce) + { + if (is_array($announce)) + { + foreach ($announce as $value) + { + $allTrackers[] = $value; + } + } + + else + { + $allTrackers[] = $value; + } + } + + // Remove duplicates + $allTrackers = array_unique($allTrackers); + + // Yggdrasil-only mode + if ($yggdrasil) + { + // Replace announce URL with first application tracker if original does not match Yggdrasil condition + if (!preg_match($regex, str_replace(['[',']'], false, parse_url($value, PHP_URL_HOST)))) + { + $file->setAnnounce( + $appTrackers[0] + ); + } + + // Remove non-Yggdrasil trackers from announcement list + foreach ($allTrackers as $key => $value) + { + // trackers + if (!preg_match($regex, str_replace(['[',']'], false, parse_url($value, PHP_URL_HOST)))) + { + unset($allTrackers[$key]); + } + } + } + + // Format announce list + $trackers = []; + + foreach ($allTrackers as $value) + { + $trackers[] = [$value]; + } + + // Update announce list + $file->setAnnounceList( + $trackers + ); + + // Return filtered file + return $file; + } } diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index a11291a..538af56 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -40,9 +40,6 @@ class UserController extends AbstractController #[Route( '/{_locale}/settings', name: 'user_settings', - defaults: [ - '_locale' => '%app.locale%' - ], requirements: [ '_locale' => '%app.locales%', ], @@ -88,6 +85,23 @@ class UserController extends AbstractController ); } + // Update categories + if ($request->get('categories')) + { + $categories = []; + foreach ((array) $request->get('categories') as $category) + { + if (in_array($category, explode('|', $this->getParameter('app.categories')))) + { + $categories[] = $category; + } + } + + $user->setCategories( + $categories + ); + } + // Update theme if (in_array($request->get('theme'), explode('|', $this->getParameter('app.themes')))) { @@ -120,6 +134,11 @@ class UserController extends AbstractController $request->get('yggdrasil') === 'true' ); + // Update posters + $user->setPosters( + $request->get('posters') === 'true' + ); + // Save changes to DB $userService->save($user); @@ -137,18 +156,21 @@ class UserController extends AbstractController 'default/user/settings.html.twig', [ 'user' => [ - 'id' => $user->getId(), - 'sensitive' => $user->isSensitive(), - 'yggdrasil' => $user->isYggdrasil(), - 'locale' => $user->getLocale(), - 'locales' => $user->getLocales(), - 'events' => $user->getEvents(), - 'theme' => $user->getTheme(), - 'added' => $user->getAdded() + 'id' => $user->getId(), + 'sensitive' => $user->isSensitive(), + 'yggdrasil' => $user->isYggdrasil(), + 'posters' => $user->isPosters(), + 'locale' => $user->getLocale(), + 'locales' => $user->getLocales(), + 'categories' => $user->getCategories(), + 'events' => $user->getEvents(), + 'theme' => $user->getTheme(), + 'added' => $user->getAdded() ], - 'locales' => explode('|', $this->getParameter('app.locales')), - 'themes' => explode('|', $this->getParameter('app.themes')), - 'events' => $activityService->getEventsTree() + 'locales' => explode('|', $this->getParameter('app.locales')), + 'categories' => explode('|', $this->getParameter('app.categories')), + 'themes' => explode('|', $this->getParameter('app.themes')), + 'events' => $activityService->getEventsTree() ] ); } @@ -157,7 +179,6 @@ class UserController extends AbstractController '/{_locale}/profile/{userId}', name: 'user_info', defaults: [ - '_locale' => '%app.locale%', 'userId' => 0, ], requirements: [ @@ -210,22 +231,26 @@ class UserController extends AbstractController [ 'session' => [ - 'user' => $user + 'user' => $user, + 'owner' => $user->getId() === $userTarget->getId(), + 'moderator' => $user->isModerator() ], 'user' => [ - 'id' => $userTarget->getId(), - 'address' => $userTarget->getId() === $user->getId() ? $userTarget->getAddress() : false, - 'moderator' => $userTarget->isModerator(), - 'approved' => $userTarget->isApproved(), - 'status' => $userTarget->isStatus(), - 'sensitive' => $userTarget->isSensitive(), - 'yggdrasil' => $userTarget->isYggdrasil(), - 'locale' => $userTarget->getLocale(), - 'locales' => $userTarget->getLocales(), - 'events' => $userTarget->getEvents(), - 'theme' => $userTarget->getTheme(), - 'added' => $userTarget->getAdded(), - 'identicon' => $userService->identicon( + 'id' => $userTarget->getId(), + 'address' => $userTarget->getAddress(), + 'moderator' => $userTarget->isModerator(), + 'approved' => $userTarget->isApproved(), + 'status' => $userTarget->isStatus(), + 'posters' => $userTarget->isPosters(), + 'sensitive' => $userTarget->isSensitive(), + 'yggdrasil' => $userTarget->isYggdrasil(), + 'locale' => $userTarget->getLocale(), + 'locales' => $userTarget->getLocales(), + 'categories' => $user->getCategories(), + 'events' => $userTarget->getEvents(), + 'theme' => $userTarget->getTheme(), + 'added' => $userTarget->getAdded(), + 'identicon' => $userService->identicon( $userTarget->getAddress(), 48 ), @@ -263,7 +288,8 @@ class UserController extends AbstractController name: 'user_star_toggle', requirements: [ - 'userId' => '\d+', + '_locale' => '%app.locales%', + 'userId' => '\d+', ], methods: [ @@ -292,6 +318,12 @@ class UserController extends AbstractController ); } + // Block crawler requests + if (in_array($request->getClientIp(), explode('|', $this->getParameter('app.crawlers')))) + { + throw $this->createNotFoundException(); + } + // Init target user if (!$userTarget = $userService->getUser($request->get('userId'))) { @@ -339,7 +371,8 @@ class UserController extends AbstractController name: 'user_moderator_toggle', requirements: [ - 'userId' => '\d+', + '_locale' => '%app.locales%', + 'userId' => '\d+', ], methods: [ @@ -413,7 +446,8 @@ class UserController extends AbstractController name: 'user_status_toggle', requirements: [ - 'userId' => '\d+', + '_locale' => '%app.locales%', + 'userId' => '\d+', ], methods: [ @@ -487,7 +521,8 @@ class UserController extends AbstractController name: 'user_approved_toggle', requirements: [ - 'userId' => '\d+', + '_locale' => '%app.locales%', + 'userId' => '\d+', ], methods: [ @@ -536,11 +571,21 @@ class UserController extends AbstractController true ); + $torrentService->setTorrentCategoriesApprovedByUserId( + $userTarget->getId(), + true + ); + $torrentService->setTorrentSensitivesApprovedByUserId( $userTarget->getId(), true ); + $torrentService->setTorrentPostersApprovedByUserId( + $userTarget->getId(), + true + ); + // @TODO make event for each item } @@ -611,6 +656,7 @@ class UserController extends AbstractController $this->getParameter('app.theme'), $this->getParameter('app.sensitive'), $this->getParameter('app.yggdrasil'), + $this->getParameter('app.posters'), $this->getParameter('app.approved') ); diff --git a/src/Entity/Activity.php b/src/Entity/Activity.php index a08cfcb..1be1097 100644 --- a/src/Entity/Activity.php +++ b/src/Entity/Activity.php @@ -20,42 +20,57 @@ class Activity // Event codes /// User - public const EVENT_USER_ADD = 1000; + public const EVENT_USER_ADD = 1000; - public const EVENT_USER_APPROVE_ADD = 1200; - public const EVENT_USER_APPROVE_DELETE = 1201; + public const EVENT_USER_APPROVE_ADD = 1200; + public const EVENT_USER_APPROVE_DELETE = 1201; - public const EVENT_USER_MODERATOR_ADD = 1300; - public const EVENT_USER_MODERATOR_DELETE = 1301; + public const EVENT_USER_MODERATOR_ADD = 1300; + public const EVENT_USER_MODERATOR_DELETE = 1301; - public const EVENT_USER_STATUS_ADD = 1400; - public const EVENT_USER_STATUS_DELETE = 1401; + public const EVENT_USER_STATUS_ADD = 1400; + public const EVENT_USER_STATUS_DELETE = 1401; - public const EVENT_USER_STAR_ADD = 1500; - public const EVENT_USER_STAR_DELETE = 1501; + public const EVENT_USER_STAR_ADD = 1500; + public const EVENT_USER_STAR_DELETE = 1501; /// Torrent - public const EVENT_TORRENT_ADD = 2000; + public const EVENT_TORRENT_ADD = 2000; - public const EVENT_TORRENT_APPROVE_ADD = 1100; - public const EVENT_TORRENT_APPROVE_DELETE = 1101; + public const EVENT_TORRENT_APPROVE_ADD = 1100; + public const EVENT_TORRENT_APPROVE_DELETE = 1101; - public const EVENT_TORRENT_LOCALES_ADD = 2200; - public const EVENT_TORRENT_LOCALES_DELETE = 2201; - public const EVENT_TORRENT_LOCALES_APPROVE_ADD = 2210; - public const EVENT_TORRENT_LOCALES_APPROVE_DELETE = 2211; + public const EVENT_TORRENT_LOCALES_ADD = 2200; + public const EVENT_TORRENT_LOCALES_DELETE = 2201; + public const EVENT_TORRENT_LOCALES_APPROVE_ADD = 2210; + public const EVENT_TORRENT_LOCALES_APPROVE_DELETE = 2211; - public const EVENT_TORRENT_SENSITIVE_ADD = 2300; - public const EVENT_TORRENT_SENSITIVE_DELETE = 2301; - public const EVENT_TORRENT_SENSITIVE_APPROVE_ADD = 2310; - public const EVENT_TORRENT_SENSITIVE_APPROVE_DELETE = 2311; + public const EVENT_TORRENT_SENSITIVE_ADD = 2300; + public const EVENT_TORRENT_SENSITIVE_DELETE = 2301; + public const EVENT_TORRENT_SENSITIVE_APPROVE_ADD = 2310; + public const EVENT_TORRENT_SENSITIVE_APPROVE_DELETE = 2311; - public const EVENT_TORRENT_STAR_ADD = 2400; - public const EVENT_TORRENT_STAR_DELETE = 2401; + public const EVENT_TORRENT_STAR_ADD = 2400; + public const EVENT_TORRENT_STAR_DELETE = 2401; - public const EVENT_TORRENT_DOWNLOAD_FILE_ADD = 2500; + public const EVENT_TORRENT_DOWNLOAD_FILE_ADD = 2500; - public const EVENT_TORRENT_DOWNLOAD_MAGNET_ADD = 2600; + public const EVENT_TORRENT_DOWNLOAD_MAGNET_ADD = 2600; + + public const EVENT_TORRENT_WANTED_ADD = 2700; + + public const EVENT_TORRENT_STATUS_ADD = 1800; + public const EVENT_TORRENT_STATUS_DELETE = 1801; + + public const EVENT_TORRENT_POSTER_ADD = 2800; + public const EVENT_TORRENT_POSTER_DELETE = 2801; + public const EVENT_TORRENT_POSTER_APPROVE_ADD = 2810; + public const EVENT_TORRENT_POSTER_APPROVE_DELETE = 2811; + + public const EVENT_TORRENT_CATEGORIES_ADD = 2900; + public const EVENT_TORRENT_CATEGORIES_DELETE = 2901; + public const EVENT_TORRENT_CATEGORIES_APPROVE_ADD = 2910; + public const EVENT_TORRENT_CATEGORIES_APPROVE_DELETE = 2911; // ... diff --git a/src/Entity/Torrent.php b/src/Entity/Torrent.php index 876bd1e..515a62e 100644 --- a/src/Entity/Torrent.php +++ b/src/Entity/Torrent.php @@ -33,6 +33,9 @@ class Torrent #[ORM\Column] private ?bool $approved = null; + #[ORM\Column] + private ?bool $status = null; + #[ORM\Column(length: 32)] private ?string $md5file = null; @@ -48,6 +51,12 @@ class Torrent #[ORM\Column(nullable: true)] private ?int $leechers = null; + #[ORM\Column(nullable: true)] + private ?int $torrentPosterId = null; + + #[ORM\Column(type: Types::SIMPLE_ARRAY)] + private ?array $categories = null; + public function getId(): ?int { return $this->id; @@ -156,6 +165,18 @@ class Torrent return $this; } + public function isStatus(): ?bool + { + return $this->status; + } + + public function setStatus(bool $status): static + { + $this->status = $status; + + return $this; + } + public function getSeeders(): ?int { return $this->seeders; @@ -191,4 +212,28 @@ class Torrent return $this; } + + public function getTorrentPosterId(): ?int + { + return $this->torrentPosterId; + } + + public function setTorrentPosterId(?int $torrentPosterId): static + { + $this->torrentPosterId = $torrentPosterId; + + return $this; + } + + public function getCategories(): ?array + { + return $this->categories; + } + + public function setCategories(?array $categories): static + { + $this->categories = $categories; + + return $this; + } } diff --git a/src/Entity/TorrentCategories.php b/src/Entity/TorrentCategories.php new file mode 100644 index 0000000..9d73809 --- /dev/null +++ b/src/Entity/TorrentCategories.php @@ -0,0 +1,103 @@ +id; + } + + public function setId(string $id): static + { + $this->id = $id; + + return $this; + } + + public function getTorrentId(): ?int + { + return $this->torrentId; + } + + public function setTorrentId(int $torrentId): static + { + $this->torrentId = $torrentId; + + return $this; + } + + public function getUserId(): ?int + { + return $this->userId; + } + + public function setUserId(int $userId): static + { + $this->userId = $userId; + + return $this; + } + + public function getAdded(): ?int + { + return $this->added; + } + + public function setAdded(int $added): static + { + $this->added = $added; + + return $this; + } + + public function getValue(): array + { + return $this->value; + } + + public function setValue(array $value): static + { + $this->value = $value; + + return $this; + } + + public function isApproved(): ?bool + { + return $this->approved; + } + + public function setApproved(bool $approved): static + { + $this->approved = $approved; + + return $this; + } +} diff --git a/src/Entity/TorrentPoster.php b/src/Entity/TorrentPoster.php new file mode 100644 index 0000000..b25c481 --- /dev/null +++ b/src/Entity/TorrentPoster.php @@ -0,0 +1,117 @@ +id; + } + + public function setId(string $id): static + { + $this->id = $id; + + return $this; + } + + public function getTorrentId(): ?int + { + return $this->torrentId; + } + + public function setTorrentId(int $torrentId): static + { + $this->torrentId = $torrentId; + + return $this; + } + + public function getUserId(): ?int + { + return $this->userId; + } + + public function setUserId(int $userId): static + { + $this->userId = $userId; + + return $this; + } + + public function getAdded(): ?int + { + return $this->added; + } + + public function setAdded(int $added): static + { + $this->added = $added; + + return $this; + } + + public function isApproved(): ?bool + { + return $this->approved; + } + + public function setApproved(bool $approved): static + { + $this->approved = $approved; + + return $this; + } + + public function getMd5file(): ?string + { + return $this->md5file; + } + + public function setMd5file(string $md5file): static + { + $this->md5file = $md5file; + + return $this; + } + + public function getPosition(): ?string + { + return $this->position; + } + + public function setPosition(string $position): static + { + $this->position = $position; + + return $this; + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 7339f65..330a97a 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -47,6 +47,12 @@ class User #[ORM\Column] private ?bool $yggdrasil = null; + #[ORM\Column] + private ?bool $posters = null; + + #[ORM\Column(type: Types::SIMPLE_ARRAY)] + private ?array $categories = null; + public function getId(): ?int { return $this->id; @@ -190,4 +196,28 @@ class User return $this; } + + public function isPosters(): ?bool + { + return $this->posters; + } + + public function setPosters(bool $posters): static + { + $this->posters = $posters; + + return $this; + } + + public function getCategories(): ?array + { + return $this->categories; + } + + public function setCategories(?array $categories): static + { + $this->categories = $categories; + + return $this; + } } diff --git a/src/Repository/TorrentCategoriesRepository.php b/src/Repository/TorrentCategoriesRepository.php new file mode 100644 index 0000000..030f69c --- /dev/null +++ b/src/Repository/TorrentCategoriesRepository.php @@ -0,0 +1,23 @@ + + * + * @method TorrentCategories|null find($id, $lockMode = null, $lockVersion = null) + * @method TorrentCategories|null findOneBy(array $criteria, array $orderBy = null) + * @method TorrentCategories[] findAll() + * @method TorrentCategories[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class TorrentCategoriesRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, TorrentCategories::class); + } +} diff --git a/src/Repository/TorrentPosterRepository.php b/src/Repository/TorrentPosterRepository.php new file mode 100644 index 0000000..235231c --- /dev/null +++ b/src/Repository/TorrentPosterRepository.php @@ -0,0 +1,23 @@ + + * + * @method TorrentPoster|null find($id, $lockMode = null, $lockVersion = null) + * @method TorrentPoster|null findOneBy(array $criteria, array $orderBy = null) + * @method TorrentPoster[] findAll() + * @method TorrentPoster[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + */ +class TorrentPosterRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, TorrentPoster::class); + } +} diff --git a/src/Repository/TorrentRepository.php b/src/Repository/TorrentRepository.php index a8f12f6..536a72f 100644 --- a/src/Repository/TorrentRepository.php +++ b/src/Repository/TorrentRepository.php @@ -22,93 +22,220 @@ class TorrentRepository extends ServiceEntityRepository } public function findTorrentsTotal( + int $userId, array $keywords, - array $locales, + ?array $locales, + ?array $categories, ?bool $sensitive = null, - ?bool $approved = null, - int $limit = 0, - int $offset = 10 + ?bool $approved = null, + ?bool $status = null, + int $limit = 10, + int $offset = 0 ): int { return $this->getTorrentsQueryByFilter( + $userId, $keywords, $locales, + $categories, $sensitive, $approved, + $status, )->select('count(t.id)') ->getQuery() ->getSingleScalarResult(); } public function findTorrents( + int $userId, array $keywords, - array $locales, + ?array $locales, + ?array $categories, ?bool $sensitive = null, - ?bool $approved = null, - int $limit = 0, - int $offset = 10 + ?bool $approved = null, + ?bool $status = null, + int $limit = 10, + int $offset = 0 ): array { return $this->getTorrentsQueryByFilter( + $userId, $keywords, $locales, + $categories, $sensitive, $approved, + $status, )->setMaxResults($limit) - ->setFirstResult($offset) - ->orderBy('t.id', 'DESC') // same as t.added - ->getQuery() - ->getResult(); + ->setFirstResult($offset) + ->orderBy('t.id', 'DESC') // same as t.added + ->getQuery() + ->getResult(); } private function getTorrentsQueryByFilter( - array $keywords, - array $locales, - ?bool $sensitive = null, - ?bool $approved = null, + int $userId, + ?array $keywords, + ?array $locales, + ?array $categories, + ?bool $sensitive = null, + ?bool $approved = null, + ?bool $status = null ): \Doctrine\ORM\QueryBuilder { $query = $this->createQueryBuilder('t'); - if ($keywords) // @TODO ANY or DTS + if (is_array($keywords)) { - $orX = $query->expr()->orX(); - foreach ($keywords as $i => $keyword) { - $orX->add("t.keywords LIKE :keyword{$i}"); - $query->setParameter(":keyword{$i}", "%{$keyword}%"); - } + // Make query to the index case insensitive + $keyword = mb_strtolower($keyword); - $query->andWhere($orX); + // Init OR condition for each word form + $orKeywords = $query->expr()->orX(); + + $orKeywords->add("t.keywords LIKE :keyword{$i}"); + $query->setParameter(":keyword{$i}", "%{$keyword}%"); + + // Generate word forms for each transliteration locale #33 + foreach ($this->generateWordForms($keyword) as $j => $wordForm) + { + $orKeywords->add("t.keywords LIKE :keyword{$i}{$j}"); + $query->setParameter(":keyword{$i}{$j}", "%{$wordForm}%"); + } + + // Append AND condition + $query->andWhere($orKeywords); + } } - if ($locales) // @TODO ANY or DTS + if (is_array($locales)) { - $orX = $query->expr()->orX(); + $orLocales = $query->expr()->orX(); foreach ($locales as $i => $locale) { - $orX->add("t.locales LIKE :locale{$i}"); + $orLocales->add("t.locales LIKE :locale{$i}"); + $orLocales->add("t.userId = :userId"); $query->setParameter(":locale{$i}", "%{$locale}%"); + $query->setParameter('userId', $userId); } - $query->andWhere($orX); + $query->andWhere($orLocales); + } + + if (is_array($categories)) + { + $orCategories = $query->expr()->orX(); + + foreach ($categories as $i => $category) + { + $orCategories->add("t.categories LIKE :category{$i}"); + $orCategories->add("t.userId = :userId"); + + $query->setParameter(":category{$i}", "%{$category}%"); + $query->setParameter('userId', $userId); + } + + $query->andWhere($orCategories); } if (is_bool($sensitive)) { - $query->andWhere('t.sensitive = :sensitive') - ->setParameter('sensitive', $sensitive); + $orSensitive = $query->expr()->orX(); + + $orSensitive->add("t.sensitive = :sensitive"); + $orSensitive->add("t.userId = :userId"); + + $query->setParameter('sensitive', $sensitive); + $query->setParameter('userId', $userId); + + $query->andWhere($orSensitive); } if (is_bool($approved)) { - $query->andWhere('t.approved = :approved') - ->setParameter('approved', $approved); + $orApproved = $query->expr()->orX(); + + $orApproved->add("t.approved = :approved"); + $orApproved->add("t.userId = :userId"); + + $query->setParameter('approved', $approved); + $query->setParameter('userId', $userId); + + $query->andWhere($orApproved); + } + + if (is_bool($status)) + { + $orStatus = $query->expr()->orX(); + + $orStatus->add("t.status = :status"); + $orStatus->add("t.userId = :userId"); + + $query->setParameter('status', $status); + $query->setParameter('userId', $userId); + + $query->andWhere($orStatus); } return $query; } + + // Word forms generator to improve search results + // e.g. transliteration rules for latin filenames + private function generateWordForms( + string $keyword, + // #33 supported locales: + // https://github.com/ashtokalo/php-translit + array $transliteration = [ + 'be', + 'bg', + 'el', + 'hy', + 'kk', + 'mk', + 'ru', + 'ka', + 'uk' + ], + // Additional char forms + array $charForms = + [ + 'c' => 'k', + 'k' => 'c', + ] + ): array + { + $wordForms = []; + + // Apply transliteration + foreach ($transliteration as $locale) + { + $wordForms[] = \ashtokalo\translit\Translit::object()->convert( + $keyword, + $locale + ); + } + + // Apply char forms + foreach ($wordForms as $wordForm) + { + foreach ($charForms as $from => $to) + { + $wordForms[] = str_replace( + $from, + $to, + $wordForm + ); + } + } + + // Remove duplicates + return array_unique( + $wordForms + ); + } } diff --git a/src/Service/ActivityService.php b/src/Service/ActivityService.php index 14eaa9f..dd785d1 100644 --- a/src/Service/ActivityService.php +++ b/src/Service/ActivityService.php @@ -51,16 +51,31 @@ class ActivityService Activity::EVENT_TORRENT_LOCALES_APPROVE_ADD, Activity::EVENT_TORRENT_LOCALES_APPROVE_DELETE, + Activity::EVENT_TORRENT_CATEGORIES_ADD, + Activity::EVENT_TORRENT_CATEGORIES_DELETE, + Activity::EVENT_TORRENT_CATEGORIES_APPROVE_ADD, + Activity::EVENT_TORRENT_CATEGORIES_APPROVE_DELETE, + Activity::EVENT_TORRENT_SENSITIVE_ADD, Activity::EVENT_TORRENT_SENSITIVE_DELETE, Activity::EVENT_TORRENT_SENSITIVE_APPROVE_ADD, Activity::EVENT_TORRENT_SENSITIVE_APPROVE_DELETE, + Activity::EVENT_TORRENT_POSTER_ADD, + Activity::EVENT_TORRENT_POSTER_DELETE, + Activity::EVENT_TORRENT_POSTER_APPROVE_ADD, + Activity::EVENT_TORRENT_POSTER_APPROVE_DELETE, + Activity::EVENT_TORRENT_STAR_ADD, Activity::EVENT_TORRENT_STAR_DELETE, Activity::EVENT_TORRENT_DOWNLOAD_FILE_ADD, Activity::EVENT_TORRENT_DOWNLOAD_MAGNET_ADD, + + Activity::EVENT_TORRENT_STATUS_ADD, + Activity::EVENT_TORRENT_STATUS_DELETE, + + Activity::EVENT_TORRENT_WANTED_ADD, ]; } @@ -267,6 +282,55 @@ class ActivityService break; + /// Torrent categories + case Activity::EVENT_TORRENT_CATEGORIES_ADD: + + $events + [ + $this->translatorInterface->trans('Torrent categories') + ] + [ + $this->translatorInterface->trans('Added') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_CATEGORIES_DELETE: + + $events + [ + $this->translatorInterface->trans('Torrent categories') + ] + [ + $this->translatorInterface->trans('Deleted') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_CATEGORIES_APPROVE_ADD: + + $events + [ + $this->translatorInterface->trans('Torrent categories') + ] + [ + $this->translatorInterface->trans('Approved') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_CATEGORIES_APPROVE_DELETE: + + $events + [ + $this->translatorInterface->trans('Torrent categories') + ] + [ + $this->translatorInterface->trans('Disapproved') + ] = $code; + + break; + /// Torrent sensitive case Activity::EVENT_TORRENT_SENSITIVE_ADD: @@ -316,6 +380,55 @@ class ActivityService break; + /// Torrent poster + case Activity::EVENT_TORRENT_POSTER_ADD: + + $events + [ + $this->translatorInterface->trans('Torrent posters') + ] + [ + $this->translatorInterface->trans('Added') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_POSTER_DELETE: + + $events + [ + $this->translatorInterface->trans('Torrent posters') + ] + [ + $this->translatorInterface->trans('Deleted') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_POSTER_APPROVE_ADD: + + $events + [ + $this->translatorInterface->trans('Torrent posters') + ] + [ + $this->translatorInterface->trans('Approved') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_POSTER_APPROVE_DELETE: + + $events + [ + $this->translatorInterface->trans('Torrent posters') + ] + [ + $this->translatorInterface->trans('Disapproved') + ] = $code; + + break; + /// Torrent stars case Activity::EVENT_TORRENT_STAR_ADD: @@ -365,6 +478,42 @@ class ActivityService ] = $code; break; + + case Activity::EVENT_TORRENT_WANTED_ADD: + + $events + [ + $this->translatorInterface->trans('Torrents') + ] + [ + $this->translatorInterface->trans('Wanted') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_STATUS_ADD: + + $events + [ + $this->translatorInterface->trans('Torrents') + ] + [ + $this->translatorInterface->trans('Enabled') + ] = $code; + + break; + + case Activity::EVENT_TORRENT_STATUS_DELETE: + + $events + [ + $this->translatorInterface->trans('Torrents') + ] + [ + $this->translatorInterface->trans('Disabled') + ] = $code; + + break; } } @@ -847,6 +996,96 @@ class ActivityService return $activity; } + public function addEventTorrentStatusAdd( + int $userId, + int $torrentId, + int $added + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_STATUS_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentStatusDelete( + int $userId, + int $torrentId, + int $added + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_STATUS_DELETE + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentWantedAdd( + int $userId, + int $added, + int $torrentId + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_WANTED_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setAdded( + $added + ); + + $activity->setTorrentId( + $torrentId + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + /// Torrent Download public function addEventTorrentDownloadFileAdd( int $userId, @@ -1118,6 +1357,155 @@ class ActivityService return $activity; } + /// Torrent categories + public function addEventTorrentCategoriesAdd( + int $userId, + int $torrentId, + int $added, + int $torrentCategoriesId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_CATEGORIES_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentCategoriesId' => $torrentCategoriesId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentCategoriesDelete( + int $userId, + int $torrentId, + int $added, + int $torrentCategoriesId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_CATEGORIES_DELETE + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentCategoriesId' => $torrentCategoriesId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentCategoriesApproveAdd( + int $userId, + int $torrentId, + int $added, + int $torrentCategoriesId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_CATEGORIES_APPROVE_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentCategoriesId' => $torrentCategoriesId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentCategoriesApproveDelete( + int $userId, + int $torrentId, + int $added, + int $torrentCategoriesId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_CATEGORIES_APPROVE_DELETE + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentCategoriesId' => $torrentCategoriesId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + /// Torrent sensitive public function addEventTorrentSensitiveAdd( int $userId, @@ -1266,4 +1654,153 @@ class ActivityService return $activity; } + + /// Torrent poster + public function addEventTorrentPosterAdd( + int $userId, + int $torrentId, + int $added, + int $torrentPosterId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_POSTER_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentPosterId' => $torrentPosterId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentPosterDelete( + int $userId, + int $torrentId, + int $added, + int $torrentPosterId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_POSTER_DELETE + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentPosterId' => $torrentPosterId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentPosterApproveAdd( + int $userId, + int $torrentId, + int $added, + int $torrentPosterId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_POSTER_APPROVE_ADD + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentPosterId' => $torrentPosterId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } + + public function addEventTorrentPosterApproveDelete( + int $userId, + int $torrentId, + int $added, + int $torrentPosterId, + ): ?Activity + { + $activity = new Activity(); + + $activity->setEvent( + Activity::EVENT_TORRENT_POSTER_APPROVE_DELETE + ); + + $activity->setUserId( + $userId + ); + + $activity->setTorrentId( + $torrentId + ); + + $activity->setAdded( + $added + ); + + $activity->setData( + [ + 'torrentPosterId' => $torrentPosterId + ] + ); + + $this->entityManagerInterface->persist($activity); + $this->entityManagerInterface->flush(); + + return $activity; + } } \ No newline at end of file diff --git a/src/Service/TorrentService.php b/src/Service/TorrentService.php index d37bedb..c0c3d52 100644 --- a/src/Service/TorrentService.php +++ b/src/Service/TorrentService.php @@ -4,14 +4,18 @@ namespace App\Service; use App\Entity\Torrent; use App\Entity\TorrentLocales; +use App\Entity\TorrentCategories; use App\Entity\TorrentSensitive; +use App\Entity\TorrentPoster; use App\Entity\TorrentStar; use App\Entity\TorrentDownloadFile; use App\Entity\TorrentDownloadMagnet; use App\Repository\TorrentRepository; use App\Repository\TorrentLocalesRepository; +use App\Repository\TorrentCategoriesRepository; use App\Repository\TorrentSensitiveRepository; +use App\Repository\TorrentPosterRepository; use App\Repository\TorrentStarRepository; use App\Repository\TorrentDownloadFileRepository; use App\Repository\TorrentDownloadMagnetRepository; @@ -36,91 +40,6 @@ class TorrentService } // Tools - public function scrapeTorrentQueue( - array $trackers = [] - ): void - { - // Init Scraper - $scraper = new \Yggverse\Scrapeer\Scraper(); - - if ($torrent = $this->getTorrentScrapeQueue()) - { - // Get file - if (!$file = $this->readTorrentFileByTorrentId($torrent->getId())) - { - // @TODO - throw new \Exception( - $translator->trans('File not found') - ); - } - - // Get info hashes - $hashes = []; - - if ($hash = $file->getInfoHashV1(false)) - { - $hashes[] = $hash; - } - - if ($hash = $file->getInfoHashV2(false)) - { - $hashes[] = $hash; - } - - // Init default values - $seeders = 0; - $peers = 0; - $leechers = 0; - - // Get scrape - if ($hashes && $trackers) - { - // Update scrape info - if ($results = $scraper->scrape($hashes, $trackers, null, 1)) - { - foreach ($results as $result) - { - if (isset($result['seeders'])) - { - $seeders = $seeders + (int) $result['seeders']; - } - - if (isset($result['completed'])) - { - $peers = $peers + (int) $result['completed']; - } - - if (isset($result['leechers'])) - { - $leechers = $leechers + (int) $result['leechers']; - } - } - } - } - - // Update torrent scrape - $torrent->setSeeders( - $seeders - ); - - $torrent->setPeers( - $peers - ); - - $torrent->setLeechers( - $leechers - ); - - $torrent->setScraped( - time() - ); - - // Save results to DB - $this->entityManagerInterface->persist($torrent); - $this->entityManagerInterface->flush(); - } - } - public function readTorrentFileByFilepath( string $filepath ): ?\Rhilip\Bencode\TorrentFile @@ -139,61 +58,264 @@ class TorrentService } public function readTorrentFileByTorrentId( - int $id + int $torrentId ): ?\Rhilip\Bencode\TorrentFile { return $this->readTorrentFileByFilepath( - $this->getStorageFilepathById($id) + $this->getStorageFilepathByTorrentId($torrentId) + ); + } + + public function generateTorrentKeywordsByString( + string $string, + int $wordLengthMin, + int $wordLengthMax, + ): array + { + $words = explode( + ' ', + preg_replace( + '/[\s]+/', + ' ', + preg_replace( + '/[\W_]+/u', + ' ', + $string + ) + ) + ); + + // Apply words filter + foreach ((array) $words as $key => $value) + { + // Apply word length filter + $length = mb_strlen($value); + + if ($length < $wordLengthMin || $length > $wordLengthMax) + { + unset($words[$key]); + } + + else + { + // Apply case insensitive search conversion + $words[$key] = mb_strtolower($value); + } + } + + // Build simple array + $keywords = []; + foreach ((array) $words as $word) + { + $keywords[] = $word; + } + + // Return unique keywords + return array_unique( + $keywords ); } public function generateTorrentKeywordsByTorrentFilepath( + string $filepath, - int $minLength = 3 + + bool $extractName, + bool $extractFilenames, + bool $extractInfoHashV1, + bool $extractInfoHashV2, + bool $extractSource, + bool $extractComment, + + int $wordLengthMin, + int $wordLengthMax + ): array { $keywords = []; - foreach ($this->readTorrentFileByFilepath($filepath)->getFileList() as $file) + if ($file = $this->readTorrentFileByFilepath($filepath)) { - $words = explode( - ' ', - preg_replace( - '/[\s]+/', - ' ', - preg_replace( - '/[\W]+/', - ' ', - $file['path'] - ) - ) - ); - - foreach ($words as $key => $value) + if ($extractName) { - if (mb_strlen($value) < $minLength) + if ($name = $file->getName(false)) { - unset($words[$key]); - } - - else - { - $words[$key] = mb_strtolower($value); + $keywords = array_merge( + $keywords, + $this->generateTorrentKeywordsByString( + $name, + $wordLengthMin, + $wordLengthMax + ) + ); } } - $keywords = array_merge($keywords, $words); + if ($extractFilenames) + { + foreach ($file->getFileList() as $list) + { + $keywords = array_merge( + $keywords, + $this->generateTorrentKeywordsByString( + $list['path'], + $wordLengthMin, + $wordLengthMax + ) + ); + } + } + + if ($extractSource) + { + if ($source = $file->getSource(false)) + { + $keywords = array_merge( + $keywords, + $this->generateTorrentKeywordsByString( + $source, + $wordLengthMin, + $wordLengthMax + ) + ); + } + } + + if ($extractComment) + { + if ($comment = $file->getComment(false)) + { + $keywords = array_merge( + $keywords, + $this->generateTorrentKeywordsByString( + $comment, + $wordLengthMin, + $wordLengthMax + ) + ); + } + } + + if ($extractInfoHashV1) + { + if ($hash = $file->getInfoHashV1(false)) + { + $keywords[] = $hash; + } + } + + if ($extractInfoHashV2) + { + if ($hash = $file->getInfoHashV2(false)) + { + $keywords[] = $hash; + } + } } - return array_unique($keywords); + return array_unique( + $keywords + ); } - public function getStorageFilepathById(int $id): string + public function getImageUriByTorrentPosterId( + int $torrentPosterId, + int $quality = 100, + int $width = 748, + int $height = 0, + float $opacity = 1, + bool $grayscale = false, + string $format = 'webp' + ): string + { + $uri = sprintf( + '/posters/%s.%s', + implode('/', str_split($torrentPosterId)), + $format + ); + + $filename = sprintf( + '%s/public/posters/%s.%s', + $this->kernelInterface->getProjectDir(), + implode('/', str_split($torrentPosterId)), + $format + ); + + if (file_exists($filename)) + { + return $uri; + } + + $path = explode('/', $filename); + + array_pop($path); + + @mkdir(implode('/', $path), 0755, true); + + $image = new \Imagick(); + + $image->readImage( + $this->getStorageFilepathByTorrentPosterId( + $torrentPosterId + ) + ); + + $image->setImageFormat($format); + $image->setImageCompressionQuality($quality); + + if ($width || $height) + { + $image->adaptiveResizeImage( + $width, + $height + ); + } + + if ($grayscale) + { + $image->setImageType( + \Imagick::IMGTYPE_GRAYSCALE + ); + } + + if ($opacity) + { + $image->setImageOpacity( + $opacity + ); + } + + $image->writeImage( + $filename + ); + + return $uri; + } + + public function getStorageFilepathByTorrentPosterId(int $torrentPosterId): string + { + return sprintf( + '%s/var/posters/%s.original', + $this->kernelInterface->getProjectDir(), + implode('/', str_split($torrentPosterId)) + ); + } + + public function getStorageFilepathByTorrentId(int $torrentId): string { return sprintf( '%s/var/torrents/%s.torrent', $this->kernelInterface->getProjectDir(), - implode('/', str_split($id)) + implode('/', str_split($torrentId)) + ); + } + + public function getFtpFilepathByFilename(string $filename): string + { + return sprintf( + '%s/var/ftp/%s', + $this->kernelInterface->getProjectDir(), + $filename ); } @@ -201,28 +323,81 @@ class TorrentService { $contributors = []; - foreach ($this->findTorrentLocalesByTorrentId($torrent->getUserId()) as $torrentLocale) + foreach ($this->findTorrentCategoriesByTorrentId($torrent->getId()) as $torrentCategory) + { + $contributors[] = $torrentCategory->getUserId(); + } + + foreach ($this->findTorrentLocalesByTorrentId($torrent->getId()) as $torrentLocale) { $contributors[] = $torrentLocale->getUserId(); } - foreach ($this->findTorrentSensitiveByTorrentId($torrent->getUserId()) as $torrentSensitive) + foreach ($this->findTorrentSensitiveByTorrentId($torrent->getId()) as $torrentSensitive) { $contributors[] = $torrentSensitive->getUserId(); } + foreach ($this->findTorrentPosterByTorrentId($torrent->getId()) as $torrentPoster) + { + $contributors[] = $torrentPoster->getUserId(); + } + $contributors[] = $torrent->getUserId(); return array_unique($contributors); } + public function copyToFtpStorage( + int $torrentId, + string $filename + ): void + { + $filesystem = new Filesystem(); + $filesystem->copy( + $this->getStorageFilepathByTorrentId( + $torrentId + ), + $this->getFtpFilepathByFilename( + $filename + ) + ); + } + + public function removeFromFtpStorage( + string $filename + ): void + { + $filesystem = new Filesystem(); + $filesystem->remove( + $this->getFtpFilepathByFilename( + $filename + ) + ); + } + public function add( + string $filepath, - int $userId, - int $added, - array $locales, - bool $sensitive, - bool $approved + + bool $extractName, + bool $extractFilenames, + bool $extractInfoHashV1, + bool $extractInfoHashV2, + bool $extractSource, + bool $extractComment, + + int $wordLengthMin, + int $wordLengthMax, + + int $userId, + int $added, + array $locales, + array $categories, + bool $sensitive, + bool $approved, + bool $status + ): ?Torrent { $torrent = $this->addTorrent( @@ -230,17 +405,27 @@ class TorrentService $added, md5_file($filepath), $this->generateTorrentKeywordsByTorrentFilepath( - $filepath + $filepath, + $extractName, + $extractFilenames, + $extractInfoHashV1, + $extractInfoHashV2, + $extractSource, + $extractComment, + $wordLengthMin, + $wordLengthMax ), $locales, + $categories, $sensitive, - $approved + $approved, + $status ); $filesystem = new Filesystem(); $filesystem->copy( $filepath, - $this->getStorageFilepathById( + $this->getStorageFilepathByTorrentId( $torrent->getId() ) ); @@ -253,6 +438,14 @@ class TorrentService $approved ); + $this->addTorrentCategories( + $torrent->getId(), + $userId, + $added, + $categories, + $approved + ); + $this->addTorrentSensitive( $torrent->getId(), $userId, @@ -278,8 +471,10 @@ class TorrentService string $md5file, array $keywords, array $locales, + array $categories, bool $sensitive, - bool $approved + bool $approved, + bool $status ): ?Torrent { $torrent = new Torrent(); @@ -289,8 +484,10 @@ class TorrentService $torrent->setMd5File($md5file); $torrent->setKeywords($keywords); $torrent->setLocales($locales); + $torrent->setCategories($categories); $torrent->setSensitive($sensitive); $torrent->setApproved($approved); + $torrent->setStatus($status); $this->entityManagerInterface->persist($torrent); $this->entityManagerInterface->flush(); @@ -322,6 +519,30 @@ class TorrentService return $torrent; } + public function toggleTorrentStatus( + int $torrentId + ): ?Torrent + { + $torrent = $this->getTorrent($torrentId); + + $torrent->setStatus( + !$torrent->isStatus() // toggle current value + ); + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + + $this->updateTorrentLocales( + $torrent->getId() + ); + + $this->updateTorrentSensitive( + $torrent->getId() + ); + + return $torrent; + } + public function getTorrentScrapeQueue(): ?Torrent { return $this->entityManagerInterface @@ -335,40 +556,52 @@ class TorrentService } public function findTorrents( + int $userId, array $keywords, - array $locales, + ?array $locales, + ?array $categories, ?bool $sensitive, ?bool $approved, - int $limit, - int $offset + ?bool $status, + int $limit, + int $offset ) : array { return $this->entityManagerInterface ->getRepository(Torrent::class) ->findTorrents( + $userId, $keywords, $locales, + $categories, $sensitive, $approved, + $status, $limit, $offset ); } public function findTorrentsTotal( + int $userId, array $keywords, - array $locales, + ?array $locales, + ?array $categories, ?bool $sensitive, - ?bool $approved + ?bool $approved, + ?bool $status ) : int { return $this->entityManagerInterface ->getRepository(Torrent::class) ->findTorrentsTotal( + $userId, $keywords, $locales, + $categories, $sensitive, - $approved + $approved, + $status ); } @@ -437,6 +670,114 @@ class TorrentService } } + public function updateTorrentCategories( + int $torrentId + ): void + { + if ($torrent = $this->getTorrent($torrentId)) + { + if ($torrentCategories = $this->entityManagerInterface + ->getRepository(TorrentCategories::class) + ->findOneBy( + [ + 'torrentId' => $torrentId, + 'approved' => true, + ], + [ + 'id' => 'DESC' + ] + )) + { + $torrent->setCategories($torrentCategories->getValue()); + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + } + } + } + + public function updateTorrentScraped( + int $torrentId, + int $time + ): void + { + if ($torrent = $this->getTorrent($torrentId)) + { + $torrent->setScraped( + $time + ); + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + } + } + + public function updateTorrentScrape( + int $torrentId, + int $seeders, + int $peers, + int $leechers + ): void + { + if ($torrent = $this->getTorrent($torrentId)) + { + $torrent->setSeeders( + $seeders + ); + + $torrent->setPeers( + $peers + ); + + $torrent->setLeechers( + $leechers + ); + + $torrent->setScraped( + time() + ); + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + } + } + + public function reindexTorrentKeywordsAll( + bool $extractName, + bool $extractFilenames, + bool $extractInfoHashV1, + bool $extractInfoHashV2, + bool $extractSource, + bool $extractComment, + int $wordLengthMin, + int $wordLengthMax + ): void + { + foreach ($this->entityManagerInterface + ->getRepository(Torrent::class) + ->findAll() as $torrent) + { + $torrent->setKeywords( + $this->generateTorrentKeywordsByTorrentFilepath( + $this->getStorageFilepathByTorrentId( + $torrent->getId() + ), + $extractName, + $extractFilenames, + $extractInfoHashV1, + $extractInfoHashV2, + $extractSource, + $extractComment, + $wordLengthMin, + $wordLengthMax + ) + ); + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + } + } + public function setTorrentApprovedByTorrentId( int $torrentId, bool $value @@ -599,6 +940,133 @@ class TorrentService } } + // Torrent category + public function getTorrentCategories( + int $torrentCategoryId + ): ?TorrentCategories + { + return $this->entityManagerInterface + ->getRepository(TorrentCategories::class) + ->find($torrentCategoryId); + } + + public function findLastTorrentCategoriesByTorrentId( + int $torrentId + ): ?TorrentCategories + { + return $this->entityManagerInterface + ->getRepository(TorrentCategories::class) + ->findOneBy( + [ + 'torrentId' => $torrentId + ], + [ + 'id' => 'DESC' + ] + ); + } + + public function findTorrentCategoriesByTorrentId(int $torrentId): array + { + return $this->entityManagerInterface + ->getRepository(TorrentCategories::class) + ->findBy( + [ + 'torrentId' => $torrentId, + ], + [ + 'id' => 'DESC' + ] + ); + } + + public function toggleTorrentCategoriesApproved( + int $torrentCategoriesId + ): ?TorrentCategories + { + $torrentCategories = $this->getTorrentCategories($torrentCategoriesId); + + $torrentCategories->setApproved( + !$torrentCategories->isApproved() // toggle current value + ); + + $this->entityManagerInterface->persist($torrentCategories); + $this->entityManagerInterface->flush(); + + $this->updateTorrentCategories( + $torrentCategories->getTorrentId() + ); + + return $torrentCategories; + } + + public function deleteTorrentCategories( + int $torrentCategoriesId + ): ?TorrentCategories + { + $torrentCategories = $this->getTorrentCategories($torrentCategoriesId); + + $this->entityManagerInterface->remove($torrentCategories); + $this->entityManagerInterface->flush(); + + $this->updateTorrentCategories( + $torrentCategories->getTorrentId() + ); + + return $torrentCategories; + } + + public function addTorrentCategories( + int $torrentId, + int $userId, + int $added, + array $value, + bool $approved + ): ?TorrentCategories + { + $torrentCategories = new TorrentCategories(); + + $torrentCategories->setTorrentId($torrentId); + $torrentCategories->setUserId($userId); + $torrentCategories->setAdded($added); + $torrentCategories->setValue($value); + $torrentCategories->setApproved($approved); + + $this->entityManagerInterface->persist($torrentCategories); + $this->entityManagerInterface->flush(); + + $this->updateTorrentCategories( + $torrentId + ); + + return $torrentCategories; + } + + public function setTorrentCategoriesApprovedByUserId( + int $userId, + bool $value + ): void + { + foreach ($this->entityManagerInterface + ->getRepository(TorrentCategories::class) + ->findBy( + [ + 'userId' => $userId + ]) as $torrentCategories) + { + $torrentCategories->setApproved( + $value + ); + + $this->entityManagerInterface->persist($torrentCategories); + $this->entityManagerInterface->flush(); + + $this->updateTorrentCategories( + $torrentCategories->getTorrentId(), + ); + } + } + // Torrent sensitive public function getTorrentSensitive( int $torrentSensitiveId @@ -730,6 +1198,218 @@ class TorrentService } } + // Torrent poster + public function getTorrentPoster( + int $torrentPosterId + ): ?TorrentPoster + { + return $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->find( + $torrentPosterId + ); + } + + public function findTorrentPosterByMd5File( + string $md5file + ): ?Torrent + { + return $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->findOneBy( + [ + 'md5file' => $md5file + ] + ); + } + + public function findLastTorrentPosterByTorrentId( + int $torrentId + ): ?TorrentPoster + { + return $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->findOneBy( + [ + 'torrentId' => $torrentId + ], + [ + 'id' => 'DESC' + ] + ); + } + + public function findTorrentPosterByTorrentId( + int $torrentId + ): array + { + return $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->findBy( + [ + 'torrentId' => $torrentId + ], + [ + 'id' => 'DESC' + ] + ); + } + + public function toggleTorrentPosterApproved( + int $torrentPosterId + ): ?TorrentPoster + { + $torrentPoster = $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->find($torrentPosterId); + + $torrentPoster->setApproved( + !$torrentPoster->isApproved() // toggle current value + ); + + $this->entityManagerInterface->persist($torrentPoster); + $this->entityManagerInterface->flush(); + + $this->updateTorrentPoster( + $torrentPoster->getTorrentId() + ); + + return $torrentSensitive; + } + + public function deleteTorrentPoster( + int $torrentPosterId + ): ?TorrentPoster + { + // Remove torrent file from permanent storage + $filesystem = new Filesystem(); + $filesystem->remove( + $this->getStorageFilepathByTorrentPosterId( + $torrentPosterId + ) + ); + + // Remove from DB + $torrentPoster = $this->getTorrentPoster( + $torrentPosterId + ); + + $this->entityManagerInterface->remove($torrentPoster); + $this->entityManagerInterface->flush(); + + // Update torrent + $this->updateTorrentPoster( + $torrentPoster->getTorrentId() + ); + + return $torrentSensitive; + } + + public function addTorrentPoster( + string $filename, + string $position, + int $torrentId, + int $userId, + int $added, + bool $approved + ): ?TorrentPoster + { + // Add new DB record + $torrentPoster = new TorrentPoster(); + + $torrentPoster->setTorrentId($torrentId); + $torrentPoster->setUserId($userId); + $torrentPoster->setAdded($added); + $torrentPoster->setApproved($approved); + $torrentPoster->setPosition($position); + $torrentPoster->setMd5file( + md5_file($filename) + ); + + $this->entityManagerInterface->persist($torrentPoster); + $this->entityManagerInterface->flush(); + + // Save file in permanent storage + $filesystem = new Filesystem(); + $filesystem->copy( + $filename, + $this->getStorageFilepathByTorrentPosterId( + $torrentPoster->getId() + ) + ); + + // Update torrent info + $this->updateTorrentPoster( + $torrentId + ); + + return $torrentPoster; + } + + public function setTorrentPostersApprovedByUserId( + int $userId, + bool $value + ): void + { + foreach ($this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->findBy( + [ + 'userId' => $userId + ]) as $torrentPoster) + { + $torrentPoster->setApproved( + $value + ); + + $this->entityManagerInterface->persist($torrentPoster); + $this->entityManagerInterface->flush(); + + $this->updateTorrentPoster( + $torrentPoster->getTorrentId(), + ); + } + } + + public function updateTorrentPoster( + int $torrentId, + ): void + { + if ($torrent = $this->getTorrent($torrentId)) + { + if ($torrentPoster = $this->entityManagerInterface + ->getRepository(TorrentPoster::class) + ->findOneBy( + [ + 'torrentId' => $torrentId, + 'approved' => true, + ], + [ + 'id' => 'DESC' + ] + )) + { + $torrent->setTorrentPosterId( + $torrentPoster->getId() + ); + } + + else + { + $torrent->setTorrentPosterId( + null + ); + } + + $this->entityManagerInterface->persist($torrent); + $this->entityManagerInterface->flush(); + } + } + + + + + // Torrent star public function findTorrentStar( int $torrentId, diff --git a/src/Service/UserService.php b/src/Service/UserService.php index 2459d5d..eeba420 100644 --- a/src/Service/UserService.php +++ b/src/Service/UserService.php @@ -32,6 +32,7 @@ class UserService string $theme, bool $sensitive = true, bool $yggdrasil = true, + bool $posters = true, bool $approved = false, bool $moderator = false, bool $status = true @@ -84,6 +85,10 @@ class UserService $yggdrasil ); + $user->setPosters( + $posters + ); + $this->entityManagerInterface->persist($user); $this->entityManagerInterface->flush(); diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 50d142d..440ca6c 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -39,13 +39,27 @@ class AppExtension extends AbstractExtension 'formatAgo' ] ), + new TwigFilter( + 'url_to_markdown', + [ + $this, + 'urlToMarkdown' + ] + ), + new TwigFilter( + 'trans_category', + [ + $this, + 'transCategory' + ] + ), ]; } public function formatBytes( int $bytes, int $precision = 2 - ) : string + ): string { $size = [ $this->translator->trans('B'), @@ -66,7 +80,7 @@ class AppExtension extends AbstractExtension public function formatAgo( int $time, - ) : string + ): string { $diff = time() - $time; @@ -77,21 +91,42 @@ class AppExtension extends AbstractExtension $values = [ - 365 * 24 * 60 * 60 => $this->translator->trans('year'), - 30 * 24 * 60 * 60 => $this->translator->trans('month'), - 24 * 60 * 60 => $this->translator->trans('day'), - 60 * 60 => $this->translator->trans('hour'), - 60 => $this->translator->trans('minute'), - 1 => $this->translator->trans('second') - ]; - - $plural = [ - $this->translator->trans('year') => $this->translator->trans('years'), - $this->translator->trans('month') => $this->translator->trans('months'), - $this->translator->trans('day') => $this->translator->trans('days'), - $this->translator->trans('hour') => $this->translator->trans('hours'), - $this->translator->trans('minute') => $this->translator->trans('minutes'), - $this->translator->trans('second') => $this->translator->trans('seconds') + 365 * 24 * 60 * 60 => + [ + $this->translator->trans('year ago'), + $this->translator->trans('years ago'), + $this->translator->trans(' years ago') + ], + 30 * 24 * 60 * 60 => + [ + $this->translator->trans('month ago'), + $this->translator->trans('months ago'), + $this->translator->trans(' months ago') + ], + 24 * 60 * 60 => + [ + $this->translator->trans('day ago'), + $this->translator->trans('days ago'), + $this->translator->trans(' days ago') + ], + 60 * 60 => + [ + $this->translator->trans('hour ago'), + $this->translator->trans('hours ago'), + $this->translator->trans(' hours ago') + ], + 60 => + [ + $this->translator->trans('minute ago'), + $this->translator->trans('minutes ago'), + $this->translator->trans(' minutes ago') + ], + 1 => + [ + $this->translator->trans('second ago'), + $this->translator->trans('seconds ago'), + $this->translator->trans(' seconds ago') + ] ]; foreach ($values as $key => $value) @@ -103,12 +138,55 @@ class AppExtension extends AbstractExtension $round = round($result); return sprintf( - '%s %s %s', + '%s %s', $round, - $round > 1 ? $plural[$value] : $value, - $this->translator->trans('ago') + $this->plural( + $round, + $value + ) ); } } } + + public function urlToMarkdown( + string $text + ): string + { + return preg_replace( + '~(https?://(?:www\.)?[^\(\s\)]+)~i', + '[$1]($1)', + $text + ); + } + + public function transCategory( + string $name + ): string + { + switch ($name) + { + case 'movie': return $this->translator->trans('movie'); + case 'series': return $this->translator->trans('series'); + case 'tv': return $this->translator->trans('tv'); + case 'animation': return $this->translator->trans('animation'); + case 'music': return $this->translator->trans('music'); + case 'game': return $this->translator->trans('game'); + case 'audiobook': return $this->translator->trans('audiobook'); + case 'podcast': return $this->translator->trans('podcast'); + case 'book': return $this->translator->trans('book'); + case 'archive': return $this->translator->trans('archive'); + case 'picture': return $this->translator->trans('picture'); + case 'software': return $this->translator->trans('software'); + case 'other': return $this->translator->trans('other'); + default: return $name; + } + } + + private function plural(int $number, array $texts) + { + $cases = [2, 0, 1, 1, 1, 2]; + + return $texts[(($number % 100) > 4 && ($number % 100) < 20) ? 2 : $cases[min($number % 10, 5)]]; + } } \ No newline at end of file diff --git a/templates/bundles/TwigBundle/Exception/error404.html.twig b/templates/bundles/TwigBundle/Exception/error404.html.twig new file mode 100644 index 0000000..4509a25 --- /dev/null +++ b/templates/bundles/TwigBundle/Exception/error404.html.twig @@ -0,0 +1,14 @@ +{% extends theme ~ '/layout.html.twig' %} +{% block title %}{{ 'Not found' | trans }} - {{ name }}{% endblock %} +{% block main_content %} +
+
+

+ 404 +

+
+ {{ 'Page not found!' | trans }} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/bundles/TwigBundle/Exception/error500.html.twig b/templates/bundles/TwigBundle/Exception/error500.html.twig new file mode 100644 index 0000000..8567d21 --- /dev/null +++ b/templates/bundles/TwigBundle/Exception/error500.html.twig @@ -0,0 +1,17 @@ +{% extends theme ~ '/layout.html.twig' %} +{% block title %}{{ 'Error' | trans }} - {{ name }}{% endblock %} +{% block main_content %} +
+
+

+ {{ 'Oops!' | trans }} +

+
+ {{ 'Internal server error' | trans }} +
+ + {{ 'Report' | trans }} + +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/default/activity/event/torrent/add.html.twig b/templates/default/activity/event/torrent/add.html.twig index 3a113e7..b7e2610 100644 --- a/templates/default/activity/event/torrent/add.html.twig +++ b/templates/default/activity/event/torrent/add.html.twig @@ -1,22 +1,19 @@
- + {{ 'identicon' | trans }} - - {{ 'have added torrent' | trans }} - + {{ 'have added torrent' | trans }} {% if session.user.moderator or session.user.owner %} {{ torrent.name }} - {% if torrent.approved == false %} - #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/add.rss.twig b/templates/default/activity/event/torrent/add.rss.twig index 174c82c..db55c4c 100644 --- a/templates/default/activity/event/torrent/add.rss.twig +++ b/templates/default/activity/event/torrent/add.rss.twig @@ -6,9 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/approve/add.html.twig b/templates/default/activity/event/torrent/approve/add.html.twig index ab2350c..e394ecb 100644 --- a/templates/default/activity/event/torrent/approve/add.html.twig +++ b/templates/default/activity/event/torrent/approve/add.html.twig @@ -11,7 +11,11 @@ {{ torrent.name }} {% else %} - {% if torrent.sensitive == true %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/approve/add.rss.twig b/templates/default/activity/event/torrent/approve/add.rss.twig index 7287540..e378199 100644 --- a/templates/default/activity/event/torrent/approve/add.rss.twig +++ b/templates/default/activity/event/torrent/approve/add.rss.twig @@ -6,7 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.sensitive == true %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/approve/delete.html.twig b/templates/default/activity/event/torrent/approve/delete.html.twig index 6051686..50d6079 100644 --- a/templates/default/activity/event/torrent/approve/delete.html.twig +++ b/templates/default/activity/event/torrent/approve/delete.html.twig @@ -10,13 +10,12 @@ {{ torrent.name }} - {% if torrent.approved == false %} - #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/approve/delete.rss.twig b/templates/default/activity/event/torrent/approve/delete.rss.twig index d358829..7252d9f 100644 --- a/templates/default/activity/event/torrent/approve/delete.rss.twig +++ b/templates/default/activity/event/torrent/approve/delete.rss.twig @@ -6,7 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.sensitive == true %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/categories/add.html.twig b/templates/default/activity/event/torrent/categories/add.html.twig new file mode 100644 index 0000000..1d081c7 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/add.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have added categories edition' | trans }} + {% if torrent.categories.exist %} + + #{{ torrent.categories.id }} + + {% else %} + #{{ torrent.categories.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/add.rss.twig b/templates/default/activity/event/torrent/categories/add.rss.twig new file mode 100644 index 0000000..2262f72 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/add.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have added categories edition' | trans }} + #{{ torrent.categories.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity-{{ id }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/approve/add.html.twig b/templates/default/activity/event/torrent/categories/approve/add.html.twig new file mode 100644 index 0000000..19c4836 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/approve/add.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have approved categories edition' | trans }} + {% if torrent.categories.exist %} + + #{{ torrent.categories.id }} + + {% else %} + #{{ torrent.categories.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/approve/add.rss.twig b/templates/default/activity/event/torrent/categories/approve/add.rss.twig new file mode 100644 index 0000000..9395f46 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/approve/add.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have approved categories edition' | trans }} + #{{ torrent.categories.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity-{{ id }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/approve/delete.html.twig b/templates/default/activity/event/torrent/categories/approve/delete.html.twig new file mode 100644 index 0000000..2d9b682 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/approve/delete.html.twig @@ -0,0 +1,41 @@ +
+
+ + {{ 'identicon' | trans }} + + + {{ 'have disapproved categories edition' | trans }} + + {% if torrent.categories.exist %} + + #{{ torrent.categories.id }} + + {% else %} + #{{ torrent.categories.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/approve/delete.rss.twig b/templates/default/activity/event/torrent/categories/approve/delete.rss.twig new file mode 100644 index 0000000..a6a6970 --- /dev/null +++ b/templates/default/activity/event/torrent/categories/approve/delete.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have disapproved categories edition' | trans }} + #{{ torrent.categories.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity-{{ id }} + {{ url('torrent_categories_edit', { torrentId : torrent.id, torrentCategoriesId : torrent.categories.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/delete.html.twig b/templates/default/activity/event/torrent/categories/delete.html.twig new file mode 100644 index 0000000..06b972b --- /dev/null +++ b/templates/default/activity/event/torrent/categories/delete.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have deleted categories edition' | trans }} + {% if torrent.categories.exist %} + + #{{ torrent.categories.id }} + + {% else %} + #{{ torrent.categories.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/categories/delete.rss.twig b/templates/default/activity/event/torrent/categories/delete.rss.twig new file mode 100644 index 0000000..063750b --- /dev/null +++ b/templates/default/activity/event/torrent/categories/delete.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have deleted categories edition' | trans }} + #{{ torrent.categories.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_categories_edit', { torrentId : torrent.id }) }}#activity-{{ id }} + {{ url('torrent_categories_edit', { torrentId : torrent.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/download/file/add.html.twig b/templates/default/activity/event/torrent/download/file/add.html.twig index 33f83ad..1e0e5e3 100644 --- a/templates/default/activity/event/torrent/download/file/add.html.twig +++ b/templates/default/activity/event/torrent/download/file/add.html.twig @@ -3,7 +3,7 @@ {{ 'identicon' | trans }} - + {{ 'have downloaded torrent file' | trans }} {% if session.user.moderator or session.user.owner %} @@ -11,12 +11,14 @@ {{ torrent.name }} {% if torrent.approved == false %} - #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/download/file/add.rss.twig b/templates/default/activity/event/torrent/download/file/add.rss.twig index ebeaf7c..d9bee5b 100644 --- a/templates/default/activity/event/torrent/download/file/add.rss.twig +++ b/templates/default/activity/event/torrent/download/file/add.rss.twig @@ -6,9 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/download/magnet/add.html.twig b/templates/default/activity/event/torrent/download/magnet/add.html.twig index a3aa52a..edfc68c 100644 --- a/templates/default/activity/event/torrent/download/magnet/add.html.twig +++ b/templates/default/activity/event/torrent/download/magnet/add.html.twig @@ -11,12 +11,14 @@ {{ torrent.name }} {% if torrent.approved == false %} - #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/download/magnet/add.rss.twig b/templates/default/activity/event/torrent/download/magnet/add.rss.twig index 6afad66..e29157f 100644 --- a/templates/default/activity/event/torrent/download/magnet/add.rss.twig +++ b/templates/default/activity/event/torrent/download/magnet/add.rss.twig @@ -6,9 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/locales/add.html.twig b/templates/default/activity/event/torrent/locales/add.html.twig index 1d2541f..facd581 100644 --- a/templates/default/activity/event/torrent/locales/add.html.twig +++ b/templates/default/activity/event/torrent/locales/add.html.twig @@ -1,11 +1,9 @@
- + {{ 'identicon' | trans }} - - {{ 'have added locales edition' | trans }} - + {{ 'have added locales edition' | trans }} {% if torrent.locales.exist %} #{{ torrent.locales.id }} @@ -22,9 +20,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/locales/add.rss.twig b/templates/default/activity/event/torrent/locales/add.rss.twig index 20a65f5..81ec578 100644 --- a/templates/default/activity/event/torrent/locales/add.rss.twig +++ b/templates/default/activity/event/torrent/locales/add.rss.twig @@ -8,9 +8,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/locales/approve/add.html.twig b/templates/default/activity/event/torrent/locales/approve/add.html.twig index c32780b..27ed85b 100644 --- a/templates/default/activity/event/torrent/locales/approve/add.html.twig +++ b/templates/default/activity/event/torrent/locales/approve/add.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have approved locales edition' | trans }} @@ -20,9 +20,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/locales/approve/add.rss.twig b/templates/default/activity/event/torrent/locales/approve/add.rss.twig index fc86232..64dbcdd 100644 --- a/templates/default/activity/event/torrent/locales/approve/add.rss.twig +++ b/templates/default/activity/event/torrent/locales/approve/add.rss.twig @@ -8,9 +8,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/locales/approve/delete.html.twig b/templates/default/activity/event/torrent/locales/approve/delete.html.twig index c9653e9..d49dcb1 100644 --- a/templates/default/activity/event/torrent/locales/approve/delete.html.twig +++ b/templates/default/activity/event/torrent/locales/approve/delete.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} @@ -22,9 +22,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/locales/approve/delete.rss.twig b/templates/default/activity/event/torrent/locales/approve/delete.rss.twig index de936f1..b0cbada 100644 --- a/templates/default/activity/event/torrent/locales/approve/delete.rss.twig +++ b/templates/default/activity/event/torrent/locales/approve/delete.rss.twig @@ -8,9 +8,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/locales/delete.html.twig b/templates/default/activity/event/torrent/locales/delete.html.twig index a86610b..4327e41 100644 --- a/templates/default/activity/event/torrent/locales/delete.html.twig +++ b/templates/default/activity/event/torrent/locales/delete.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have deleted locales edition' | trans }} @@ -20,9 +20,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/locales/delete.rss.twig b/templates/default/activity/event/torrent/locales/delete.rss.twig index 2c26702..1bb311d 100644 --- a/templates/default/activity/event/torrent/locales/delete.rss.twig +++ b/templates/default/activity/event/torrent/locales/delete.rss.twig @@ -8,9 +8,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/poster/add.html.twig b/templates/default/activity/event/torrent/poster/add.html.twig new file mode 100644 index 0000000..519a6f0 --- /dev/null +++ b/templates/default/activity/event/torrent/poster/add.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have added poster edition' | trans }} + {% if torrent.poster.exist %} + + #{{ torrent.poster.id }} + + {% else %} + #{{ torrent.poster.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/add.rss.twig b/templates/default/activity/event/torrent/poster/add.rss.twig new file mode 100644 index 0000000..348e851 --- /dev/null +++ b/templates/default/activity/event/torrent/poster/add.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have added poster edition' | trans }} + #{{ torrent.poster.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity-{{ id }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/approve/add.html.twig b/templates/default/activity/event/torrent/poster/approve/add.html.twig new file mode 100644 index 0000000..35685c0 --- /dev/null +++ b/templates/default/activity/event/torrent/poster/approve/add.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have approved poster edition' | trans }} + {% if torrent.poster.exist %} + + #{{ torrent.poster.id }} + + {% else %} + #{{ torrent.poster.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/approve/add.rss.twig b/templates/default/activity/event/torrent/poster/approve/add.rss.twig new file mode 100644 index 0000000..3a75b3d --- /dev/null +++ b/templates/default/activity/event/torrent/poster/approve/add.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have approved poster edition' | trans }} + #{{ torrent.poster.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity-{{ id }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/approve/delete.html.twig b/templates/default/activity/event/torrent/poster/approve/delete.html.twig new file mode 100644 index 0000000..483a79f --- /dev/null +++ b/templates/default/activity/event/torrent/poster/approve/delete.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have disapproved poster edition' | trans }} + {% if torrent.poster.exist %} + + #{{ torrent.poster.id }} + + {% else %} + #{{ torrent.poster.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/approve/delete.rss.twig b/templates/default/activity/event/torrent/poster/approve/delete.rss.twig new file mode 100644 index 0000000..42d6527 --- /dev/null +++ b/templates/default/activity/event/torrent/poster/approve/delete.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have disapproved poster edition' | trans }} + #{{ torrent.poster.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity-{{ id }} + {{ url('torrent_poster_edit', { torrentId : torrent.id, torrentPosterId : torrent.poster.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/delete.html.twig b/templates/default/activity/event/torrent/poster/delete.html.twig new file mode 100644 index 0000000..c3c7293 --- /dev/null +++ b/templates/default/activity/event/torrent/poster/delete.html.twig @@ -0,0 +1,39 @@ +
+
+ + {{ 'identicon' | trans }} + + {{ 'have deleted poster edition' | trans }} + {% if torrent.poster.exist %} + + #{{ torrent.poster.id }} + + {% else %} + #{{ torrent.poster.id }} + {% endif %} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% if torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% endif %} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/poster/delete.rss.twig b/templates/default/activity/event/torrent/poster/delete.rss.twig new file mode 100644 index 0000000..4b7bf6a --- /dev/null +++ b/templates/default/activity/event/torrent/poster/delete.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have deleted poster edition' | trans }} + #{{ torrent.poster.id }} + {{ 'for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_poster_edit', { torrentId : torrent.id }) }}#activity-{{ id }} + {{ url('torrent_poster_edit', { torrentId : torrent.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/sensitive/add.html.twig b/templates/default/activity/event/torrent/sensitive/add.html.twig index 843fa2d..e21705a 100644 --- a/templates/default/activity/event/torrent/sensitive/add.html.twig +++ b/templates/default/activity/event/torrent/sensitive/add.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have added sensitive edition' | trans }} @@ -20,10 +20,12 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/sensitive/add.rss.twig b/templates/default/activity/event/torrent/sensitive/add.rss.twig index 4280165..e1036bb 100644 --- a/templates/default/activity/event/torrent/sensitive/add.rss.twig +++ b/templates/default/activity/event/torrent/sensitive/add.rss.twig @@ -8,10 +8,12 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} {% endif %} diff --git a/templates/default/activity/event/torrent/sensitive/approve/add.html.twig b/templates/default/activity/event/torrent/sensitive/approve/add.html.twig index 627d38c..4bad7b0 100644 --- a/templates/default/activity/event/torrent/sensitive/approve/add.html.twig +++ b/templates/default/activity/event/torrent/sensitive/approve/add.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have approved sensitive edition' | trans }} @@ -20,10 +20,12 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/sensitive/approve/add.rss.twig b/templates/default/activity/event/torrent/sensitive/approve/add.rss.twig index f8d029e..583a42f 100644 --- a/templates/default/activity/event/torrent/sensitive/approve/add.rss.twig +++ b/templates/default/activity/event/torrent/sensitive/approve/add.rss.twig @@ -8,10 +8,12 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} {% endif %} diff --git a/templates/default/activity/event/torrent/sensitive/approve/delete.html.twig b/templates/default/activity/event/torrent/sensitive/approve/delete.html.twig index 7c8de47..c02a804 100644 --- a/templates/default/activity/event/torrent/sensitive/approve/delete.html.twig +++ b/templates/default/activity/event/torrent/sensitive/approve/delete.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have disapproved sensitive edition' | trans }} @@ -20,10 +20,12 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/sensitive/approve/delete.rss.twig b/templates/default/activity/event/torrent/sensitive/approve/delete.rss.twig index da8ea11..f1a697f 100644 --- a/templates/default/activity/event/torrent/sensitive/approve/delete.rss.twig +++ b/templates/default/activity/event/torrent/sensitive/approve/delete.rss.twig @@ -8,10 +8,12 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} {% endif %} diff --git a/templates/default/activity/event/torrent/sensitive/delete.html.twig b/templates/default/activity/event/torrent/sensitive/delete.html.twig index f212a44..a2640dc 100644 --- a/templates/default/activity/event/torrent/sensitive/delete.html.twig +++ b/templates/default/activity/event/torrent/sensitive/delete.html.twig @@ -1,6 +1,6 @@
- + {{ 'identicon' | trans }} {{ 'have deleted sensitive edition' | trans }} @@ -20,10 +20,12 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/sensitive/delete.rss.twig b/templates/default/activity/event/torrent/sensitive/delete.rss.twig index d2254e8..3c13424 100644 --- a/templates/default/activity/event/torrent/sensitive/delete.rss.twig +++ b/templates/default/activity/event/torrent/sensitive/delete.rss.twig @@ -8,10 +8,12 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} - #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} {% else %} {{ torrent.name }} {% endif %} diff --git a/templates/default/activity/event/torrent/star/add.html.twig b/templates/default/activity/event/torrent/star/add.html.twig index 8b911cc..9d27547 100644 --- a/templates/default/activity/event/torrent/star/add.html.twig +++ b/templates/default/activity/event/torrent/star/add.html.twig @@ -1,11 +1,9 @@
- + {{ 'identicon' | trans }} - {{ 'have added star for torrent' | trans }} - {% if session.user.moderator or session.user.owner %} {{ torrent.name }} @@ -14,9 +12,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/star/add.rss.twig b/templates/default/activity/event/torrent/star/add.rss.twig index d56a7b5..a5fb324 100644 --- a/templates/default/activity/event/torrent/star/add.rss.twig +++ b/templates/default/activity/event/torrent/star/add.rss.twig @@ -6,9 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/star/delete.html.twig b/templates/default/activity/event/torrent/star/delete.html.twig index 0582790..a160792 100644 --- a/templates/default/activity/event/torrent/star/delete.html.twig +++ b/templates/default/activity/event/torrent/star/delete.html.twig @@ -1,12 +1,10 @@
- + {{ 'identicon' | trans }} - {{ 'have removed star from torrent' | trans }} - {% if session.user.moderator or session.user.owner %} {{ torrent.name }} @@ -15,9 +13,11 @@ #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) {% endif %} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} diff --git a/templates/default/activity/event/torrent/star/delete.rss.twig b/templates/default/activity/event/torrent/star/delete.rss.twig index e24ff3a..6c4c02c 100644 --- a/templates/default/activity/event/torrent/star/delete.rss.twig +++ b/templates/default/activity/event/torrent/star/delete.rss.twig @@ -6,9 +6,11 @@ {% if session.user.moderator or session.user.owner %} {{ torrent.name }} {% else %} - {% if torrent.approved == false %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) - {% elseif torrent.sensitive == true %} + {% elseif torrent.sensitive == true and session.user.sensitive == true %} #{{ torrent.id }} ({{ 'sensitive' | trans }}) {% else %} {{ torrent.name }} diff --git a/templates/default/activity/event/torrent/status/add.html.twig b/templates/default/activity/event/torrent/status/add.html.twig new file mode 100644 index 0000000..0466adc --- /dev/null +++ b/templates/default/activity/event/torrent/status/add.html.twig @@ -0,0 +1,30 @@ +
+
+ + {{ 'identicon' | trans }} + + + {{ 'have enabled torrent' | trans }} + + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/status/add.rss.twig b/templates/default/activity/event/torrent/status/add.rss.twig new file mode 100644 index 0000000..1f21d67 --- /dev/null +++ b/templates/default/activity/event/torrent/status/add.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have enabled torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + <a href="{{ path('torrent_info', { torrentId : torrent.id }) }}"> + {{ torrent.name }} + </a> + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity-{{ id }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/status/delete.html.twig b/templates/default/activity/event/torrent/status/delete.html.twig new file mode 100644 index 0000000..3c5dea3 --- /dev/null +++ b/templates/default/activity/event/torrent/status/delete.html.twig @@ -0,0 +1,30 @@ +
+
+ + {{ 'identicon' | trans }} + + + {{ 'have disabled torrent' | trans }} + + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/status/delete.rss.twig b/templates/default/activity/event/torrent/status/delete.rss.twig new file mode 100644 index 0000000..f1ef108 --- /dev/null +++ b/templates/default/activity/event/torrent/status/delete.rss.twig @@ -0,0 +1,26 @@ + + + {{ 'User' | trans }} + #{{ user.id }} + {{ 'have disabled torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + <a href="{{ path('torrent_info', { torrentId : torrent.id }) }}"> + {{ torrent.name }} + </a> + {% endif %} + {% endif %} + + #{{ user.id }} + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity-{{ id }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/torrent/wanted/add.html.twig b/templates/default/activity/event/torrent/wanted/add.html.twig new file mode 100644 index 0000000..86a8744 --- /dev/null +++ b/templates/default/activity/event/torrent/wanted/add.html.twig @@ -0,0 +1,25 @@ +
+
+ {{ 'Seeders wanted for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + + {{ torrent.name }} + + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + + {{ torrent.name }} + + {% endif %} + {% endif %} +
+
+ {{ added | format_ago }} +
+
\ No newline at end of file diff --git a/templates/default/activity/event/torrent/wanted/add.rss.twig b/templates/default/activity/event/torrent/wanted/add.rss.twig new file mode 100644 index 0000000..9459b57 --- /dev/null +++ b/templates/default/activity/event/torrent/wanted/add.rss.twig @@ -0,0 +1,21 @@ + + + {{ 'Seeders wanted for torrent' | trans }} + {% if session.user.moderator or session.user.owner %} + {{ torrent.name }} + {% else %} + {% if torrent.status == false %} + #{{ torrent.id }} ({{ 'disabled' | trans }}) + {% elseif torrent.approved == false %} + #{{ torrent.id }} ({{ 'waiting for approve' | trans }}) + {% elseif torrent.sensitive == true and session.user.sensitive == true %} + #{{ torrent.id }} ({{ 'sensitive' | trans }}) + {% else %} + {{ torrent.name }} + {% endif %} + {% endif %} + + {{ added | date('D, d M Y h:i:s O') }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity-{{ id }} + {{ url('torrent_info', { torrentId : torrent.id }) }}#activity + \ No newline at end of file diff --git a/templates/default/activity/event/user/add.html.twig b/templates/default/activity/event/user/add.html.twig index ad3a920..974a8d1 100644 --- a/templates/default/activity/event/user/add.html.twig +++ b/templates/default/activity/event/user/add.html.twig @@ -5,7 +5,7 @@ {{ 'identicon' | trans }} - {{ 'have joined' | trans }} {{ name }} + {{ 'have joined' | trans }}
diff --git a/templates/default/activity/event/user/add.rss.twig b/templates/default/activity/event/user/add.rss.twig index 9c0a9ea..4f4fdd1 100644 --- a/templates/default/activity/event/user/add.rss.twig +++ b/templates/default/activity/event/user/add.rss.twig @@ -1,5 +1,5 @@ - {{ 'User' | trans }} #{{ user.id }} {{ 'have joined' | trans }} {{ name }} + {{ 'User' | trans }} #{{ user.id }} {{ 'have joined' | trans }} #{{ user.id }} {{ added | date('D, d M Y h:i:s O') }} {{ url('user_info', { userId : user.id }) }}#activity-{{ id }} diff --git a/templates/default/layout.html.twig b/templates/default/layout.html.twig index b6c1775..99c0eeb 100644 --- a/templates/default/layout.html.twig +++ b/templates/default/layout.html.twig @@ -3,6 +3,9 @@ {% block title %}{{ name }}{% endblock %} + {% block keywords %} + + {% endblock %} {% block stylesheets %} @@ -13,15 +16,19 @@
- + {#32 +
+ {{ 'Upload any torrent - download with Yggdrasil' | trans | format(path('torrent_submit')) | raw }} +
+ #} {% block header_search %} {{ render(controller( 'App\\Controller\\SearchController::module', { - query : app.request.get('query'), - type : app.request.get('type') + request: app.request } )) }} {% endblock %} diff --git a/templates/default/search/module.html.twig b/templates/default/search/module.html.twig index b996bf7..8b1b99b 100644 --- a/templates/default/search/module.html.twig +++ b/templates/default/search/module.html.twig @@ -1,4 +1,69 @@
- + + {% if filter %} + +
+
+ {{ 'Locales' | trans }} +
+
+ {% for locale in locales | sort %} + {#{% if locale.total %}#} +
+ {% if locale.checked %} + + {% else %} + + {% endif %} + +
+ {#{% endif %}#} + {% endfor %} +
+
+ {{ 'Categories' | trans }} +
+
+ {% for category in categories | sort %} + {#{% if category.total %}#} +
+ {% if category.checked %} + + {% else %} + + {% endif %} + +
+ {#{% endif %}#} + {% endfor %} +
+
+ {{ 'other' | trans | u.title }} +
+
+ {% if sensitive.checked %} + + {% else %} + + {% endif %} + +
+
+ {% endif %}
\ No newline at end of file diff --git a/templates/default/torrent/edit/categories.html.twig b/templates/default/torrent/edit/categories.html.twig new file mode 100644 index 0000000..417828d --- /dev/null +++ b/templates/default/torrent/edit/categories.html.twig @@ -0,0 +1,109 @@ +{% extends 'default/layout.html.twig' %} +{% block title %}{{'Edit categories'|trans }} - {{'Torrent'|trans }} #{{ torrentId }} - {{ name }}{% endblock %} +{% block main_content %} +
+
+

+ {{'Edit categories for torrent' | trans }} + #{{ torrentId }} +

+
+
+
+ + + + + + + {% for error in form.categories.error %} +
+ {{ error }} +
+ {% endfor %} +
+ {% for category in categories | sort %} +
+ {% if category in form.categories.attribute.value %} + + {% else %} + + {% endif %} + +
+ {% endfor %} + {# + + #} +
+
+
+ +
+
+ {% for edition in editions %} +
+ {% if edition.active %} + {{ edition.added | format_ago }} + {% else %} + + {{ edition.added | format_ago }} + + {% endif %} + {{ 'by'|trans }} + + {{'identicon'|trans }} + +
+ {% if session.moderator or session.owner %} + + + + + + + {% endif %} + {% if edition.approved %} + {% if session.moderator %} + + + + + + {% else %} + + + + + + {% endif %} + {% else %} + {% if session.moderator %} + + + + + + {% else %} + + + + + + {% endif %} + {% endif %} +
+
+ {% endfor %} +{% endblock %} diff --git a/templates/default/torrent/edit/locales.html.twig b/templates/default/torrent/edit/locales.html.twig index 1245721..dcab8db 100644 --- a/templates/default/torrent/edit/locales.html.twig +++ b/templates/default/torrent/edit/locales.html.twig @@ -24,7 +24,7 @@
{% endfor %}
- {% for locale in locales %} + {% for locale in locales | sort %}
{% if locale in form.locales.attribute.value %} diff --git a/templates/default/torrent/edit/poster.html.twig b/templates/default/torrent/edit/poster.html.twig new file mode 100644 index 0000000..e4ed5e9 --- /dev/null +++ b/templates/default/torrent/edit/poster.html.twig @@ -0,0 +1,121 @@ +{% extends 'default/layout.html.twig' %} +{% block title %}{{ 'Edit torrent poster' | trans }} - {{ 'Torrent' | trans }} #{{ torrentId }} - {{ name }}{% endblock %} +{% block main_content %} +
+
+

+ {{'Edit poster for torrent' | trans }} + #{{ torrentId }} +

+
+
+
+ {% for error in form.poster.error %} +
+ {{ error }} +
+ {% endfor %} + +
+
+ + + + + + +
+
+ +
+
+ {% for edition in editions %} +
+ {% if edition.active %} + {{ edition.added | format_ago }} + {% else %} + + {{ edition.added | format_ago }} + + {% endif %} + {{ 'by' | trans }} + + {{'identicon'|trans }} + +
+ {% if session.moderator or session.owner %} + + + + + + + {% endif %} + {% if edition.approved %} + {% if session.moderator %} + + + + + + {% else %} + + + + + + {% endif %} + {% else %} + {% if session.moderator %} + + + + + + {% else %} + + + + + + {% endif %} + {% endif %} +
+ {% if edition.active %} +
+ +
+ + + + + + +
+
+
+ +
+
+ {% endif %} +
+ {% endfor %} +{% endblock %} diff --git a/templates/default/torrent/info.html.twig b/templates/default/torrent/info.html.twig index bd09bf9..dda2a72 100644 --- a/templates/default/torrent/info.html.twig +++ b/templates/default/torrent/info.html.twig @@ -2,16 +2,18 @@ {% import _self as self %} {% for key, value in tree %} {% if value is iterable %} -
-
- {{ key }} -
+
+ {{ key }} +
+
{{ self.recursive_file_tree(value) }}
{% else %} -
- {{ key }} -
+
+
+ {{ key }} +
+
{{ value | format_bytes }}
@@ -21,59 +23,65 @@ {% from _self import recursive_file_tree %} {% extends 'default/layout.html.twig' %} {% block title %}{{ file.name }} - {{ 'Torrent' | trans }} #{{ torrent.id }}{% if pagination.page > 1 %} - {{ 'Page' | trans }} {{ pagination.page }}{% endif %} - {{ name }}{% endblock %} +{% block keywords %} + {% if torrent.keywords %} + + {% endif %} +{% endblock %} {% block main_content %} -
+

{{ file.name }} {#{{ 'Torrent' | trans }} #{{ torrent.id }}#}

- {% if user.moderator %} + {% if session.moderator or session.owner %} + {% if session.moderator %} + + + + + {% endif %} {% endif %} {% endif %} + + + + {% if file.source %} {% endif %} @@ -204,7 +249,8 @@ {{ 'Software' | trans }} {% endif %} @@ -214,7 +260,8 @@ {{ 'Comment' | trans }} {% endif %} @@ -285,7 +332,7 @@
{% for tracker, status in trackers %} -
+
{% if status %} {{ tracker }} {% else %} @@ -302,23 +349,41 @@ {% endfor %}
- + - {{ 'Locales' | trans }} + {{ 'Locale' | trans }}
{% if torrent.locales %}
- {% for i, locale in torrent.locales %}{% if i > 0 %},{% endif %} {{ locale|locale_name(locale)|u.title }}{% endfor %} + {% set i = 0 %} + {% for locale in torrent.locales | sort %}{% if i > 0 %},{% endif %} {{ locale | locale_name(locale) | u.title }}{% set i = i + 1 %}{% endfor %}
{% endif %}
- + + + + + + {{ 'Category' | trans }} +
+
+ {% if torrent.categories %} +
+ {% set i = 0 %} + {% for category in torrent.categories | sort %}{% if i > 0 %},{% endif %} {{ category | trans_category | u.title }}{% set i = i + 1 %}{% endfor %} +
+ {% endif %} +
+
+
+
+ + + + + + {{ 'Poster' | trans }} +
+
+ {% if torrent.poster %} + {{ 'Yes' | trans }} + {% else %} + {{ 'No' | trans }} + {% endif %} +
+
diff --git a/templates/default/torrent/list.html.twig b/templates/default/torrent/list.html.twig index c74e816..93e27d1 100644 --- a/templates/default/torrent/list.html.twig +++ b/templates/default/torrent/list.html.twig @@ -2,18 +2,52 @@ {% block title %}{% if query %}{{ query }} - {{ 'Search' | trans }} - {% endif %}{{ name }}{% endblock %} {% block main_content %}
-

{{ 'Recent uploads' | trans }}

- - - - - - - + {% if query %} +

{{ 'Search results' | trans }}

+ + {% if app.request.get('filter') %} + + + + + + + + + + + {% else %} + + + + + + + + + + + {% endif %} + + {% else %} +

{{ 'Recent uploads' | trans }}

+ + + + + + + + {% endif %}
{% if torrents %} {% for torrent in torrents %} -
+

@@ -21,122 +55,195 @@ {{ torrent.file.name }}

- {% if torrent.scrape.leechers == 0 and torrent.scrape.leechers == 0 %} - + {% if torrent.scrape.leechers > 0 and torrent.scrape.seeders == 0 %} + {{ 'wanted' | trans }} - + + {% endif %} + {% if torrent.status == false %} + + + + + + {% endif %} {% if torrent.approved == false %} - + {% endif %} {% if torrent.sensitive == true %} - + {% endif %} + {% if torrent.file.hash.v2 %} + + + + + + {% endif %} + {% if torrent.file.hash.v1 and torrent.file.hash.v2 %} + + + + + + {% endif %}
{% if torrent.keywords %}
- {% for keyword in torrent.keywords %} - + {% for keyword, quantity in torrent.keywords %} + #{{ keyword }} {% endfor %}
{% endif %}
- {# - - {{ torrent.added | format_ago }} - {{ 'by' | trans }} - - {{ 'identicon' | trans }} - - - #} - + {{ torrent.file.size | format_bytes }} - + - - + + - + {{ torrent.scrape.seeders }} - + - - + + - + {{ torrent.scrape.peers }} - + - - + + - + {{ torrent.scrape.leechers }} - +
{% endfor %} + {% if pagination.pages > 1 %} +
+ {{ 'Page' | trans | lower }} {{ pagination.page }} / {{ pagination.pages }} + {% if query %} + {% if pagination.page > 1 %} + {% if pagination.page == 2 %} + + {{ 'Back' | trans | lower }} + + {% else %} + + {{ 'Back' | trans | lower }} + + {% endif %} + {% endif %} + {% if pagination.page < pagination.pages %} + + {{ 'Next' | trans | lower }} + + {% endif %} + {% else %} + {% if pagination.page > 1 %} + {% if pagination.page == 2 %} + + {{ 'Back' | trans | lower }} + + {% else %} + + {{ 'Back' | trans | lower }} + + {% endif %} + {% endif %} + {% if pagination.page < pagination.pages %} + + {{ 'Next' | trans | lower }} + + {% endif %} + {% endif %} +
+ {% endif %} {% else %}
diff --git a/templates/default/torrent/sitemap.xml.twig b/templates/default/torrent/sitemap.xml.twig new file mode 100644 index 0000000..99d77e5 --- /dev/null +++ b/templates/default/torrent/sitemap.xml.twig @@ -0,0 +1,15 @@ + + + {% for torrent in torrents %} + + {{ torrent.added | date('Y-m-d') }} + {% for code in locales %} + {% if code == locale %} + {{ url('torrent_info', { '_locale': code , torrentId : torrent.id }) }} + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} + diff --git a/templates/default/torrent/submit.html.twig b/templates/default/torrent/submit.html.twig index 27f6a14..c36da9a 100644 --- a/templates/default/torrent/submit.html.twig +++ b/templates/default/torrent/submit.html.twig @@ -31,7 +31,7 @@
{% endfor %}
- {% for locale in locales %} + {% for locale in locales | sort %}
{% if locale in form.locales.attribute.value %} @@ -48,9 +48,42 @@ #}
+
+
+ + + + + + + {% for error in form.categories.error %} +
+ {{ error }} +
+ {% endfor %} +
+ {% for category in categories | sort %} +
+ {% if category in form.categories.attribute.value %} + + {% else %} + + {% endif %} + +
+ {% endfor %} + {# + {{'Other...'|trans }} + #} +
+
-
#}
@@ -83,19 +91,19 @@
- {{ 'Approved' | trans }} + {{ 'Enabled' | trans }} - {% if torrent.approved %} + {% if torrent.status %} {{ 'Yes' | trans }} - + {% else %} {{ 'No' | trans }} - + @@ -103,6 +111,30 @@ {% endif %}
+ {{ 'Approved' | trans }} + + {% if torrent.approved %} + {{ 'Yes' | trans }} + + + + + + {% else %} + {{ 'No' | trans }} + + + + + + {% endif %} +
@@ -188,13 +220,26 @@
+ {{ 'Private' | trans }} + + {% if file.private %} + {{ 'Yes' | trans }} + {% else %} + {{ 'No' | trans }} + {% endif %} +
{{ 'Source' | trans }} - {{ file.source }} + {# strip all tags then apply whitelist markdown filters to prevent ping from remote #} + {{ file.source | trim | striptags | url_to_markdown | markdown_to_html | nl2br }}
- {{ file.software }} + {# strip all tags then apply whitelist markdown filters to prevent ping from remote #} + {{ file.software | trim | striptags | url_to_markdown | markdown_to_html | nl2br }}
- {{ file.comment }} + {# strip all tags then apply whitelist markdown filters to prevent ping from remote #} + {{ file.comment | trim | striptags | url_to_markdown | markdown_to_html | nl2br }}
- {% if user.address %} + {% if session.owner or session.moderator %} + + + + + + + diff --git a/templates/default/user/module.html.twig b/templates/default/user/module.html.twig index 14978f6..5dc7e51 100644 --- a/templates/default/user/module.html.twig +++ b/templates/default/user/module.html.twig @@ -1,4 +1,4 @@ -
+
{% if route == 'torrent_recent' %} diff --git a/templates/default/user/settings.html.twig b/templates/default/user/settings.html.twig index 606b3fb..49fcbed 100644 --- a/templates/default/user/settings.html.twig +++ b/templates/default/user/settings.html.twig @@ -58,6 +58,23 @@
+ + + + - - + + + + - @@ -104,20 +147,22 @@ + {% set i = 0 %} {% for group, event in events %} + {% set i = i + 1 %} - - diff --git a/translations/messages+intl-icu.cs.xlf b/translations/messages+intl-icu.cs.xlf index fd1d625..e661df7 100644 --- a/translations/messages+intl-icu.cs.xlf +++ b/translations/messages+intl-icu.cs.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.de.xlf b/translations/messages+intl-icu.de.xlf index 2ccf8ab..754006d 100644 --- a/translations/messages+intl-icu.de.xlf +++ b/translations/messages+intl-icu.de.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.en.xlf b/translations/messages+intl-icu.en.xlf index 308f1eb..cbd0dc2 100644 --- a/translations/messages+intl-icu.en.xlf +++ b/translations/messages+intl-icu.en.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.eo.xlf b/translations/messages+intl-icu.eo.xlf index 207f2ef..5e611d1 100644 --- a/translations/messages+intl-icu.eo.xlf +++ b/translations/messages+intl-icu.eo.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.es.xlf b/translations/messages+intl-icu.es.xlf index cc77035..9638ae5 100644 --- a/translations/messages+intl-icu.es.xlf +++ b/translations/messages+intl-icu.es.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.fr.xlf b/translations/messages+intl-icu.fr.xlf index 7c262a4..daae954 100644 --- a/translations/messages+intl-icu.fr.xlf +++ b/translations/messages+intl-icu.fr.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.he.xlf b/translations/messages+intl-icu.he.xlf index e0da032..a324b84 100644 --- a/translations/messages+intl-icu.he.xlf +++ b/translations/messages+intl-icu.he.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.it.xlf b/translations/messages+intl-icu.it.xlf index 90a2bdc..e31236c 100644 --- a/translations/messages+intl-icu.it.xlf +++ b/translations/messages+intl-icu.it.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.ja.xlf b/translations/messages+intl-icu.ja.xlf new file mode 100644 index 0000000..56c715b --- /dev/null +++ b/translations/messages+intl-icu.ja.xlf @@ -0,0 +1,918 @@ + + + +
+ +
+ + + Users + Users + + + Joined + Joined + + + Approved + Approved + + + Disapproved + Disapproved + + + User statuses + User statuses + + + Enabled + Enabled + + + Disabled + Disabled + + + User moderators + User moderators + + + Added + Added + + + Removed + Removed + + + User stars + User stars + + + Torrents + Torrents + + + Torrent locales + Torrent locales + + + Deleted + Deleted + + + Torrent sensitive + Torrent sensitive + + + Torrent stars + Torrent stars + + + Torrent downloads + Torrent downloads + + + Files + Files + + + Magnet links + Magnet links + + + Access denied + Access denied + + + At least one locale required + At least one locale required + + + Torrent file out of size limit + Torrent file out of size limit + + + Torrent file already exists + Torrent file already exists + + + Could not parse torrent file + Could not parse torrent file + + + Torrent file required + Torrent file required + + + B + B + + + Kb + Kb + + + Mb + Mb + + + Gb + Gb + + + Tb + Tb + + + Pb + Pb + + + Eb + Eb + + + Zb + Zb + + + Yb + Yb + + + now + now + + + Keyword, file, hash... + Keyword, file, hash... + + + Search + Search + + + Recent uploads + Recent uploads + + + Active leechers waiting for seeders + Active leechers waiting for seeders + + + wanted + wanted + + + Waiting for approve + Waiting for approve + + + Size + Size + + + Seeders + Seeders + + + Peers + Peers + + + Leechers + Leechers + + + Open magnet link + Open magnet link + + + Total + Total + + + Download torrent file + Download torrent file + + + Star + Star + + + Nothing found + Nothing found + + + * share new torrent file to change it + * share new torrent file to change it + + + Submit + Submit + + + Submit torrent + Submit torrent + + + Content language + Content language + + + This torrent contains selected languages + This torrent contains selected languages + + + Sensitive + Sensitive + + + Mark torrent content as sensitive + Mark torrent content as sensitive + + + Edit locales + Edit locales + + + Torrent + Torrent + + + Edit locales for torrent + Edit locales for torrent + + + cancel + cancel + + + by + by + + + identicon + identicon + + + Delete + Delete + + + Disapprove + Disapprove + + + Approve + Approve + + + Edit sensitive status + Edit sensitive status + + + Edit sensitive status for torrent + Edit sensitive status for torrent + + + Page + Page + + + Moderation + Moderation + + + Yes + Yes + + + Toggle + Toggle + + + No + No + + + Common + Common + + + ID + ID + + + MD5 + MD5 + + + Info hash v1 + Info hash v1 + + + Info hash v2 + Info hash v2 + + + Created + Created + + + Pieces + Pieces + + + Source + Source + + + Software + Software + + + Comment + Comment + + + Contributors + Contributors + + + Scrape + Scrape + + + Trackers + Trackers + + + Filtered by settings + Filtered by settings + + + Edit + Edit + + + Locales + Locales + + + Recent activity + Recent activity + + + Back + Back + + + Next + Next + + + Settings + Settings + + + Interface + Interface + + + Theme + Theme + + + Language + Language + + + Join translation + Join translation + + + Activity + Activity + + + Downloads + Downloads + + + Yggdrasil only + Yggdrasil only + + + Save + Save + + + Home + Home + + + Profile + Profile + + + User + User + + + Bookmark + Bookmark + + + Address + Address + + + Address hidden for others + Address hidden for others + + + Access + Access + + + Status + Status + + + Active + Active + + + Moderator + Moderator + + + Languages + Languages + + + Events subscribed + Events subscribed + + + undefined event + undefined event + + + have downloaded torrent file + have downloaded torrent file + + + waiting for approve + waiting for approve + + + sensitive + sensitive + + + have downloaded magnet link + have downloaded magnet link + + + have disapproved torrent + have disapproved torrent + + + have approved torrent + have approved torrent + + + have added torrent + have added torrent + + + have deleted locales edition + have deleted locales edition + + + for torrent + for torrent + + + have disapproved locales edition + have disapproved locales edition + + + have approved locales edition + have approved locales edition + + + have added locales edition + have added locales edition + + + have removed star from torrent + have removed star from torrent + + + have added star for torrent + have added star for torrent + + + have deleted sensitive edition + have deleted sensitive edition + + + have disapproved sensitive edition + have disapproved sensitive edition + + + have approved sensitive edition + have approved sensitive edition + + + have added sensitive edition + have added sensitive edition + + + have disabled + have disabled + + + have disabled user + have disabled user + + + have enabled + have enabled + + + have enabled user + have enabled user + + + have disapproved + have disapproved + + + have disapproved user + have disapproved user + + + have approved + have approved + + + have approved user + have approved user + + + have joined + have joined + + + have removed moderator permissions from + have removed moderator permissions from + + + have removed moderator permissions from user + have removed moderator permissions from user + + + have granted moderator permissions to + have granted moderator permissions to + + + have granted moderator permissions to user + have granted moderator permissions to user + + + have removed star from + have removed star from + + + have removed star from user + have removed star from user + + + have added star for + have added star for + + + have added star for user + have added star for user + + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + + +
+
diff --git a/translations/messages+intl-icu.ka.xlf b/translations/messages+intl-icu.ka.xlf index 910808f..944c10a 100644 --- a/translations/messages+intl-icu.ka.xlf +++ b/translations/messages+intl-icu.ka.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.lv.xlf b/translations/messages+intl-icu.lv.xlf index 3f47604..814cec1 100644 --- a/translations/messages+intl-icu.lv.xlf +++ b/translations/messages+intl-icu.lv.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.nl.xlf b/translations/messages+intl-icu.nl.xlf new file mode 100644 index 0000000..cb827de --- /dev/null +++ b/translations/messages+intl-icu.nl.xlf @@ -0,0 +1,918 @@ + + + +
+ +
+ + + Users + Users + + + Joined + Joined + + + Approved + Approved + + + Disapproved + Disapproved + + + User statuses + User statuses + + + Enabled + Enabled + + + Disabled + Disabled + + + User moderators + User moderators + + + Added + Added + + + Removed + Removed + + + User stars + User stars + + + Torrents + Torrents + + + Torrent locales + Torrent locales + + + Deleted + Deleted + + + Torrent sensitive + Torrent sensitive + + + Torrent stars + Torrent stars + + + Torrent downloads + Torrent downloads + + + Files + Files + + + Magnet links + Magnet links + + + Access denied + Access denied + + + At least one locale required + At least one locale required + + + Torrent file out of size limit + Torrent file out of size limit + + + Torrent file already exists + Torrent file already exists + + + Could not parse torrent file + Could not parse torrent file + + + Torrent file required + Torrent file required + + + B + B + + + Kb + Kb + + + Mb + Mb + + + Gb + Gb + + + Tb + Tb + + + Pb + Pb + + + Eb + Eb + + + Zb + Zb + + + Yb + Yb + + + now + now + + + Keyword, file, hash... + Keyword, file, hash... + + + Search + Search + + + Recent uploads + Recent uploads + + + Active leechers waiting for seeders + Active leechers waiting for seeders + + + wanted + wanted + + + Waiting for approve + Waiting for approve + + + Size + Size + + + Seeders + Seeders + + + Peers + Peers + + + Leechers + Leechers + + + Open magnet link + Open magnet link + + + Total + Total + + + Download torrent file + Download torrent file + + + Star + Star + + + Nothing found + Nothing found + + + * share new torrent file to change it + * share new torrent file to change it + + + Submit + Submit + + + Submit torrent + Submit torrent + + + Content language + Content language + + + This torrent contains selected languages + This torrent contains selected languages + + + Sensitive + Sensitive + + + Mark torrent content as sensitive + Mark torrent content as sensitive + + + Edit locales + Edit locales + + + Torrent + Torrent + + + Edit locales for torrent + Edit locales for torrent + + + cancel + cancel + + + by + by + + + identicon + identicon + + + Delete + Delete + + + Disapprove + Disapprove + + + Approve + Approve + + + Edit sensitive status + Edit sensitive status + + + Edit sensitive status for torrent + Edit sensitive status for torrent + + + Page + Page + + + Moderation + Moderation + + + Yes + Yes + + + Toggle + Toggle + + + No + No + + + Common + Common + + + ID + ID + + + MD5 + MD5 + + + Info hash v1 + Info hash v1 + + + Info hash v2 + Info hash v2 + + + Created + Created + + + Pieces + Pieces + + + Source + Source + + + Software + Software + + + Comment + Comment + + + Contributors + Contributors + + + Scrape + Scrape + + + Trackers + Trackers + + + Filtered by settings + Filtered by settings + + + Edit + Edit + + + Locales + Locales + + + Recent activity + Recent activity + + + Back + Back + + + Next + Next + + + Settings + Settings + + + Interface + Interface + + + Theme + Theme + + + Language + Language + + + Join translation + Join translation + + + Activity + Activity + + + Downloads + Downloads + + + Yggdrasil only + Yggdrasil only + + + Save + Save + + + Home + Home + + + Profile + Profile + + + User + User + + + Bookmark + Bookmark + + + Address + Address + + + Address hidden for others + Address hidden for others + + + Access + Access + + + Status + Status + + + Active + Active + + + Moderator + Moderator + + + Languages + Languages + + + Events subscribed + Events subscribed + + + undefined event + undefined event + + + have downloaded torrent file + have downloaded torrent file + + + waiting for approve + waiting for approve + + + sensitive + sensitive + + + have downloaded magnet link + have downloaded magnet link + + + have disapproved torrent + have disapproved torrent + + + have approved torrent + have approved torrent + + + have added torrent + have added torrent + + + have deleted locales edition + have deleted locales edition + + + for torrent + for torrent + + + have disapproved locales edition + have disapproved locales edition + + + have approved locales edition + have approved locales edition + + + have added locales edition + have added locales edition + + + have removed star from torrent + have removed star from torrent + + + have added star for torrent + have added star for torrent + + + have deleted sensitive edition + have deleted sensitive edition + + + have disapproved sensitive edition + have disapproved sensitive edition + + + have approved sensitive edition + have approved sensitive edition + + + have added sensitive edition + have added sensitive edition + + + have disabled + have disabled + + + have disabled user + have disabled user + + + have enabled + have enabled + + + have enabled user + have enabled user + + + have disapproved + have disapproved + + + have disapproved user + have disapproved user + + + have approved + have approved + + + have approved user + have approved user + + + have joined + have joined + + + have removed moderator permissions from + have removed moderator permissions from + + + have removed moderator permissions from user + have removed moderator permissions from user + + + have granted moderator permissions to + have granted moderator permissions to + + + have granted moderator permissions to user + have granted moderator permissions to user + + + have removed star from + have removed star from + + + have removed star from user + have removed star from user + + + have added star for + have added star for + + + have added star for user + have added star for user + + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + + +
+
diff --git a/translations/messages+intl-icu.pl.xlf b/translations/messages+intl-icu.pl.xlf index 0e3533a..b9debc7 100644 --- a/translations/messages+intl-icu.pl.xlf +++ b/translations/messages+intl-icu.pl.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.pt.xlf b/translations/messages+intl-icu.pt.xlf index 3d7be42..bc8dc0f 100644 --- a/translations/messages+intl-icu.pt.xlf +++ b/translations/messages+intl-icu.pt.xlf @@ -5,10 +5,6 @@ - - File not found - File not found - Users Users @@ -149,58 +145,6 @@ now now - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago - Keyword, file, hash... Keyword, file, hash... @@ -225,10 +169,6 @@ Waiting for approve Waiting for approve - - Content visible for non sensitive users only - Content visible for non sensitive users only - Size Size @@ -453,10 +393,6 @@ Join translation Join translation - - Content - Content - Activity Activity @@ -665,6 +601,318 @@ have added star for user have added star for user + + Error + Error + + + Oops! + Oops! + + + Internal server error + Internal server error + + + Report + Report + + + Not found + Not found + + + Page not found! + Page not found! + + + BitTorrent protocol version 2 + BitTorrent protocol version 2 + + + BitTorrent protocol version 1 + BitTorrent protocol version 1 + + + year ago + year ago + + + month ago + month ago + + + day ago + day ago + + + hour ago + hour ago + + + minute ago + minute ago + + + second ago + second ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + years ago + years ago + + + months ago + months ago + + + days ago + days ago + + + hours ago + hours ago + + + minutes ago + minutes ago + + + seconds ago + seconds ago + + + Search results + Search results + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Upload any torrent - download with Yggdrasil]]> + + + Wanted + Wanted + + + Seeders wanted for torrent + Seeders wanted for torrent + + + Hide + Hide + + + have disabled torrent + have disabled torrent + + + have enabled torrent + have enabled torrent + + + disabled + disabled + + + Poster file out of size limit + Poster file out of size limit + + + Image file not supported + Image file not supported + + + Poster file required + Poster file required + + + Edit torrent poster + Edit torrent poster + + + Edit poster for torrent + Edit poster for torrent + + + Poster + Poster + + + Posters + Posters + + + have deleted poster edition + have deleted poster edition + + + have disapproved poster edition + have disapproved poster edition + + + have approved poster edition + have approved poster edition + + + have added poster edition + have added poster edition + + + Torrent posters + Torrent posters + + + Center + Center + + + Top + Top + + + Bottom + Bottom + + + Categories + Categories + + + At least one category required + At least one category required + + + Content category + Content category + + + This torrent have selected categories + This torrent have selected categories + + + Edit categories + Edit categories + + + Edit categories for torrent + Edit categories for torrent + + + Locale + Locale + + + Category + Category + + + Torrent categories + Torrent categories + + + have deleted categories edition + have deleted categories edition + + + have disapproved categories edition + have disapproved categories edition + + + have approved categories edition + have approved categories edition + + + have added categories edition + have added categories edition + + + movie + movie + + + series + series + + + tv + tv + + + animation + animation + + + music + music + + + game + game + + + audiobook + audiobook + + + podcast + podcast + + + book + book + + + archive + archive + + + picture + picture + + + software + software + + + other + other + + + Hide filter + Hide filter + + + Show filter + Show filter + + + Private + Private + diff --git a/translations/messages+intl-icu.ru.xlf b/translations/messages+intl-icu.ru.xlf index f742dc9..a452819 100644 --- a/translations/messages+intl-icu.ru.xlf +++ b/translations/messages+intl-icu.ru.xlf @@ -5,361 +5,301 @@ - - File not found - File not found - Users - Users + Пользователи Joined - Joined + Присоединился Approved - Approved + Утвержден Disapproved - Disapproved + Отклонен User statuses - User statuses + Статусы пользователей Enabled - Enabled + Включено Disabled - Disabled + Отключено User moderators - User moderators + Модерация пользователей Added - Added + Добавлено Removed - Removed + Удалено User stars - User stars + Звезды пользователей Torrents - Torrents + Торренты Torrent locales - Torrent locales + Локали торрента Deleted - Deleted + Удалено Torrent sensitive - Torrent sensitive + Чувствительное содержимое Torrent stars - Torrent stars + Звезды торрента Torrent downloads - Torrent downloads + Загрузки торрентов Files - Files + Файлы Magnet links - Magnet links + Magnet-ссылки Access denied - Access denied + Доступ запрещен At least one locale required - At least one locale required + Требуется хотя бы одна локаль Torrent file out of size limit - Torrent file out of size limit + Превышен размер торрент-файла Torrent file already exists - Torrent file already exists + Торрент-файл уже существует Could not parse torrent file - Could not parse torrent file + Не удалось проанализировать торрент-файл Torrent file required - Torrent file required + Требуется указать торрент-файл B - B + Б Kb - Kb + Кб Mb - Mb + Мб Gb - Gb + Гб Tb - Tb + Тб Pb - Pb + Пб Eb - Eb + Эб Zb - Zb + Зб Yb - Yb + Иб now - now - - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago + сейчас Keyword, file, hash... - Keyword, file, hash... + Ключевое слово, файл, хэш... Search - Search + Поиск Recent uploads - Recent uploads + Последние загрузки Active leechers waiting for seeders - Active leechers waiting for seeders + Активные пиры ожидают раздачи wanted - wanted + розыск Waiting for approve - Waiting for approve - - - Content visible for non sensitive users only - Content visible for non sensitive users only + На рассмотрении Size - Size + Размер Seeders - Seeders + Сиды Peers - Peers + Пиры Leechers - Leechers + Личеры Open magnet link - Open magnet link + Открыть magnet-ссылку Total - Total + Всего Download torrent file - Download torrent file + Скачать торрент-файл Star - Star + Звезда Nothing found - Nothing found + Ничего не найдено * share new torrent file to change it - * share new torrent file to change it + * поделитесь новым торрент-файлом, чтобы исправить это Submit - Submit + Отправить Submit torrent - Submit torrent + Отправить торрент Content language - Content language + Язык контента This torrent contains selected languages - This torrent contains selected languages + Этот торрент содержит выбранные языки Sensitive - Sensitive + Чувствительность Mark torrent content as sensitive - Mark torrent content as sensitive + Отметить содержимое торрента как чувствительное Edit locales - Edit locales + Изменить локали Torrent - Torrent + Торрент Edit locales for torrent - Edit locales for torrent + Изменить локали для торрента cancel - cancel + отменить by - by + от identicon - identicon + пиктограмма Delete - Delete + Удалить Disapprove - Disapprove + Отклонить Approve - Approve + Утвердить Edit sensitive status - Edit sensitive status + Изменить статус чувствительности Edit sensitive status for torrent - Edit sensitive status for torrent + Редактировать статус чувствительности для торрента Page - Page + Страница Moderation - Moderation + Модерация Yes - Yes + Да Toggle - Toggle + Переключить No - No + Нет Common - Common + Общее ID @@ -371,299 +311,607 @@ Info hash v1 - Info hash v1 + Инфо-хэш v1 Info hash v2 - Info hash v2 + Инфо-хэш v2 Created - Created + Создано Pieces - Pieces + Фрагменты Source - Source + Источник Software - Software + Программа Comment - Comment + Комментарий Contributors - Contributors + Участники Scrape - Scrape + Статус Trackers - Trackers + Трекеры Filtered by settings - Filtered by settings + Отфильтровано согласно настройкам Edit - Edit + Редактировать Locales - Locales + Локали Recent activity - Recent activity + Недавняя активность Back - Back + Назад Next - Next + Далее Settings - Settings + Настройки Interface - Interface + Интерфейс Theme - Theme + Тема Language - Language + Язык Join translation - Join translation - - - Content - Content + Присоединиться к переводам Activity - Activity + Активность Downloads - Downloads + Загрузки Yggdrasil only - Yggdrasil only + Только Yggdrasil Save - Save + Сохранить Home - Home + Главная Profile - Profile + Профиль User - User + Пользователь Bookmark - Bookmark + Закладка Address - Address + Адрес Address hidden for others - Address hidden for others + Адрес скрыт для других Access - Access + Доступ Status - Status + Статус Active - Active + Активный Moderator - Moderator + Модератор Languages - Languages + Языки Events subscribed - Events subscribed + Подписка на события undefined event - undefined event + неизвестное событие have downloaded torrent file - have downloaded torrent file + скачал торрент-файл waiting for approve - waiting for approve + на рассмотрении sensitive - sensitive + чувствительность have downloaded magnet link - have downloaded magnet link + скачал magnet-ссылку have disapproved torrent - have disapproved torrent + отменил утверждение торрента have approved torrent - have approved torrent + утвердил торрент have added torrent - have added torrent + добавил торрент have deleted locales edition - have deleted locales edition + удалил редакцию локалей for torrent - for torrent + для торрента have disapproved locales edition - have disapproved locales edition + отклонил редакцию локалей have approved locales edition - have approved locales edition + утвердил редакцию локалей have added locales edition - have added locales edition + добавил редакцию локалей have removed star from torrent - have removed star from torrent + удалил звезду с торрента have added star for torrent - have added star for torrent + добавил звезду для торрента have deleted sensitive edition - have deleted sensitive edition + удалил редакцию чувствительного контента have disapproved sensitive edition - have disapproved sensitive edition + отклонил редакцию чувствительного контента have approved sensitive edition - have approved sensitive edition + утвердил редакцию чувствительного контента have added sensitive edition - have added sensitive edition + добавил редакцию чувствительного контента have disabled - have disabled + отключил have disabled user - have disabled user + отключил пользователя have enabled - have enabled + включил have enabled user - have enabled user + включил пользователя have disapproved - have disapproved + отклонил have disapproved user - have disapproved user + отключил пользователя have approved - have approved + утвердил have approved user - have approved user + утвердил пользователя have joined - have joined + присоединился have removed moderator permissions from - have removed moderator permissions from + удалил права модератора от have removed moderator permissions from user - have removed moderator permissions from user + удалил права модератора от пользователя have granted moderator permissions to - have granted moderator permissions to + предоставил права модератора для have granted moderator permissions to user - have granted moderator permissions to user + предоставил права модератора для пользователя have removed star from - have removed star from + удалил звезду от have removed star from user - have removed star from user + удалили звезду от пользователя have added star for - have added star for + добавил звезду для have added star for user - have added star for user + добавил звезду для пользователя + + + Error + Ошибка + + + Oops! + Ой! + + + Internal server error + Внутренняя ошибка сервера + + + Report + Сообщить + + + Not found + Не найдено + + + Page not found! + Страница не найдена! + + + BitTorrent protocol version 2 + BitTorrent протокол версии 2 + + + BitTorrent protocol version 1 + BitTorrent протокол версии 1 + + + year ago + год назад + + + month ago + месяц назад + + + day ago + день назад + + + hour ago + час назад + + + minute ago + минуту назад + + + second ago + секунду назад + + + years ago + год назад + + + months ago + месяца назад + + + days ago + дня назад + + + hours ago + часа назад + + + minutes ago + минуты назад + + + seconds ago + секунды назад + + + years ago + лет назад + + + months ago + месяцев назад + + + days ago + дней назад + + + hours ago + часов назад + + + minutes ago + минут назад + + + seconds ago + секунд назад + + + Search results + Результаты поиска + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Загрузить любой торрент - скачать с Yggdrasil]]> + + + Wanted + Розыск + + + Seeders wanted for torrent + Требуется раздача для торрента + + + Hide + Скрыть + + + have disabled torrent + отключил торрент + + + have enabled torrent + включил торрент + + + disabled + отключено + + + Poster file out of size limit + Размер файла постера превышает максимальный размер + + + Image file not supported + Формат изображения не поддерживается + + + Poster file required + Требуется указать файл постера + + + Edit torrent poster + Редактировать постер торрента + + + Edit poster for torrent + Редактировать постер для торрента + + + Poster + Постер + + + Posters + Постеры + + + have deleted poster edition + удалил редакцию постера + + + have disapproved poster edition + отклонил редакцию постера + + + have approved poster edition + утвердил редакцию постера + + + have added poster edition + добавил редакцию постера + + + Torrent posters + Постеры торрентов + + + Center + Центр + + + Top + Верх + + + Bottom + Низ + + + Categories + Категории + + + At least one category required + Необходимо указать минимум одну категорию + + + Content category + Категория содержимого + + + This torrent have selected categories + Этот торрент содержит выбранные категории + + + Edit categories + Редактировать категории + + + Edit categories for torrent + Редактировать категории для торрента + + + Locale + Локаль + + + Category + Категория + + + Torrent categories + Категории торрента + + + have deleted categories edition + удалил редакцию категорий + + + have disapproved categories edition + отклонил редакцию категорий + + + have approved categories edition + утвердил редакцию категорий + + + have added categories edition + добавил редакцию категорий + + + movie + фильм + + + series + сериал + + + tv + ТВ шоу + + + animation + анимация + + + music + музыка + + + game + игра + + + audiobook + аудиокнига + + + podcast + подкаст + + + book + книга + + + archive + архив + + + picture + изображение + + + software + программа + + + other + другое + + + Hide filter + Скрыть фильтр + + + Show filter + Показать фильтр + + + Private + Приватный diff --git a/translations/messages+intl-icu.uk.xlf b/translations/messages+intl-icu.uk.xlf index 85a8e00..ffea2ef 100644 --- a/translations/messages+intl-icu.uk.xlf +++ b/translations/messages+intl-icu.uk.xlf @@ -5,361 +5,301 @@ - - File not found - File not found - Users - Users + Користувачі Joined - Joined + Приєднався Approved - Approved + Затверджено Disapproved - Disapproved + Відхилено User statuses - User statuses + Статуси користувача Enabled - Enabled + Увімкнено Disabled - Disabled + Вимкнено User moderators - User moderators + Модератори Added - Added + Додано Removed - Removed + Видалено User stars - User stars + Зірки користувача Torrents - Torrents + Торенти Torrent locales - Torrent locales + Файли торентів Deleted - Deleted + Видалено Torrent sensitive - Torrent sensitive + Чутливий вміст Torrent stars - Torrent stars + Зірки торенту Torrent downloads - Torrent downloads + Завантаження торенту Files - Files + Файли Magnet links - Magnet links + Magnet-посилання Access denied - Access denied + Відмовлено у доступі At least one locale required - At least one locale required + Необхідна принаймні одна локаль Torrent file out of size limit - Torrent file out of size limit + Торент-файл поза розміром Torrent file already exists - Torrent file already exists + Торент-файл вже існує Could not parse torrent file - Could not parse torrent file + Не вдалося проаналізувати торент-файл Torrent file required - Torrent file required + Необхідно надати торент файл B - B + Б Kb - Kb + Кб Mb - Mb + Мб Gb - Gb + Гб Tb - Tb + Тб Pb - Pb + Пб Eb - Eb + Еб Zb - Zb + Зб Yb - Yb + Іб now - now - - - year - year - - - month - month - - - day - day - - - hour - hour - - - minute - minute - - - second - second - - - years - years - - - months - months - - - days - days - - - hours - hours - - - minutes - minutes - - - seconds - seconds - - - ago - ago + щойно Keyword, file, hash... - Keyword, file, hash... + Ключове слово, файл, хеш... Search - Search + Пошук Recent uploads - Recent uploads + Останні завантаження Active leechers waiting for seeders - Active leechers waiting for seeders + Активні лічери очікують сідів wanted - wanted + розшук Waiting for approve - Waiting for approve - - - Content visible for non sensitive users only - Content visible for non sensitive users only + Очікує на підтвердження Size - Size + Розмір Seeders - Seeders + Сідери Peers - Peers + Піри Leechers - Leechers + Лічери Open magnet link - Open magnet link + Відкрити посилання на magnet Total - Total + Всього Download torrent file - Download torrent file + Завантажити торрент файл Star - Star + Зірка Nothing found - Nothing found + Нічого не знайдено * share new torrent file to change it - * share new torrent file to change it + * поширте новий торент-файл, щоб змінити це Submit - Submit + Надіслати Submit torrent - Submit torrent + Надіслати торент Content language - Content language + Мова контенту This torrent contains selected languages - This torrent contains selected languages + Цей торрент містить обрані мови Sensitive - Sensitive + Чутливий вміст Mark torrent content as sensitive - Mark torrent content as sensitive + Помітити вміст торенту як чутливий Edit locales - Edit locales + Редагувати локалі Torrent - Torrent + Торент Edit locales for torrent - Edit locales for torrent + Редагування локалей для торенту cancel - cancel + скасувати by - by + за участі identicon - identicon + піктограма Delete - Delete + Видалити Disapprove - Disapprove + Відхилити Approve - Approve + Затвердити Edit sensitive status - Edit sensitive status + Редагувати статус чутливості Edit sensitive status for torrent - Edit sensitive status for torrent + Редагувати статус чутливості для торенту Page - Page + Сторінка Moderation - Moderation + Модерація Yes - Yes + Так Toggle - Toggle + Перемкнути No - No + Ні Common - Common + Загальні ID @@ -371,299 +311,607 @@ Info hash v1 - Info hash v1 + Інфо-хеш версії 1 Info hash v2 - Info hash v2 + Інфо-хеш версії 2 Created - Created + Створено Pieces - Pieces + Частини Source - Source + Джерело Software - Software + Програма Comment - Comment + Коментар Contributors - Contributors + Учасники Scrape - Scrape + Стан Trackers - Trackers + Трекери Filtered by settings - Filtered by settings + Відфільтровано згідно з налаштуваннями Edit - Edit + Редагувати Locales - Locales + Локалі Recent activity - Recent activity + Остання активність Back - Back + Назад Next - Next + Далі Settings - Settings + Налаштування Interface - Interface + Інтерфейс Theme - Theme + Тема Language - Language + Мова Join translation - Join translation - - - Content - Content + Приєднатись до перекладу Activity - Activity + Активність Downloads - Downloads + Завантаження Yggdrasil only - Yggdrasil only + Тільки Іґдрасіль Save - Save + Зберегти Home - Home + Головна Profile - Profile + Профіль User - User + Користувач Bookmark - Bookmark + Додати до обраного Address - Address + Адреса Address hidden for others - Address hidden for others + Адресу приховано для інших Access - Access + Доступ Status - Status + Статус Active - Active + Активний Moderator - Moderator + Модератор Languages - Languages + Мови Events subscribed - Events subscribed + Підписка на події undefined event - undefined event + невідома подія have downloaded torrent file - have downloaded torrent file + завантажив торрент файл waiting for approve - waiting for approve + очікує на підтвердження sensitive - sensitive + чутливий вміст have downloaded magnet link - have downloaded magnet link + завантажив торрент файл have disapproved torrent - have disapproved torrent + відхилив торент have approved torrent - have approved torrent + затвердив торент have added torrent - have added torrent + додав торент have deleted locales edition - have deleted locales edition + видалено версію локалей for torrent - for torrent + для торенту have disapproved locales edition - have disapproved locales edition + відхилив версію локалей have approved locales edition - have approved locales edition + затвердив версію локалей have added locales edition - have added locales edition + додав редакцію локалей have removed star from torrent - have removed star from torrent + видалив зірку з торента have added star for torrent - have added star for torrent + додав зірку для торента have deleted sensitive edition - have deleted sensitive edition + видалив редакцію чутливого вмісту have disapproved sensitive edition - have disapproved sensitive edition + відхилив редакцію чутливого вмісту have approved sensitive edition - have approved sensitive edition + затвердив редакцію чутливого вмісту have added sensitive edition - have added sensitive edition + додав редакцію чутливого вмісту have disabled - have disabled + вимкнув have disabled user - have disabled user + вимкнув користувача have enabled - have enabled + увімкнув have enabled user - have enabled user + увімкнув користувача have disapproved - have disapproved + відхилив have disapproved user - have disapproved user + відхилив користувача have approved - have approved + затвердив have approved user - have approved user + затвердив користувача have joined - have joined + приєднався have removed moderator permissions from - have removed moderator permissions from + видалив права модератора від have removed moderator permissions from user - have removed moderator permissions from user + видалив права модератора від користувача have granted moderator permissions to - have granted moderator permissions to + надано права модератора have granted moderator permissions to user - have granted moderator permissions to user + надано права модератора користувачеві have removed star from - have removed star from + видалив зірку від have removed star from user - have removed star from user + видалив зірку від користувача have added star for - have added star for + додав зірку до have added star for user - have added star for user + додав зірку користувачеві + + + Error + Помилка + + + Oops! + Ой! + + + Internal server error + Внутрішня помилка сервера + + + Report + Звіт + + + Not found + Не знайдено + + + Page not found! + Сторінку не знайдено! + + + BitTorrent protocol version 2 + BitTorrent протокол версії 2 + + + BitTorrent protocol version 1 + BitTorrent протокол версії 1 + + + year ago + рік тому + + + month ago + місяць тому + + + day ago + день тому + + + hour ago + годину тому + + + minute ago + хвилину тому + + + second ago + секунду тому + + + years ago + роки тому + + + months ago + місяці тому + + + days ago + дні тому + + + hours ago + години тому + + + minutes ago + хвилини тому + + + seconds ago + секунди тому + + + years ago + років тому + + + months ago + місяців тому + + + days ago + днів тому + + + hours ago + годин тому + + + minutes ago + хвилин тому + + + seconds ago + секунд тому + + + Search results + Результати пошуку + + + <a href="%s">Upload</a> any torrent - download with Yggdrasil + Надіслати будь-який торент - завантажити з Yggdrasil]]> + + + Wanted + Розшук + + + Seeders wanted for torrent + Розшукуються роздачі для торенту + + + Hide + Приховати + + + have disabled torrent + вимкнув торент + + + have enabled torrent + увімкнув торент + + + disabled + вимкнено + + + Poster file out of size limit + Розмір файлу постера перевищує ліміти + + + Image file not supported + Формат зображення не підтримується + + + Poster file required + Необхідно вказати файл постера + + + Edit torrent poster + Редагувати постер торента + + + Edit poster for torrent + Редагувати постер для торента + + + Poster + Постер + + + Posters + Постери + + + have deleted poster edition + видалив редакцію постера + + + have disapproved poster edition + відхилив редакцію постера + + + have approved poster edition + додав редакцію постера + + + have added poster edition + додав редакцію постера + + + Torrent posters + Постери торентів + + + Center + Центр + + + Top + Верх + + + Bottom + Низ + + + Categories + Категорії + + + At least one category required + Потрібно вказати щонайменше одну категорію + + + Content category + Категорія вмісту + + + This torrent have selected categories + Цей торрент має виділені категорії + + + Edit categories + Змінити категорії + + + Edit categories for torrent + Редагувати категорії для торенту + + + Locale + Локаль + + + Category + Категорія + + + Torrent categories + Категорії торенту + + + have deleted categories edition + видалив редакцію категорій + + + have disapproved categories edition + відхилив редакцію категорій + + + have approved categories edition + затвердив редакцію категорій + + + have added categories edition + додав редакцію категорій + + + movie + кіно + + + series + серіал + + + tv + ТБ шоу + + + animation + анімація + + + music + музика + + + game + гра + + + audiobook + аудіокнига + + + podcast + подкаст + + + book + книга + + + archive + архів + + + picture + зображення + + + software + програма + + + other + інше + + + Hide filter + Приховати фільтр + + + Show filter + Показати фільтр + + + Private + Приватний
{{ 'Common'|trans }}
{{ 'Address' | trans }} @@ -68,7 +68,7 @@ {% if user.status %} {{ 'Active' | trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -77,7 +77,7 @@ {% endif %} {% else %} {{ 'Disabled' | trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -94,7 +94,7 @@ {% if user.approved %} {{ 'Yes'| trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -103,7 +103,7 @@ {% endif %} {% else %} {{ 'No'| trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -120,7 +120,7 @@ {% if user.moderator %} {{ 'Yes'| trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -129,7 +129,7 @@ {% endif %} {% else %} {{ 'No'| trans }} - {% if user.moderator %} + {% if session.moderator %} @@ -172,7 +172,29 @@ {{ 'Languages' | trans }} - {% for i, locale in user.locales %}{% if i > 0 %},{% endif %} {{ locale|locale_name(locale)|u.title }}{% endfor %} + {% set i = 0 %} + {% for locale in user.locales | sort %}{% if i > 0 %},{% endif %} {{ locale | locale_name(locale) | u.title }}{% set i = i + 1 %}{% endfor %} + +
+ {{ 'Categories' | trans }} + + {% set i = 0 %} + {% for category in user.categories | sort %}{% if i > 0 %},{% endif %} {{ category | trans_category | u.title }}{% set i = i + 1 %}{% endfor %} +
+ {{ 'Posters' | trans }} + + {% if user.posters %} + {{ 'Yes' | trans }} + {% else %} + {{ 'No' | trans }} + {% endif %}
+ {{ 'Posters' | trans }} + +
+ {% if user.posters %} + + {% else %} + + {% endif %} + +
+
{{ 'Search' | trans }} @@ -65,34 +82,60 @@
- {{ 'Content' | trans }} +
+ {{ 'Locales' | trans }} +
- {% for locale in locales %} -
+
+ {% for locale in locales | sort %} +
{% if locale in user.locales %} {% else %} {% endif %} -
{% endfor %}
+ +
+ {{ 'Categories' | trans }} +
+
+ {% for category in categories | sort %} +
+ {% if category in user.categories %} + + {% else %} + + {% endif %} + +
+ {% endfor %} +
{{ 'Sensitive' | trans }} -
+
+
{% if user.sensitive %} - + {% else %} - + {% endif %} +
+ {{ group }} + {% for key, value in event %} - + {% if value in user.events %} {% else %} {% endif %} - @@ -136,10 +181,13 @@ {% if user.yggdrasil %} - + {% else %} - + {% endif %} +