mirror of
https://github.com/wallabag/wallabag.git
synced 2026-03-16 22:47:37 +01:00
Compare commits
3 Commits
feat/sort
...
add-import
| Author | SHA1 | Date | |
|---|---|---|---|
| b4f1776828 | |||
| 5629330cb6 | |||
| 7e7674a4a6 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@ -1,2 +0,0 @@
|
||||
# Migrated rules from dependabot.yml
|
||||
composer.* @Kdecherf @j0k3r @yguedidi
|
||||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@ -35,6 +35,10 @@ updates:
|
||||
phpstan-dependencies:
|
||||
patterns:
|
||||
- "phpstan/*"
|
||||
reviewers:
|
||||
- j0k3r
|
||||
- yguedidi
|
||||
- Kdecherf
|
||||
ignore:
|
||||
- dependency-name: symfony/*
|
||||
update-types: [ "version-update:semver-major" ]
|
||||
|
||||
2
.github/workflows/coding-standards.yml
vendored
2
.github/workflows/coding-standards.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
|
||||
6
.github/workflows/continuous-integration.yml
vendored
6
.github/workflows/continuous-integration.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@ -116,7 +116,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@ -187,7 +187,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
|
||||
2
.github/workflows/translations.yml
vendored
2
.github/workflows/translations.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
|
||||
2
.github/workflows/upload-release-package.yml
vendored
2
.github/workflows/upload-release-package.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@ -5,22 +5,6 @@
|
||||
* **[BC BREAK]** Convert 403 errors to 404 errors by @yguedidi in https://github.com/wallabag/wallabag/pull/8075
|
||||
* `wallassets/` folder renamed to `build/`
|
||||
|
||||
## [2.6.13](https://github.com/wallabag/wallabag/tree/2.6.13)
|
||||
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.12...2.6.13)
|
||||
|
||||
### Improvements
|
||||
|
||||
* Add support of Pocket CSV import by @kdecherf and @nicosomb in [https://github.com/wallabag/wallabag/pull/8240](https://github.com/wallabag/wallabag/pull/8240)
|
||||
* Backport Pocket and Shaarli HTML imports from master by @nicosomb in [https://github.com/wallabag/wallabag/pull/8193](https://github.com/wallabag/wallabag/pull/8193)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Avoid non-validated OTP to be enabled #8139 by @j0k3r in [https://github.com/wallabag/wallabag/pull/8139](https://github.com/wallabag/wallabag/pull/8139)
|
||||
|
||||
### Technical stuff
|
||||
|
||||
* Update j0k3r/php-readability:1.2.13 to fix regression (about latin1 instead of UTF-8 used for entries) by @nicosomb [https://github.com/wallabag/wallabag/pull/8194](https://github.com/wallabag/wallabag/pull/8194)
|
||||
|
||||
## [2.6.12](https://github.com/wallabag/wallabag/tree/2.6.12)
|
||||
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.11...2.6.12)
|
||||
|
||||
@ -29,6 +13,7 @@
|
||||
* Fix changelog by @yguedidi in [https://github.com/wallabag/wallabag/pull/8135](https://github.com/wallabag/wallabag/pull/8135)
|
||||
* Update dependencies by @yguedidi in [https://github.com/wallabag/wallabag/pull/8136](https://github.com/wallabag/wallabag/pull/8136)
|
||||
|
||||
|
||||
## [2.6.11](https://github.com/wallabag/wallabag/tree/2.6.11)
|
||||
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.10...2.6.11)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# wallabag
|
||||
|
||||
[](https://github.com/wallabag/wallabag/actions/workflows/continuous-integration.yml?query=branch%3Amaster)
|
||||

|
||||
[](https://matrix.to/#/#wallabag:matrix.org)
|
||||
[](https://liberapay.com/wallabag/donate)
|
||||
[](https://hosted.weblate.org/engage/wallabag/?utm_source=widget)
|
||||
|
||||
@ -305,11 +305,6 @@ old_sound_rabbit_mq:
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_html'
|
||||
type: topic
|
||||
import_pocket_csv:
|
||||
connection: default
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
type: topic
|
||||
consumers:
|
||||
import_pocket:
|
||||
connection: default
|
||||
@ -428,15 +423,6 @@ old_sound_rabbit_mq:
|
||||
name: 'wallabag.import.pocket_html'
|
||||
callback: wallabag.consumer.amqp.pocket_html
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_pocket_csv:
|
||||
connection: default
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
type: topic
|
||||
queue_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
callback: wallabag.consumer.amqp.pocket_csv
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
|
||||
fos_js_routing:
|
||||
routes_to_expose:
|
||||
|
||||
@ -108,11 +108,6 @@ services:
|
||||
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pocket_html_producer'
|
||||
$redisProducer: '@wallabag.producer.redis.pocket_html'
|
||||
|
||||
Wallabag\Controller\Import\PocketCsvController:
|
||||
arguments:
|
||||
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pocket_csv_producer'
|
||||
$redisProducer: '@wallabag.producer.redis.pocket_csv'
|
||||
|
||||
Wallabag\Doctrine\MigrationFactoryDecorator:
|
||||
decorates: doctrine.migrations.migrations_factory
|
||||
|
||||
@ -281,62 +276,83 @@ services:
|
||||
|
||||
Wallabag\Import\PocketImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''pocket_enabled'')' ] ]
|
||||
- [ setClient, [ '@Symfony\Contracts\HttpClient\HttpClientInterface $pocketClient' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pocket }
|
||||
|
||||
Wallabag\Import\WallabagV1Import:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''wallabag_v1_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: wallabag_v1 }
|
||||
|
||||
Wallabag\Import\WallabagV2Import:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''wallabag_v2_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: wallabag_v2 }
|
||||
|
||||
Wallabag\Import\ElcuratorImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''elcurator_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: elcurator }
|
||||
|
||||
Wallabag\Import\ReadabilityImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''readability_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: readability }
|
||||
|
||||
Wallabag\Import\InstapaperImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''instapaper_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: instapaper }
|
||||
|
||||
Wallabag\Import\PinboardImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''pinboard_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pinboard }
|
||||
|
||||
Wallabag\Import\DeliciousImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''delicious_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: delicious }
|
||||
|
||||
Wallabag\Import\OmnivoreImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''omnivore_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: omnivore }
|
||||
|
||||
Wallabag\Import\FirefoxImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''firefox_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: firefox }
|
||||
|
||||
Wallabag\Import\ChromeImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''chrome_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: chrome }
|
||||
|
||||
Wallabag\Import\ShaarliImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''shaarli_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: shaarli }
|
||||
|
||||
Wallabag\Import\PocketHtmlImport:
|
||||
calls:
|
||||
- [ setEnabled, [ '@=service(''craue_config'').get(''pocket_html_enabled'')' ] ]
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pocket_html }
|
||||
|
||||
Wallabag\Import\PocketCsvImport:
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pocket_csv }
|
||||
|
||||
# to factorize the proximity and bypass translation for prev & next
|
||||
pagerfanta.view.default_wallabag:
|
||||
class: Pagerfanta\View\OptionableView
|
||||
|
||||
@ -20,7 +20,6 @@ services:
|
||||
$elcuratorConsumer: '@old_sound_rabbit_mq.import_elcurator_consumer'
|
||||
$shaarliConsumer: '@old_sound_rabbit_mq.import_shaarli_consumer'
|
||||
$pocketHtmlConsumer: '@old_sound_rabbit_mq.import_pocket_html_consumer'
|
||||
$pocketCsvConsumer: '@old_sound_rabbit_mq.import_pocket_csv_consumer'
|
||||
$omnivoreConsumer: '@old_sound_rabbit_mq.import_omnivore_consumer'
|
||||
|
||||
wallabag.consumer.amqp.pocket:
|
||||
@ -87,8 +86,3 @@ services:
|
||||
class: Wallabag\Consumer\AMQPEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketHtmlImport'
|
||||
|
||||
wallabag.consumer.amqp.pocket_csv:
|
||||
class: Wallabag\Consumer\AMQPEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketCsvImport'
|
||||
|
||||
@ -212,19 +212,3 @@ services:
|
||||
class: Wallabag\Consumer\RedisEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketHtmlImport'
|
||||
|
||||
# pocket csv
|
||||
wallabag.queue.redis.pocket_csv:
|
||||
class: Simpleue\Queue\RedisQueue
|
||||
arguments:
|
||||
$queueName: "wallabag.import.pocket_csv"
|
||||
|
||||
wallabag.producer.redis.pocket_csv:
|
||||
class: Wallabag\Redis\Producer
|
||||
arguments:
|
||||
- "@wallabag.queue.redis.pocket_csv"
|
||||
|
||||
wallabag.consumer.redis.pocket_csv:
|
||||
class: Wallabag\Consumer\RedisEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketCsvImport'
|
||||
|
||||
@ -126,6 +126,58 @@ parameters:
|
||||
name: import_with_rabbitmq
|
||||
value: 0
|
||||
section: import
|
||||
-
|
||||
name: pocket_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: wallabag_v1_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: wallabag_v2_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: elcurator_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: readability_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: instapaper_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: pinboard_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: delicious_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: omnivore_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: firefox_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: chrome_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: shaarli_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: pocket_html_enabled
|
||||
value: 1
|
||||
section: import
|
||||
-
|
||||
name: matomo_enabled
|
||||
value: 0
|
||||
|
||||
@ -23,7 +23,6 @@ $config
|
||||
'friendsoftwig/twigcs',
|
||||
'incenteev/composer-parameter-handler',
|
||||
'j0k3r/graby-site-config',
|
||||
'j0k3r/php-readability',
|
||||
'laminas/laminas-code',
|
||||
'lcobucci/jwt',
|
||||
'mgargano/simplehtmldom',
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
"doctrine/orm": "^2.20.2",
|
||||
"doctrine/persistence": "^3.4",
|
||||
"egulias/email-validator": "^4.0.4",
|
||||
"enshrined/svg-sanitize": "^0.22",
|
||||
"enshrined/svg-sanitize": "^0.21",
|
||||
"friendsofsymfony/jsrouting-bundle": "^3.5",
|
||||
"friendsofsymfony/oauth-server-bundle": "dev-master#dc8ff343363cf794d30eb1a123610d186a43f162",
|
||||
"friendsofsymfony/rest-bundle": "^3.8",
|
||||
@ -80,7 +80,6 @@
|
||||
"incenteev/composer-parameter-handler": "^2.2",
|
||||
"j0k3r/graby": "^2.4.6",
|
||||
"j0k3r/graby-site-config": "^1.0.197",
|
||||
"j0k3r/php-readability": "^1.2.13",
|
||||
"javibravo/simpleue": "^2.1",
|
||||
"jms/serializer": "^3.32.3",
|
||||
"jms/serializer-bundle": "^5.5.1",
|
||||
|
||||
274
composer.lock
generated
274
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "58a7696a7e938ab8a69c7faf2444cd09",
|
||||
"content-hash": "00b8f95df6ec0572c06ad6f34847405c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "babdev/pagerfanta-bundle",
|
||||
@ -776,16 +776,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.9.5",
|
||||
"version": "3.9.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868"
|
||||
"reference": "ec16c82f20be1a7224e65ac67144a29199f87959"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"reference": "4a4e2eed3134036ee36a147ee0dac037dfa17868",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/ec16c82f20be1a7224e65ac67144a29199f87959",
|
||||
"reference": "ec16c82f20be1a7224e65ac67144a29199f87959",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -798,14 +798,14 @@
|
||||
"psr/log": "^1|^2|^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "13.0.0",
|
||||
"doctrine/coding-standard": "12.0.0",
|
||||
"fig/log-test": "^1",
|
||||
"jetbrains/phpstorm-stubs": "2023.1",
|
||||
"phpstan/phpstan": "2.1.17",
|
||||
"phpstan/phpstan": "2.1.1",
|
||||
"phpstan/phpstan-strict-rules": "^2",
|
||||
"phpunit/phpunit": "9.6.23",
|
||||
"slevomat/coding-standard": "8.16.2",
|
||||
"squizlabs/php_codesniffer": "3.13.1",
|
||||
"phpunit/phpunit": "9.6.22",
|
||||
"slevomat/coding-standard": "8.13.1",
|
||||
"squizlabs/php_codesniffer": "3.10.2",
|
||||
"symfony/cache": "^5.4|^6.0|^7.0",
|
||||
"symfony/console": "^4.4|^5.4|^6.0|^7.0"
|
||||
},
|
||||
@ -867,7 +867,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.9.5"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.9.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -883,7 +883,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-15T22:40:05+00:00"
|
||||
"time": "2025-01-16T08:28:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
@ -1470,16 +1470,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/migrations",
|
||||
"version": "3.9.1",
|
||||
"version": "3.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/migrations.git",
|
||||
"reference": "0f1e0c960ac29866d648a4f50142a74fe1cb6999"
|
||||
"reference": "325b61e41d032f5f7d7e2d11cbefff656eadc9ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/migrations/zipball/0f1e0c960ac29866d648a4f50142a74fe1cb6999",
|
||||
"reference": "0f1e0c960ac29866d648a4f50142a74fe1cb6999",
|
||||
"url": "https://api.github.com/repos/doctrine/migrations/zipball/325b61e41d032f5f7d7e2d11cbefff656eadc9ab",
|
||||
"reference": "325b61e41d032f5f7d7e2d11cbefff656eadc9ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1553,7 +1553,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/migrations/issues",
|
||||
"source": "https://github.com/doctrine/migrations/tree/3.9.1"
|
||||
"source": "https://github.com/doctrine/migrations/tree/3.9.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1569,7 +1569,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T07:19:23+00:00"
|
||||
"time": "2025-03-26T06:48:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
@ -1893,16 +1893,16 @@
|
||||
},
|
||||
{
|
||||
"name": "enshrined/svg-sanitize",
|
||||
"version": "0.22.0",
|
||||
"version": "0.21.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/darylldoyle/svg-sanitizer.git",
|
||||
"reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500"
|
||||
"reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/0afa95ea74be155a7bcd6c6fb60c276c39984500",
|
||||
"reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500",
|
||||
"url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
|
||||
"reference": "5e477468fac5c5ce933dce53af3e8e4e58dcccc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1932,9 +1932,9 @@
|
||||
"description": "An SVG sanitizer for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
|
||||
"source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.22.0"
|
||||
"source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.21.0"
|
||||
},
|
||||
"time": "2025-08-12T10:13:48+00:00"
|
||||
"time": "2025-01-13T09:32:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fossar/htmlawed",
|
||||
@ -4146,16 +4146,16 @@
|
||||
},
|
||||
{
|
||||
"name": "j0k3r/graby-site-config",
|
||||
"version": "1.0.202",
|
||||
"version": "1.0.199",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/j0k3r/graby-site-config.git",
|
||||
"reference": "870ff8f1f35cdbf87ff000b68c7bef5e712fd533"
|
||||
"reference": "dbb352fd7931f813e286eed8f1684da6052737e3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/870ff8f1f35cdbf87ff000b68c7bef5e712fd533",
|
||||
"reference": "870ff8f1f35cdbf87ff000b68c7bef5e712fd533",
|
||||
"url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/dbb352fd7931f813e286eed8f1684da6052737e3",
|
||||
"reference": "dbb352fd7931f813e286eed8f1684da6052737e3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4184,9 +4184,9 @@
|
||||
"description": "Graby site config files",
|
||||
"support": {
|
||||
"issues": "https://github.com/j0k3r/graby-site-config/issues",
|
||||
"source": "https://github.com/j0k3r/graby-site-config/tree/1.0.202"
|
||||
"source": "https://github.com/j0k3r/graby-site-config/tree/1.0.199"
|
||||
},
|
||||
"time": "2025-08-01T07:03:24+00:00"
|
||||
"time": "2025-05-01T02:32:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "j0k3r/httplug-ssrf-plugin",
|
||||
@ -4261,16 +4261,16 @@
|
||||
},
|
||||
{
|
||||
"name": "j0k3r/php-readability",
|
||||
"version": "1.2.13",
|
||||
"version": "1.2.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/j0k3r/php-readability.git",
|
||||
"reference": "b9dde0f4cd46e9fc082bb37f75dc94ecd2f8faad"
|
||||
"reference": "109a22662de0d703f01387e5714ad4f9a03b95c0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/j0k3r/php-readability/zipball/b9dde0f4cd46e9fc082bb37f75dc94ecd2f8faad",
|
||||
"reference": "b9dde0f4cd46e9fc082bb37f75dc94ecd2f8faad",
|
||||
"url": "https://api.github.com/repos/j0k3r/php-readability/zipball/109a22662de0d703f01387e5714ad4f9a03b95c0",
|
||||
"reference": "109a22662de0d703f01387e5714ad4f9a03b95c0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4332,7 +4332,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/j0k3r/php-readability/issues",
|
||||
"source": "https://github.com/j0k3r/php-readability/tree/1.2.13"
|
||||
"source": "https://github.com/j0k3r/php-readability/tree/1.2.12"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4340,7 +4340,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-03T08:02:58+00:00"
|
||||
"time": "2025-03-04T09:20:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "javibravo/simpleue",
|
||||
@ -4405,16 +4405,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Jean85/pretty-package-versions.git",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4424,9 +4424,8 @@
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"jean85/composer-provided-replaced-stub-package": "^1.0",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.6",
|
||||
"rector/rector": "^2.0",
|
||||
"vimeo/psalm": "^4.3 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
@ -4459,9 +4458,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Jean85/pretty-package-versions/issues",
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0"
|
||||
},
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
"time": "2024-11-18T16:19:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jms/metadata",
|
||||
@ -4529,16 +4528,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jms/serializer",
|
||||
"version": "3.32.5",
|
||||
"version": "3.32.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/serializer.git",
|
||||
"reference": "7c88b1b02ff868eecc870eeddbb3b1250e4bd89c"
|
||||
"reference": "f5c6227b2664d1e75fda65f1e6c5686a0c034b31"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/schmittjoh/serializer/zipball/7c88b1b02ff868eecc870eeddbb3b1250e4bd89c",
|
||||
"reference": "7c88b1b02ff868eecc870eeddbb3b1250e4bd89c",
|
||||
"url": "https://api.github.com/repos/schmittjoh/serializer/zipball/f5c6227b2664d1e75fda65f1e6c5686a0c034b31",
|
||||
"reference": "f5c6227b2664d1e75fda65f1e6c5686a0c034b31",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4615,7 +4614,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/schmittjoh/serializer/issues",
|
||||
"source": "https://github.com/schmittjoh/serializer/tree/3.32.5"
|
||||
"source": "https://github.com/schmittjoh/serializer/tree/3.32.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4627,7 +4626,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-26T15:55:41+00:00"
|
||||
"time": "2025-04-06T18:42:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jms/serializer-bundle",
|
||||
@ -8050,16 +8049,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "4.14.1",
|
||||
"version": "4.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getsentry/sentry-php.git",
|
||||
"reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda"
|
||||
"reference": "2af937d47d8aadb8dab0b1d7b9557e495dd12856"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/a28c4a6f5fda2bf730789a638501d7a737a64eda",
|
||||
"reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/2af937d47d8aadb8dab0b1d7b9557e495dd12856",
|
||||
"reference": "2af937d47d8aadb8dab0b1d7b9557e495dd12856",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -8123,7 +8122,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/getsentry/sentry-php/issues",
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/4.14.1"
|
||||
"source": "https://github.com/getsentry/sentry-php/tree/4.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -8135,27 +8134,27 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-23T15:25:52+00:00"
|
||||
"time": "2024-11-06T07:44:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry-symfony",
|
||||
"version": "5.3.0",
|
||||
"version": "5.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getsentry/sentry-symfony.git",
|
||||
"reference": "5081e7d842424ec09a96e3c79c5b48b89d1195b2"
|
||||
"reference": "394576244d8ac03fd2f305b82d23a6fd7a083b45"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-symfony/zipball/5081e7d842424ec09a96e3c79c5b48b89d1195b2",
|
||||
"reference": "5081e7d842424ec09a96e3c79c5b48b89d1195b2",
|
||||
"url": "https://api.github.com/repos/getsentry/sentry-symfony/zipball/394576244d8ac03fd2f305b82d23a6fd7a083b45",
|
||||
"reference": "394576244d8ac03fd2f305b82d23a6fd7a083b45",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/psr7": "^2.1.1",
|
||||
"jean85/pretty-package-versions": "^1.5||^2.0",
|
||||
"php": "^7.2||^8.0",
|
||||
"sentry/sentry": "^4.14.1",
|
||||
"sentry/sentry": "^4.10.0",
|
||||
"symfony/cache-contracts": "^1.1||^2.4||^3.0",
|
||||
"symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0",
|
||||
"symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0",
|
||||
@ -8225,7 +8224,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/getsentry/sentry-symfony/issues",
|
||||
"source": "https://github.com/getsentry/sentry-symfony/tree/5.3.0"
|
||||
"source": "https://github.com/getsentry/sentry-symfony/tree/5.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -8237,7 +8236,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-07T14:14:08+00:00"
|
||||
"time": "2025-03-03T07:47:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "simplepie/simplepie",
|
||||
@ -8816,16 +8815,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/cache-contracts",
|
||||
"version": "v3.6.0",
|
||||
"version": "v3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/cache-contracts.git",
|
||||
"reference": "5d68a57d66910405e5c0b63d6f0af941e66fc868"
|
||||
"reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/cache-contracts/zipball/5d68a57d66910405e5c0b63d6f0af941e66fc868",
|
||||
"reference": "5d68a57d66910405e5c0b63d6f0af941e66fc868",
|
||||
"url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b",
|
||||
"reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -8839,7 +8838,7 @@
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.6-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -8872,7 +8871,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/cache-contracts/tree/v3.6.0"
|
||||
"source": "https://github.com/symfony/cache-contracts/tree/v3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -8888,7 +8887,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-13T15:25:07+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
@ -9159,16 +9158,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.6.0",
|
||||
"version": "v3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
|
||||
"reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -9181,7 +9180,7 @@
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.6-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -9206,7 +9205,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.6.0"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -9222,7 +9221,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-25T14:21:43+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/doctrine-bridge",
|
||||
@ -12654,7 +12653,7 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
@ -12696,7 +12695,7 @@
|
||||
"description": "Provides a way to profile code",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/stopwatch/tree/v7.2.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -13456,21 +13455,20 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-exporter",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-exporter.git",
|
||||
"reference": "c9a1168891b5aaadfd6332ef44393330b3498c4c"
|
||||
"reference": "422b8de94c738830a1e071f59ad14d67417d7007"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/c9a1168891b5aaadfd6332ef44393330b3498c4c",
|
||||
"reference": "c9a1168891b5aaadfd6332ef44393330b3498c4c",
|
||||
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/422b8de94c738830a1e071f59ad14d67417d7007",
|
||||
"reference": "422b8de94c738830a1e071f59ad14d67417d7007",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3"
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/property-access": "^6.4|^7.0",
|
||||
@ -13513,7 +13511,7 @@
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/var-exporter/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -13529,7 +13527,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-15T09:04:05+00:00"
|
||||
"time": "2025-05-02T08:36:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/webpack-encore-bundle",
|
||||
@ -13678,16 +13676,16 @@
|
||||
},
|
||||
{
|
||||
"name": "tecnickcom/tcpdf",
|
||||
"version": "6.10.0",
|
||||
"version": "6.9.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tecnickcom/TCPDF.git",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d"
|
||||
"reference": "c838d7f7babb0d35763acfb9ecf78c3f45966f83"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"reference": "ca5b6de294512145db96bcbc94e61696599c391d",
|
||||
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/c838d7f7babb0d35763acfb9ecf78c3f45966f83",
|
||||
"reference": "c838d7f7babb0d35763acfb9ecf78c3f45966f83",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -13737,7 +13735,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/tecnickcom/TCPDF/issues",
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0"
|
||||
"source": "https://github.com/tecnickcom/TCPDF/tree/6.9.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -13745,7 +13743,7 @@
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-27T18:02:28+00:00"
|
||||
"time": "2025-05-13T11:34:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
@ -15121,16 +15119,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/data-fixtures",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/data-fixtures.git",
|
||||
"reference": "f65b353922b7ac48f360428e19b22fcce5aba134"
|
||||
"reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/f65b353922b7ac48f360428e19b22fcce5aba134",
|
||||
"reference": "f65b353922b7ac48f360428e19b22fcce5aba134",
|
||||
"url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/f7f1e12d6bceb58c204b3e77210a103c1c57601e",
|
||||
"reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -15144,14 +15142,14 @@
|
||||
"doctrine/phpcr-odm": "<1.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^13",
|
||||
"doctrine/coding-standard": "^12",
|
||||
"doctrine/dbal": "^3.5 || ^4",
|
||||
"doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
|
||||
"doctrine/orm": "^2.14 || ^3",
|
||||
"ext-sqlite3": "*",
|
||||
"fig/log-test": "^1",
|
||||
"phpstan/phpstan": "2.1.17",
|
||||
"phpunit/phpunit": "10.5.45",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^10.5.3",
|
||||
"symfony/cache": "^6.4 || ^7",
|
||||
"symfony/var-exporter": "^6.4 || ^7"
|
||||
},
|
||||
@ -15184,7 +15182,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/data-fixtures/issues",
|
||||
"source": "https://github.com/doctrine/data-fixtures/tree/2.0.3"
|
||||
"source": "https://github.com/doctrine/data-fixtures/tree/2.0.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -15200,7 +15198,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T19:59:58+00:00"
|
||||
"time": "2025-01-21T13:21:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/doctrine-fixtures-bundle",
|
||||
@ -15847,59 +15845,58 @@
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.84.0",
|
||||
"version": "v3.75.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca"
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/38dad0767bf2a9b516b976852200ae722fe984ca",
|
||||
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"reference": "399a128ff2fdaf4281e4e79b755693286cdf325c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/ndjson-react": "^1.0",
|
||||
"composer/semver": "^3.4",
|
||||
"composer/xdebug-handler": "^3.0.5",
|
||||
"composer/xdebug-handler": "^3.0.3",
|
||||
"ext-filter": "*",
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"fidry/cpu-core-counter": "^1.2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"react/child-process": "^0.6.6",
|
||||
"react/child-process": "^0.6.5",
|
||||
"react/event-loop": "^1.0",
|
||||
"react/promise": "^2.11 || ^3.0",
|
||||
"react/promise": "^2.0 || ^3.0",
|
||||
"react/socket": "^1.0",
|
||||
"react/stream": "^1.0",
|
||||
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
||||
"symfony/console": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.32",
|
||||
"symfony/polyfill-php80": "^1.32",
|
||||
"symfony/polyfill-php81": "^1.32",
|
||||
"symfony/process": "^5.4.47 || ^6.4.20 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0"
|
||||
"sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0",
|
||||
"symfony/console": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/filesystem": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/finder": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/options-resolver": "^5.4 || ^6.4 || ^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.31",
|
||||
"symfony/polyfill-php80": "^1.31",
|
||||
"symfony/polyfill-php81": "^1.31",
|
||||
"symfony/process": "^5.4 || ^6.4 || ^7.2",
|
||||
"symfony/stopwatch": "^5.4 || ^6.4 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"facile-it/paraunit": "^1.3.1 || ^2.6",
|
||||
"infection/infection": "^0.29.14",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.4",
|
||||
"keradus/cli-executor": "^2.2",
|
||||
"justinrainbow/json-schema": "^5.3 || ^6.2",
|
||||
"keradus/cli-executor": "^2.1",
|
||||
"mikey179/vfsstream": "^1.6.12",
|
||||
"php-coveralls/php-coveralls": "^2.8",
|
||||
"php-coveralls/php-coveralls": "^2.7",
|
||||
"php-cs-fixer/accessible-object": "^1.1",
|
||||
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
|
||||
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
|
||||
"phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25",
|
||||
"symfony/polyfill-php84": "^1.32",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1"
|
||||
"phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.12",
|
||||
"symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.3",
|
||||
"symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "For handling output formats in XML",
|
||||
@ -15940,7 +15937,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.84.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.75.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -15948,7 +15945,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T18:21:57+00:00"
|
||||
"time": "2025-03-31T18:40:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsoftwig/twigcs",
|
||||
@ -19076,16 +19073,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/phpunit-bridge",
|
||||
"version": "v7.3.1",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/phpunit-bridge.git",
|
||||
"reference": "71624984d8bcad6acf7a790d4e3ceafe04bc2485"
|
||||
"reference": "6106ae85a0e3ed509d339b7f924788c9cc4e7cfb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/71624984d8bcad6acf7a790d4e3ceafe04bc2485",
|
||||
"reference": "71624984d8bcad6acf7a790d4e3ceafe04bc2485",
|
||||
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/6106ae85a0e3ed509d339b7f924788c9cc4e7cfb",
|
||||
"reference": "6106ae85a0e3ed509d339b7f924788c9cc4e7cfb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -19137,11 +19134,8 @@
|
||||
],
|
||||
"description": "Provides utilities for PHPUnit, especially user deprecation notices management",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"testing"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.3.1"
|
||||
"source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -19157,7 +19151,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-04T10:09:06+00:00"
|
||||
"time": "2025-04-09T08:35:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
@ -19455,6 +19449,6 @@
|
||||
"ext-tokenizer": "*",
|
||||
"ext-xml": "*"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
@ -1,12 +1,3 @@
|
||||
FROM golang as envsubst
|
||||
|
||||
ARG ENVSUBST_VERSION=v1.3.0
|
||||
|
||||
# envsubst from gettext can not replace env vars with default values
|
||||
# this package is not available for ARM32 and we have to build it from source code
|
||||
# flag -ldflags "-s -w" produces a smaller executable
|
||||
RUN go install -ldflags "-s -w" -v github.com/a8m/envsubst/cmd/envsubst@${ENVSUBST_VERSION}
|
||||
|
||||
FROM php:8.2-fpm AS rootless
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
@ -84,8 +75,10 @@ RUN mkdir -p /tmp/blackfire \
|
||||
|
||||
RUN npm install -g yarn
|
||||
|
||||
RUN curl -L -o /usr/local/bin/envsubst https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m`; \
|
||||
chmod +x /usr/local/bin/envsubst
|
||||
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
|
||||
COPY --from=envsubst /go/bin/envsubst /usr/local/bin/envsubst
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
COPY config/ /opt/wallabag/config/
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Wallabag\Doctrine\WallabagMigration;
|
||||
|
||||
/**
|
||||
* Add boolean for two-step setup for google authenticator.
|
||||
*/
|
||||
final class Version20250413133131 extends WallabagMigration
|
||||
{
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$userTable = $schema->getTable($this->getTable('user'));
|
||||
|
||||
$this->skipIf($userTable->hasColumn('google_authenticator'), 'It seems that you already played this migration.');
|
||||
|
||||
$userTable->addColumn('google_authenticator', 'boolean', [
|
||||
'default' => false,
|
||||
'notnull' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to update data in user table, as it's not possible to perform this in the `up` method.
|
||||
*/
|
||||
public function postUp(Schema $schema): void
|
||||
{
|
||||
$this->skipIf(!$schema->getTable($this->getTable('user'))->hasColumn('google_authenticator'), 'Unable to update google_authenticator column');
|
||||
$this->connection->executeQuery(
|
||||
'UPDATE ' . $this->getTable('user') . ' SET google_authenticator = :googleAuthenticator WHERE googleAuthenticatorSecret IS NOT NULL AND googleAuthenticatorSecret <> :emptyString',
|
||||
[
|
||||
'googleAuthenticator' => true,
|
||||
'emptyString' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$userTable = $schema->getTable($this->getTable('user'));
|
||||
$userTable->dropColumn('google_authenticator');
|
||||
}
|
||||
}
|
||||
106
migrations/Version20250526113708.php
Normal file
106
migrations/Version20250526113708.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Wallabag\Doctrine\WallabagMigration;
|
||||
|
||||
/**
|
||||
* Add setting to enable or disable each importer.
|
||||
*/
|
||||
final class Version20250526113708 extends WallabagMigration
|
||||
{
|
||||
private $settings = [
|
||||
[
|
||||
'name' => 'pocket_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'wallabag_v1_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'wallabag_v2_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'elcura_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'readability_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'instapaper_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'pinboard_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'delicious_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'omnivore_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'firefox_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'chrome_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'shaarli_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'pocket_html_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
[
|
||||
'name' => 'elcurator_enabled',
|
||||
'value' => '1',
|
||||
'section' => 'import',
|
||||
],
|
||||
];
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
foreach ($this->settings as $setting) {
|
||||
$settingEnabled = $this->connection
|
||||
->fetchOne('SELECT * FROM ' . $this->getTable('internal_setting') . " WHERE name = '" . $setting['name'] . "'");
|
||||
|
||||
if (false !== $settingEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->addSql('INSERT INTO ' . $this->getTable('internal_setting') . " (name, value, section) VALUES ('" . $setting['name'] . "', '" . $setting['value'] . "', '" . $setting['section'] . "');");
|
||||
}
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->skipIf(true, 'These settings are required and should not be removed.');
|
||||
}
|
||||
}
|
||||
28
package.json
28
package.json
@ -41,26 +41,26 @@
|
||||
"url": "https://github.com/wallabag/wallabag/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.28.3",
|
||||
"@babel/eslint-parser": "^7.28.0",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@babel/core": "^7.27.1",
|
||||
"@babel/eslint-parser": "^7.27.1",
|
||||
"@babel/preset-env": "^7.27.2",
|
||||
"@symfony/webpack-encore": "^5.1.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"babel-loader": "^10.0.0",
|
||||
"core-js": "^3.45.0",
|
||||
"core-js": "^3.42.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-webpack-plugin": "^5.0.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-webpack-plugin": "^5.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"lato-font": "^3.0.0",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"postcss": "^8.5.6",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"postcss": "^8.5.3",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"sass-embedded": "^1.90.0",
|
||||
"sass-embedded": "^1.89.0",
|
||||
"sass-loader": "^16.0.5",
|
||||
"style-loader": "^4.0.0",
|
||||
"stylelint": "^15.11.0",
|
||||
@ -69,17 +69,17 @@
|
||||
"stylelint-scss": "^5.3.2",
|
||||
"terser-webpack-plugin": "^5.3.14",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack": "^5.101.2",
|
||||
"webpack": "^5.99.9",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-manifest-plugin": "^5.0.1",
|
||||
"webpack-merge": "^6.0.1",
|
||||
"webpack-notifier": "^1.15.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/atkinson-hyperlegible": "^5.2.6",
|
||||
"@fontsource/eb-garamond": "^5.2.6",
|
||||
"@fontsource/montserrat": "^5.2.6",
|
||||
"@fontsource/oswald": "^5.2.6",
|
||||
"@fontsource/atkinson-hyperlegible": "^5.2.5",
|
||||
"@fontsource/eb-garamond": "^5.2.5",
|
||||
"@fontsource/montserrat": "^5.2.5",
|
||||
"@fontsource/oswald": "^5.2.5",
|
||||
"@hotwired/stimulus": "^3.2.2",
|
||||
"@materializecss/materialize": "^1.2.2",
|
||||
"@symfony/stimulus-bridge": "^4.0.1",
|
||||
|
||||
@ -9,9 +9,8 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Wallabag\Entity\Entry;
|
||||
use Wallabag\Entity\User;
|
||||
use Wallabag\Event\EntryDeletedEvent;
|
||||
use Wallabag\Repository\EntryRepository;
|
||||
use Wallabag\Repository\UserRepository;
|
||||
|
||||
@ -27,7 +26,6 @@ class CleanDuplicatesCommand extends Command
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly EntryRepository $entryRepository,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
@ -88,12 +86,7 @@ class CleanDuplicatesCommand extends Command
|
||||
if (\in_array($url, $urls, true)) {
|
||||
++$duplicatesCount;
|
||||
|
||||
$entryToDelete = $this->entryRepository->find($entry['id']);
|
||||
|
||||
// entry deleted, dispatch event about it!
|
||||
$this->eventDispatcher->dispatch(new EntryDeletedEvent($entryToDelete), EntryDeletedEvent::NAME);
|
||||
|
||||
$this->entityManager->remove($entryToDelete);
|
||||
$this->entityManager->remove($this->entryRepository->find($entry['id']));
|
||||
$this->entityManager->flush(); // Flushing at the end of the loop would require the instance not being online
|
||||
} else {
|
||||
$urls[] = $entry['url'];
|
||||
|
||||
@ -21,7 +21,6 @@ use Wallabag\Import\FirefoxImport;
|
||||
use Wallabag\Import\InstapaperImport;
|
||||
use Wallabag\Import\OmnivoreImport;
|
||||
use Wallabag\Import\PinboardImport;
|
||||
use Wallabag\Import\PocketCsvImport;
|
||||
use Wallabag\Import\PocketHtmlImport;
|
||||
use Wallabag\Import\ReadabilityImport;
|
||||
use Wallabag\Import\ShaarliImport;
|
||||
@ -49,7 +48,6 @@ class ImportCommand extends Command
|
||||
private readonly ElcuratorImport $elcuratorImport,
|
||||
private readonly ShaarliImport $shaarliImport,
|
||||
private readonly PocketHtmlImport $pocketHtmlImport,
|
||||
private readonly PocketCsvImport $pocketCsvImport,
|
||||
private readonly OmnivoreImport $omnivoreImport,
|
||||
) {
|
||||
parent::__construct();
|
||||
@ -60,7 +58,7 @@ class ImportCommand extends Command
|
||||
$this
|
||||
->addArgument('username', InputArgument::REQUIRED, 'User to populate')
|
||||
->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file')
|
||||
->addOption('importer', null, InputOption::VALUE_OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, delicious, readability, firefox, chrome, elcurator, shaarli, pocket or pocket_csv', 'v1')
|
||||
->addOption('importer', null, InputOption::VALUE_OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, delicious, readability, firefox, chrome, elcurator, shaarli or pocket', 'v1')
|
||||
->addOption('markAsRead', null, InputOption::VALUE_OPTIONAL, 'Mark all entries as read', false)
|
||||
->addOption('useUserId', null, InputOption::VALUE_NONE, 'Use user id instead of username to find account')
|
||||
->addOption('disableContentUpdate', null, InputOption::VALUE_NONE, 'Disable fetching updated content from URL')
|
||||
@ -111,7 +109,6 @@ class ImportCommand extends Command
|
||||
'elcurator' => $this->elcuratorImport,
|
||||
'shaarli' => $this->shaarliImport,
|
||||
'pocket' => $this->pocketHtmlImport,
|
||||
'pocket_csv' => $this->pocketCsvImport,
|
||||
'omnivore' => $this->omnivoreImport,
|
||||
default => $this->wallabagV1Import,
|
||||
};
|
||||
|
||||
@ -1,118 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\Command\Import;
|
||||
|
||||
use Doctrine\DBAL\Driver\Middleware;
|
||||
use Doctrine\DBAL\Logging\Middleware as LoggingMiddleware;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Config\Definition\Exception\Exception;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Wallabag\Entity\Entry;
|
||||
use Wallabag\Entity\User;
|
||||
use Wallabag\Helper\ContentProxy;
|
||||
use Wallabag\Helper\TagsAssigner;
|
||||
use Wallabag\Repository\UserRepository;
|
||||
|
||||
class UrlCommand extends Command
|
||||
{
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly TokenStorageInterface $tokenStorage,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly ContentProxy $contentProxy,
|
||||
private readonly TagsAssigner $tagsAssigner,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('wallabag:import:url')
|
||||
->setDescription('Import a single URL')
|
||||
->addArgument('username', InputArgument::REQUIRED, 'User to add the URL to (value: username or id)')
|
||||
->addArgument('url', InputArgument::REQUIRED, 'URL to import')
|
||||
->addArgument('tags', InputArgument::OPTIONAL, 'Comma-separated list of tags to add')
|
||||
->addOption('markAsRead', null, InputOption::VALUE_OPTIONAL, 'Mark entry as read', false)
|
||||
->addOption('useUserId', null, InputOption::VALUE_NONE, 'Use user id instead of username to find account')
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
// Turning off doctrine default logs queries for saving memory
|
||||
$middlewares = $this->entityManager->getConnection()->getConfiguration()->getMiddlewares();
|
||||
$middlewaresWithoutLogging = array_filter($middlewares, fn (Middleware $middleware) => !$middleware instanceof LoggingMiddleware);
|
||||
$this->entityManager->getConnection()->getConfiguration()->setMiddlewares($middlewaresWithoutLogging);
|
||||
|
||||
if ($input->getOption('useUserId')) {
|
||||
$entityUser = $this->userRepository->findOneById($input->getArgument('username'));
|
||||
} else {
|
||||
$entityUser = $this->userRepository->findOneByUsername($input->getArgument('username'));
|
||||
}
|
||||
|
||||
if (!\is_object($entityUser)) {
|
||||
throw new Exception(\sprintf('User "%s" not found', $input->getArgument('username')));
|
||||
}
|
||||
|
||||
// Authenticate user for paywalled websites
|
||||
$token = new UsernamePasswordToken(
|
||||
$entityUser,
|
||||
'main',
|
||||
$entityUser->getRoles()
|
||||
);
|
||||
|
||||
$this->tokenStorage->setToken($token);
|
||||
$user = $this->tokenStorage->getToken()->getUser();
|
||||
\assert($user instanceof User);
|
||||
|
||||
$url = $input->getArgument('url');
|
||||
|
||||
$existingEntry = $this->entityManager
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId($url, $user->getId());
|
||||
|
||||
if (false !== $existingEntry) {
|
||||
$output->writeln(\sprintf('The URL %s is already in user’s entries.', $url));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$entry = new Entry($user);
|
||||
|
||||
try {
|
||||
$this->contentProxy->updateEntry($entry, $url);
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln(\sprintf('Error trying to import the URL %s: %s.', $url, $e->getMessage()));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($input->getOption('markAsRead')) {
|
||||
$entry->updateArchived(true);
|
||||
}
|
||||
|
||||
$this->entityManager->persist($entry);
|
||||
|
||||
$tags = explode(',', $input->getArgument('tags'));
|
||||
if (\count($tags) > 1) {
|
||||
$this->tagsAssigner->assignTagsToEntry(
|
||||
$entry,
|
||||
$tags,
|
||||
$this->entityManager->getUnitOfWork()->getScheduledEntityInsertions()
|
||||
);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
$output->writeln(\sprintf('URL %s successfully imported.', $url));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,6 @@ class RabbitMQConsumerTotalProxy
|
||||
private readonly Consumer $elcuratorConsumer,
|
||||
private readonly Consumer $shaarliConsumer,
|
||||
private readonly Consumer $pocketHtmlConsumer,
|
||||
private readonly Consumer $pocketCsvConsumer,
|
||||
private readonly Consumer $omnivoreConsumer,
|
||||
) {
|
||||
}
|
||||
@ -76,9 +75,6 @@ class RabbitMQConsumerTotalProxy
|
||||
case 'pocket_html':
|
||||
$consumer = $this->pocketHtmlConsumer;
|
||||
break;
|
||||
case 'pocket_csv':
|
||||
$consumer = $this->pocketCsvConsumer;
|
||||
break;
|
||||
case 'omnivore':
|
||||
$consumer = $this->omnivoreConsumer;
|
||||
break;
|
||||
|
||||
@ -290,17 +290,6 @@ class EntryRestController extends WallabagRestController
|
||||
* example="200",
|
||||
* )
|
||||
* ),
|
||||
* @OA\Parameter(
|
||||
* name="annotations",
|
||||
* in="query",
|
||||
* description="filter entries with annotations. all entries by default",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="integer",
|
||||
* enum={"1", "0"},
|
||||
* default="0"
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returned when successful"
|
||||
@ -326,7 +315,6 @@ class EntryRestController extends WallabagRestController
|
||||
$detail = strtolower($request->query->get('detail', 'full'));
|
||||
$domainName = (null === $request->query->get('domain_name')) ? '' : (string) $request->query->get('domain_name');
|
||||
$httpStatus = (!\array_key_exists((int) $request->query->get('http_status'), Response::$statusTexts)) ? null : (int) $request->query->get('http_status');
|
||||
$hasAnnotations = (null === $request->query->get('annotations')) ? null : (bool) $request->query->get('annotations');
|
||||
|
||||
try {
|
||||
/** @var Pagerfanta $pager */
|
||||
@ -342,8 +330,7 @@ class EntryRestController extends WallabagRestController
|
||||
$detail,
|
||||
$domainName,
|
||||
$isNotParsed,
|
||||
$httpStatus,
|
||||
$hasAnnotations
|
||||
$httpStatus
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
throw new BadRequestHttpException($e->getMessage());
|
||||
@ -369,7 +356,6 @@ class EntryRestController extends WallabagRestController
|
||||
'tags' => $tags,
|
||||
'since' => $since,
|
||||
'detail' => $detail,
|
||||
'annotations' => $hasAnnotations,
|
||||
],
|
||||
true
|
||||
)
|
||||
|
||||
@ -313,7 +313,6 @@ class ConfigController extends AbstractController
|
||||
$user = $this->getUser();
|
||||
|
||||
$user->setGoogleAuthenticatorSecret('');
|
||||
$user->setGoogleAuthenticator(false);
|
||||
$user->setBackupCodes(null);
|
||||
|
||||
$this->userManager->updateUser($user);
|
||||
@ -355,6 +354,11 @@ class ConfigController extends AbstractController
|
||||
$this->userManager->updateUser($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->addFlash(
|
||||
'notice',
|
||||
'flashes.config.notice.otp_enabled'
|
||||
);
|
||||
|
||||
return $this->render('Config/otp_app.html.twig', [
|
||||
'backupCodes' => $backupCodes,
|
||||
'qr_code' => $googleAuthenticator->getQRContent($user),
|
||||
@ -404,9 +408,6 @@ class ConfigController extends AbstractController
|
||||
'notice',
|
||||
'flashes.config.notice.otp_enabled'
|
||||
);
|
||||
$user->setGoogleAuthenticator(true);
|
||||
$this->userManager->updateUser($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirect($this->generateUrl('config') . '#set3');
|
||||
}
|
||||
@ -420,9 +421,8 @@ class ConfigController extends AbstractController
|
||||
$user->setBackupCodes(null);
|
||||
|
||||
$this->userManager->updateUser($user);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->redirect($this->generateUrl('config_otp_app'), 307);
|
||||
return $this->redirect($this->generateUrl('config') . '#set3');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -627,16 +627,6 @@ class EntryController extends AbstractController
|
||||
$currentEntryId = $request->attributes->getInt('id');
|
||||
|
||||
$formOptions = [];
|
||||
$direction = 'desc';
|
||||
$sortBy = null;
|
||||
|
||||
if (null !== $request->get('entry_filter') && null !== $request->get('entry_filter')['sortType'] && '' !== $request->get('entry_filter')['sortType']) {
|
||||
$direction = (null !== $request->get('entry_filter')['sortOrder'] && \in_array($request->get('entry_filter')['sortOrder'], ['asc', 'desc'], true)) ? $request->get('entry_filter')['sortOrder'] : 'desc';
|
||||
|
||||
if (\in_array($request->get('entry_filter')['sortType'], ['id','title','createdAt', 'url', 'readingTime'], true)) {
|
||||
$sortBy = $request->get('entry_filter')['sortType'];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'search':
|
||||
@ -664,7 +654,7 @@ class EntryController extends AbstractController
|
||||
$qb = $this->entryRepository->getBuilderForSameDomainByUser($this->getUser()->getId(), $currentEntryId);
|
||||
break;
|
||||
case 'all':
|
||||
$qb = $this->entryRepository->getBuilderForAllByUser($this->getUser()->getId(), $sortBy, $direction);
|
||||
$qb = $this->entryRepository->getBuilderForAllByUser($this->getUser()->getId());
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException(\sprintf('Type "%s" is not implemented.', $type));
|
||||
|
||||
@ -20,11 +20,15 @@ abstract class BrowserController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, TranslatorInterface $translator)
|
||||
{
|
||||
$import = $this->getImportService();
|
||||
if (!$import->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
$wallabag = $this->getImportService();
|
||||
$wallabag->setUser($this->getUser());
|
||||
$import->setUser($this->getUser());
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$file = $form->get('file')->getData();
|
||||
@ -32,7 +36,7 @@ abstract class BrowserController extends AbstractController
|
||||
$name = $this->getUser()->getId() . '.json';
|
||||
|
||||
if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag.resource_dir'), $name)) {
|
||||
$res = $wallabag
|
||||
$res = $import
|
||||
->setFilepath($this->getParameter('wallabag.resource_dir') . '/' . $name)
|
||||
->setMarkAsRead($markAsRead)
|
||||
->import();
|
||||
@ -40,7 +44,7 @@ abstract class BrowserController extends AbstractController
|
||||
$message = 'flashes.import.notice.failed';
|
||||
|
||||
if (true === $res) {
|
||||
$summary = $wallabag->getSummary();
|
||||
$summary = $import->getSummary();
|
||||
$message = $translator->trans('flashes.import.notice.summary', [
|
||||
'%imported%' => $summary['imported'],
|
||||
'%skipped%' => $summary['skipped'],
|
||||
@ -64,7 +68,7 @@ abstract class BrowserController extends AbstractController
|
||||
|
||||
return $this->render($this->getImportTemplate(), [
|
||||
'form' => $form->createView(),
|
||||
'import' => $wallabag,
|
||||
'import' => $import,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,10 @@ class DeliciousController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, DeliciousImport $delicious, Config $craueConfig, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$delicious->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
||||
@ -20,11 +20,15 @@ abstract class HtmlController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, TranslatorInterface $translator)
|
||||
{
|
||||
$import = $this->getImportService();
|
||||
if (!$import->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
$wallabag = $this->getImportService();
|
||||
$wallabag->setUser($this->getUser());
|
||||
$import->setUser($this->getUser());
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$file = $form->get('file')->getData();
|
||||
@ -32,7 +36,7 @@ abstract class HtmlController extends AbstractController
|
||||
$name = $this->getUser()->getId() . '.html';
|
||||
|
||||
if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag.resource_dir'), $name)) {
|
||||
$res = $wallabag
|
||||
$res = $import
|
||||
->setFilepath($this->getParameter('wallabag.resource_dir') . '/' . $name)
|
||||
->setMarkAsRead($markAsRead)
|
||||
->import();
|
||||
@ -40,7 +44,7 @@ abstract class HtmlController extends AbstractController
|
||||
$message = 'flashes.import.notice.failed';
|
||||
|
||||
if (true === $res) {
|
||||
$summary = $wallabag->getSummary();
|
||||
$summary = $import->getSummary();
|
||||
$message = $translator->trans('flashes.import.notice.summary', [
|
||||
'%imported%' => $summary['imported'],
|
||||
'%skipped%' => $summary['skipped'],
|
||||
@ -64,7 +68,7 @@ abstract class HtmlController extends AbstractController
|
||||
|
||||
return $this->render($this->getImportTemplate(), [
|
||||
'form' => $form->createView(),
|
||||
'import' => $wallabag,
|
||||
'import' => $import,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -58,7 +58,6 @@ class ImportController extends AbstractController
|
||||
+ $this->rabbitMQConsumerTotalProxy->getTotalMessage('elcurator')
|
||||
+ $this->rabbitMQConsumerTotalProxy->getTotalMessage('shaarli')
|
||||
+ $this->rabbitMQConsumerTotalProxy->getTotalMessage('pocket_html')
|
||||
+ $this->rabbitMQConsumerTotalProxy->getTotalMessage('pocket_csv')
|
||||
+ $this->rabbitMQConsumerTotalProxy->getTotalMessage('omnivore')
|
||||
;
|
||||
} catch (\Exception) {
|
||||
@ -78,7 +77,6 @@ class ImportController extends AbstractController
|
||||
+ $this->redisClient->llen('wallabag.import.elcurator')
|
||||
+ $this->redisClient->llen('wallabag.import.shaarli')
|
||||
+ $this->redisClient->llen('wallabag.import.pocket_html')
|
||||
+ $this->redisClient->llen('wallabag.import.pocket_csv')
|
||||
+ $this->redisClient->llen('wallabag.import.omnivore')
|
||||
;
|
||||
} catch (\Exception) {
|
||||
|
||||
@ -25,6 +25,10 @@ class InstapaperController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, InstapaperImport $instapaper, Config $craueConfig, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$instapaper->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
||||
@ -25,6 +25,10 @@ class OmnivoreController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, OmnivoreImport $omnivore, Config $craueConfig, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$omnivore->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
||||
@ -25,6 +25,10 @@ class PinboardController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, PinboardImport $pinboard, Config $craueConfig, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$pinboard->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
||||
@ -29,6 +29,10 @@ class PocketController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(PocketImport $pocketImport)
|
||||
{
|
||||
if (!$pocketImport->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$pocket = $this->getPocketImportService($pocketImport);
|
||||
|
||||
$form = $this->createFormBuilder($pocket)
|
||||
@ -49,6 +53,10 @@ class PocketController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function authAction(Request $request, PocketImport $pocketImport)
|
||||
{
|
||||
if (!$pocketImport->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$requestToken = $this->getPocketImportService($pocketImport)
|
||||
->getRequestToken($this->generateUrl('import', [], UrlGeneratorInterface::ABSOLUTE_URL));
|
||||
|
||||
@ -78,6 +86,10 @@ class PocketController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function callbackAction(PocketImport $pocketImport, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$pocketImport->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$message = 'flashes.import.notice.failed';
|
||||
$pocket = $this->getPocketImportService($pocketImport);
|
||||
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\Controller\Import;
|
||||
|
||||
use Craue\ConfigBundle\Util\Config;
|
||||
use OldSound\RabbitMqBundle\RabbitMq\Producer as RabbitMqProducer;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Wallabag\Controller\AbstractController;
|
||||
use Wallabag\Form\Type\UploadImportType;
|
||||
use Wallabag\Import\PocketCsvImport;
|
||||
use Wallabag\Redis\Producer as RedisProducer;
|
||||
|
||||
class PocketCsvController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PocketCsvImport $pocketCsvImport,
|
||||
private readonly Config $craueConfig,
|
||||
private readonly RabbitMqProducer $rabbitMqProducer,
|
||||
private readonly RedisProducer $redisProducer,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Route(path: '/import/pocket_csv', name: 'import_pocket_csv', methods: ['GET', 'POST'])]
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, TranslatorInterface $translator)
|
||||
{
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
$this->pocketCsvImport->setUser($this->getUser());
|
||||
|
||||
if ($this->craueConfig->get('import_with_rabbitmq')) {
|
||||
$this->pocketCsvImport->setProducer($this->rabbitMqProducer);
|
||||
} elseif ($this->craueConfig->get('import_with_redis')) {
|
||||
$this->pocketCsvImport->setProducer($this->redisProducer);
|
||||
}
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$file = $form->get('file')->getData();
|
||||
$markAsRead = $form->get('mark_as_read')->getData();
|
||||
$name = 'pocket_' . $this->getUser()->getId() . '.csv';
|
||||
|
||||
if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag.resource_dir'), $name)) {
|
||||
$res = $this->pocketCsvImport
|
||||
->setFilepath($this->getParameter('wallabag.resource_dir') . '/' . $name)
|
||||
->setMarkAsRead($markAsRead)
|
||||
->import();
|
||||
|
||||
$message = 'flashes.import.notice.failed';
|
||||
|
||||
if (true === $res) {
|
||||
$summary = $this->pocketCsvImport->getSummary();
|
||||
$message = $translator->trans('flashes.import.notice.summary', [
|
||||
'%imported%' => $summary['imported'],
|
||||
'%skipped%' => $summary['skipped'],
|
||||
]);
|
||||
|
||||
if (0 < $summary['queued']) {
|
||||
$message = $translator->trans('flashes.import.notice.summary_with_queue', [
|
||||
'%queued%' => $summary['queued'],
|
||||
]);
|
||||
}
|
||||
|
||||
unlink($this->getParameter('wallabag.resource_dir') . '/' . $name);
|
||||
}
|
||||
|
||||
$this->addFlash('notice', $message);
|
||||
|
||||
return $this->redirect($this->generateUrl('homepage'));
|
||||
}
|
||||
|
||||
$this->addFlash('notice', 'flashes.import.notice.failed_on_file');
|
||||
}
|
||||
|
||||
return $this->render('Import/PocketCsv/index.html.twig', [
|
||||
'form' => $form->createView(),
|
||||
'import' => $this->pocketCsvImport,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getImportService()
|
||||
{
|
||||
if ($this->craueConfig->get('import_with_rabbitmq')) {
|
||||
$this->pocketCsvImport->setProducer($this->rabbitMqProducer);
|
||||
} elseif ($this->craueConfig->get('import_with_redis')) {
|
||||
$this->pocketCsvImport->setProducer($this->redisProducer);
|
||||
}
|
||||
|
||||
return $this->pocketCsvImport;
|
||||
}
|
||||
|
||||
protected function getImportTemplate()
|
||||
{
|
||||
return 'Import/PocketCsv/index.html.twig';
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,10 @@ class ReadabilityController extends AbstractController
|
||||
#[IsGranted('IMPORT_ENTRIES')]
|
||||
public function indexAction(Request $request, ReadabilityImport $readability, Config $craueConfig, TranslatorInterface $translator)
|
||||
{
|
||||
if (!$readability->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
||||
@ -22,11 +22,15 @@ abstract class WallabagController extends AbstractController
|
||||
*/
|
||||
public function indexAction(Request $request, TranslatorInterface $translator)
|
||||
{
|
||||
$import = $this->getImportService();
|
||||
if (!$import->isEnabled()) {
|
||||
throw $this->createNotFoundException('Import is disabled');
|
||||
}
|
||||
|
||||
$form = $this->createForm(UploadImportType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
$wallabag = $this->getImportService();
|
||||
$wallabag->setUser($this->getUser());
|
||||
$import->setUser($this->getUser());
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$file = $form->get('file')->getData();
|
||||
@ -34,7 +38,7 @@ abstract class WallabagController extends AbstractController
|
||||
$name = $this->getUser()->getId() . '.json';
|
||||
|
||||
if (null !== $file && \in_array($file->getClientMimeType(), $this->getParameter('wallabag.allow_mimetypes'), true) && $file->move($this->getParameter('wallabag.resource_dir'), $name)) {
|
||||
$res = $wallabag
|
||||
$res = $import
|
||||
->setFilepath($this->getParameter('wallabag.resource_dir') . '/' . $name)
|
||||
->setMarkAsRead($markAsRead)
|
||||
->import();
|
||||
@ -42,7 +46,7 @@ abstract class WallabagController extends AbstractController
|
||||
$message = 'flashes.import.notice.failed';
|
||||
|
||||
if (true === $res) {
|
||||
$summary = $wallabag->getSummary();
|
||||
$summary = $import->getSummary();
|
||||
$message = $translator->trans('flashes.import.notice.summary', [
|
||||
'%imported%' => $summary['imported'],
|
||||
'%skipped%' => $summary['skipped'],
|
||||
@ -67,7 +71,7 @@ abstract class WallabagController extends AbstractController
|
||||
|
||||
return $this->render($this->getImportTemplate(), [
|
||||
'form' => $form->createView(),
|
||||
'import' => $wallabag,
|
||||
'import' => $import,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -147,11 +147,6 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
|
||||
#[ORM\Column(name: 'googleAuthenticatorSecret', type: 'string', nullable: true)]
|
||||
private $googleAuthenticatorSecret;
|
||||
|
||||
// default value is explicitly set to false here to ensure that Doctrine
|
||||
// does not complain about schema mapping mismatch
|
||||
#[ORM\Column(name: 'google_authenticator', type: 'boolean', options: ['default' => false])]
|
||||
private $googleAuthenticator = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@ -269,11 +264,6 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
|
||||
$this->emailTwoFactor = $emailTwoFactor;
|
||||
}
|
||||
|
||||
public function setGoogleAuthenticator(bool $googleAuthenticator): void
|
||||
{
|
||||
$this->googleAuthenticator = $googleAuthenticator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in the user config form to be "like" the email option.
|
||||
*/
|
||||
@ -304,7 +294,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI
|
||||
|
||||
public function isGoogleAuthenticatorEnabled(): bool
|
||||
{
|
||||
return $this->googleAuthenticator;
|
||||
return $this->googleAuthenticatorSecret ? true : false;
|
||||
}
|
||||
|
||||
public function getGoogleAuthenticatorUsername(): string
|
||||
|
||||
@ -205,24 +205,6 @@ class EntryFilterType extends AbstractType
|
||||
'choices' => array_flip($this->repository->findDistinctLanguageByUser($user->getId())),
|
||||
'label' => 'entry.filters.language_label',
|
||||
])
|
||||
->add('sortOrder', ChoiceFilterType::class, [
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { },
|
||||
'choices' => [
|
||||
'entry.sort.ascending' => 'asc',
|
||||
'entry.sort.descending' => 'desc',
|
||||
],
|
||||
'label' => 'entry.sort.order_label',
|
||||
])
|
||||
->add('sortType', ChoiceFilterType::class, [
|
||||
'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { },
|
||||
'choices' => [
|
||||
'entry.sort.by.creation_date' => 'createdAt',
|
||||
'entry.sort.by.title' => 'title',
|
||||
'entry.sort.by.url' => 'url',
|
||||
'entry.sort.by.reading_time' => 'readingTime',
|
||||
],
|
||||
'label' => 'entry.sort.status_label',
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ abstract class AbstractImport implements ImportInterface
|
||||
protected $skippedEntries = 0;
|
||||
protected $importedEntries = 0;
|
||||
protected $queuedEntries = 0;
|
||||
protected $enabled = true;
|
||||
|
||||
public function __construct(
|
||||
protected EntityManagerInterface $em,
|
||||
@ -74,6 +75,25 @@ abstract class AbstractImport implements ImportInterface
|
||||
return $this->markAsRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the import is enabled.
|
||||
* If not, the importer won't be available in the UI.
|
||||
*/
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the import is enabled.
|
||||
*/
|
||||
public function setEnabled(bool $enabled): static
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether articles should be fetched for updated content.
|
||||
*
|
||||
|
||||
@ -63,4 +63,15 @@ interface ImportInterface extends LoggerAwareInterface
|
||||
* @param bool $markAsRead
|
||||
*/
|
||||
public function setMarkAsRead($markAsRead): static;
|
||||
|
||||
/**
|
||||
* Get whether the import is enabled.
|
||||
* If not, the importer won't be available in the UI.
|
||||
*/
|
||||
public function isEnabled(): bool;
|
||||
|
||||
/**
|
||||
* Set whether the import is enabled.
|
||||
*/
|
||||
public function setEnabled(bool $enabled): static;
|
||||
}
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\Import;
|
||||
|
||||
use Wallabag\Entity\Entry;
|
||||
|
||||
class PocketCsvImport extends AbstractImport
|
||||
{
|
||||
protected $filepath;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'Pocket CSV';
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return 'import_pocket_csv';
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'import.pocket_csv.description';
|
||||
}
|
||||
|
||||
public function setFilepath($filepath): static
|
||||
{
|
||||
$this->filepath = $filepath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function validateEntry(array $importedEntry)
|
||||
{
|
||||
if (empty($importedEntry['url'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
if (!$this->user) {
|
||||
$this->logger->error('Pocket CSV Import: user is not defined');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_exists($this->filepath) || !is_readable($this->filepath)) {
|
||||
$this->logger->error('Pocket CSV Import: unable to read file', ['filepath' => $this->filepath]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$entries = [];
|
||||
$handle = fopen($this->filepath, 'r');
|
||||
while (false !== ($data = fgetcsv($handle, 10240))) {
|
||||
if ('title' === $data[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$entries[] = [
|
||||
'url' => $data[1],
|
||||
'title' => $data[0],
|
||||
'is_archived' => 'archive' === $data[4],
|
||||
'created_at' => $data[2],
|
||||
'tags' => $data[3],
|
||||
];
|
||||
}
|
||||
fclose($handle);
|
||||
|
||||
if (empty($entries)) {
|
||||
$this->logger->error('PocketCsvImport: no entries in imported file');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->producer) {
|
||||
$this->parseEntriesForProducer($entries);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->parseEntries($entries);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function parseEntry(array $importedEntry)
|
||||
{
|
||||
$existingEntry = $this->em
|
||||
->getRepository(Entry::class)
|
||||
->findByUrlAndUserId($importedEntry['url'], $this->user->getId());
|
||||
|
||||
if (false !== $existingEntry) {
|
||||
++$this->skippedEntries;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$entry = new Entry($this->user);
|
||||
$entry->setUrl($importedEntry['url']);
|
||||
$entry->setTitle($importedEntry['title']);
|
||||
|
||||
// update entry with content (in case fetching failed, the given entry will be return)
|
||||
$this->fetchContent($entry, $importedEntry['url'], $importedEntry);
|
||||
|
||||
if (!empty($importedEntry['tags'])) {
|
||||
$tags = str_replace('|', ',', $importedEntry['tags']);
|
||||
$this->tagsAssigner->assignTagsToEntry(
|
||||
$entry,
|
||||
$tags,
|
||||
$this->em->getUnitOfWork()->getScheduledEntityInsertions()
|
||||
);
|
||||
}
|
||||
|
||||
$entry->updateArchived($importedEntry['is_archived']);
|
||||
$entry->setCreatedAt(\DateTime::createFromFormat('U', $importedEntry['created_at']));
|
||||
|
||||
$this->em->persist($entry);
|
||||
++$this->importedEntries;
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
protected function setEntryAsRead(array $importedEntry)
|
||||
{
|
||||
$importedEntry['is_archived'] = 'archive';
|
||||
|
||||
return $importedEntry;
|
||||
}
|
||||
}
|
||||
@ -30,11 +30,10 @@ class EntryRepository extends ServiceEntityRepository
|
||||
*
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public function getBuilderForAllByUser($userId, $sortBy = 'createdAt', $direction = 'desc')
|
||||
public function getBuilderForAllByUser($userId)
|
||||
{
|
||||
$sortBy = $sortBy ?: 'createdAt';
|
||||
return $this
|
||||
->getSortedQueryBuilderByUser($userId, $sortBy, $direction)
|
||||
->getSortedQueryBuilderByUser($userId)
|
||||
;
|
||||
}
|
||||
|
||||
@ -269,17 +268,16 @@ class EntryRepository extends ServiceEntityRepository
|
||||
* @param string $order
|
||||
* @param int $since
|
||||
* @param string $tags
|
||||
* @param string $detail 'metadata' or 'full'. Include content field if 'full'
|
||||
* @param string $detail 'metadata' or 'full'. Include content field if 'full'
|
||||
* @param string $domainName
|
||||
* @param int $httpStatus
|
||||
* @param bool $isNotParsed
|
||||
* @param bool $hasAnnotations
|
||||
*
|
||||
* @todo Breaking change: replace default detail=full by detail=metadata in a future version
|
||||
*
|
||||
* @return Pagerfanta
|
||||
*/
|
||||
public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '', $detail = 'full', $domainName = '', $isNotParsed = null, $httpStatus = null, $hasAnnotations = null)
|
||||
public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'asc', $since = 0, $tags = '', $detail = 'full', $domainName = '', $isNotParsed = null, $httpStatus = null)
|
||||
{
|
||||
if (!\in_array(strtolower($detail), ['full', 'metadata'], true)) {
|
||||
throw new \Exception('Detail "' . $detail . '" parameter is wrong, allowed: full or metadata');
|
||||
@ -344,16 +342,6 @@ class EntryRepository extends ServiceEntityRepository
|
||||
$qb->andWhere('e.domainName = :domainName')->setParameter('domainName', $domainName);
|
||||
}
|
||||
|
||||
if (null !== $hasAnnotations) {
|
||||
if ($hasAnnotations) {
|
||||
$qb->leftJoin('e.annotations', 'a')
|
||||
->andWhere('a.id IS NOT NULL');
|
||||
} else {
|
||||
$qb->leftJoin('e.annotations', 'a')
|
||||
->andWhere('a.id IS NULL');
|
||||
}
|
||||
}
|
||||
|
||||
if (!\in_array(strtolower($order), ['asc', 'desc'], true)) {
|
||||
throw new \Exception('Order "' . $order . '" parameter is wrong, allowed: asc or desc');
|
||||
}
|
||||
|
||||
@ -18,14 +18,14 @@
|
||||
<img data-controller="qrcode" data-qrcode-url-value="{{ qr_code|raw }}" class="hide-on-med-and-down" />
|
||||
</p>
|
||||
|
||||
<div id="config_otp_app_secret">
|
||||
<div data-controller="highlight">
|
||||
{{ 'config.otp.app.two_factor_code_description_5'|trans }} <pre><code>{{ secret }}</code></pre>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
|
||||
|
||||
<div><pre><code>{{ backupCodes|join("\n") }}</code></pre></div>
|
||||
<div data-controller="highlight"><pre><code>{{ backupCodes|join("\n") }}</code></pre></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
|
||||
@ -36,7 +36,7 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<form class="form" action="{{ path("config_otp_app_check") }}" method="post" name="config_otp_app_check">
|
||||
<form class="form" action="{{ path("config_otp_app_check") }}" method="post">
|
||||
<input type="hidden" name="token" value="{{ csrf_token('otp') }}" />
|
||||
<div class="card-content">
|
||||
<div class="row">
|
||||
|
||||
@ -276,22 +276,6 @@
|
||||
<label for="entry_filter_createdAt_right_date" class="active">{{ 'entry.filters.created_at.to'|trans }}</label>
|
||||
</div>
|
||||
|
||||
<div class="col s6">
|
||||
{{ form_label(form.sortType) }}
|
||||
</div>
|
||||
|
||||
<div class="col s6">
|
||||
{{ form_label(form.sortOrder) }}
|
||||
</div>
|
||||
|
||||
<div class="col s6">
|
||||
{{ form_widget(form.sortType) }}
|
||||
</div>
|
||||
|
||||
<div class="col s6">
|
||||
{{ form_widget(form.sortOrder) }}
|
||||
</div>
|
||||
|
||||
<div class="col s6">
|
||||
<button type="reset" class="center waves-effect waves-green btn-flat">{{ 'entry.filters.action.clear'|trans }}</button>
|
||||
</div>
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
<header class="block">
|
||||
<h1>{{ entry.title|e|raw }}</h1>
|
||||
<a href="{{ entry.url|e }}" target="_blank" rel="noopener" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|e|raw }}" class="tool">{{ entry.domainName|removeWww }}</a>
|
||||
<p class="shared-by">{{ "entry.public.shared_by_wallabag"|trans({'%wallabag_instance%': url('homepage'), '%username%': entry.user.name|escape})|raw }}.</p>
|
||||
<p class="shared-by">{{ "entry.public.shared_by_wallabag"|trans({'%wallabag_instance%': url('homepage'), '%username%': entry.user.username|escape})|raw }}.</p>
|
||||
</header>
|
||||
<article class="block">
|
||||
{{ entry.content|raw }}
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
{% extends "layout.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'import.pocket_csv.page_title'|trans }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card-panel settings">
|
||||
{% include 'Import/_information.html.twig' %}
|
||||
|
||||
<div class="row">
|
||||
<blockquote>{{ import.description|trans|raw }}</blockquote>
|
||||
<p>{{ 'import.pocket_csv.how_to'|trans }}</p>
|
||||
|
||||
<div class="col s12">
|
||||
{{ form_start(form, {'method': 'POST'}) }}
|
||||
{{ form_errors(form) }}
|
||||
<div class="row">
|
||||
<div class="file-field input-field col s12">
|
||||
{{ form_errors(form.file) }}
|
||||
<div class="btn">
|
||||
<span>{{ form.file.vars.label|trans }}</span>
|
||||
{{ form_widget(form.file) }}
|
||||
</div>
|
||||
<div class="file-path-wrapper">
|
||||
<input class="file-path validate" type="text">
|
||||
</div>
|
||||
</div>
|
||||
<h6 class="col s12">{{ 'import.form.mark_as_read_title'|trans }}</h6>
|
||||
<div class="col s6 with-checkbox">
|
||||
<label for="{{ form.mark_as_read.vars.id }}">
|
||||
{{ form_widget(form.mark_as_read) }}
|
||||
<span>{{ form.mark_as_read.vars.label|trans }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
|
||||
|
||||
{{ form_rest(form) }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -16,17 +16,17 @@
|
||||
|
||||
{{ 'import.page_description'|trans }}
|
||||
<div class="row">
|
||||
{% for import in imports %}
|
||||
{% for import in imports | filter(i => i.isEnabled()) %}
|
||||
<div class="col s6 m3">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ import.name }}</span>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<a href="{{ path(import.url) }}">{{ 'import.action.import_contents'|trans }}</a>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ import.name }}</span>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<a href="{{ path(import.url) }}">{{ 'import.action.import_contents'|trans }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -20,11 +20,10 @@
|
||||
|
||||
<div id="set1" class="col s12">
|
||||
<dt>{{ 'about.who_behind_wallabag.developped_by'|trans }}</dt>
|
||||
<dd>Nicolas Lœuillet — <a href="https://nicolas.loeuillet.org">{{ 'about.who_behind_wallabag.website'|trans }}</a></dd>
|
||||
<dd><a href="mailto:nicolas@loeuillet.org">Nicolas Lœuillet</a> — <a href="https://nicolas.loeuillet.org">{{ 'about.who_behind_wallabag.website'|trans }}</a></dd>
|
||||
<dd>Thomas Citharel — <a href="https://tcit.fr">{{ 'about.who_behind_wallabag.website'|trans }}</a></dd>
|
||||
<dd>Jérémy Benoist — <a href="https://www.j0k3r.net">{{ 'about.who_behind_wallabag.website'|trans }}</a></dd>
|
||||
<dd>Kevin Decherf — <a href="https://kdecherf.com/">{{ 'about.who_behind_wallabag.website'|trans }}</a></dd>
|
||||
<dd>Yassine Guedidi</dd>
|
||||
<dt>{{ 'about.who_behind_wallabag.many_contributors'|trans|raw }}</dt>
|
||||
<dt>{{ 'about.who_behind_wallabag.project_website'|trans }}</dt>
|
||||
<dd><a href="https://www.wallabag.org">https://www.wallabag.org</a></dd>
|
||||
@ -34,7 +33,11 @@
|
||||
|
||||
<div id="set2" class="col s12">
|
||||
<dl>
|
||||
<dt><a href="https://doc.wallabag.org/">{{ 'about.getting_help.documentation'|trans }}</a></dt>
|
||||
<dt>{{ 'about.getting_help.documentation'|trans }}</dt>
|
||||
<dd><a href="https://doc.wallabag.org/en/">english</a></dd>
|
||||
<dd><a href="https://doc.wallabag.org/fr/">français</a></dd>
|
||||
<dd><a href="https://doc.wallabag.org/de/">deutsch</a></dd>
|
||||
<dd><a href="https://doc.wallabag.org/it/">italiano</a></dd>
|
||||
|
||||
<dt>{{ 'about.getting_help.bug_reports'|trans }}</dt>
|
||||
<dd>{{ 'about.getting_help.support'|trans|raw }}</dd>
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<ul>
|
||||
<li><a href="{{ path('import_pocket_csv') }}">{{ 'quickstart.migrate.pocket'|trans }}</a></li>
|
||||
<li><a href="{{ path('import_pocket') }}">{{ 'quickstart.migrate.pocket'|trans }}</a></li>
|
||||
<li><a href="{{ path('import_readability') }}">{{ 'quickstart.migrate.readability'|trans }}</a></li>
|
||||
<li><a href="{{ path('import_instapaper') }}">{{ 'quickstart.migrate.instapaper'|trans }}</a></li>
|
||||
<li><a href="{{ path('import') }}">{{ 'quickstart.more'|trans }}</a></li>
|
||||
@ -75,6 +75,7 @@
|
||||
<div class="card-action">
|
||||
<ul>
|
||||
<li><a href="{{ path('developer') }}">{{ 'quickstart.developer.create_application'|trans }}</a></li>
|
||||
<li><a href="https://doc.wallabag.org/en/developer/docker.html">{{ 'quickstart.developer.use_docker'|trans }}</a></li>
|
||||
<li><a href="https://doc.wallabag.org/">{{ 'quickstart.more'|trans }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Wallabag\Command\Import;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Tests\Wallabag\WallabagTestCase;
|
||||
use Wallabag\Entity\Entry;
|
||||
|
||||
class UrlCommandTest extends WallabagTestCase
|
||||
{
|
||||
private $url = 'https://www.20minutes.fr/sport/football/4158082-20250612-euro-espoirs-su-souffrir-ensemble-decimes-bleuets-retiennent-positif-apres-nul-face-portugal';
|
||||
|
||||
public function testRunUrlCommandWithoutArguments()
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage('Not enough arguments');
|
||||
|
||||
$application = new Application($this->getTestClient()->getKernel());
|
||||
|
||||
$command = $application->find('wallabag:import:url');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute([]);
|
||||
}
|
||||
|
||||
public function testRunUrlCommandWithWrongUsername()
|
||||
{
|
||||
$this->expectException(NoResultException::class);
|
||||
|
||||
$application = new Application($this->getTestClient()->getKernel());
|
||||
|
||||
$command = $application->find('wallabag:import:url');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute([
|
||||
'username' => 'random',
|
||||
'url' => $this->url,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testRunUrlCommand()
|
||||
{
|
||||
$application = new Application($this->getTestClient()->getKernel());
|
||||
|
||||
$command = $application->find('wallabag:import:url');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute([
|
||||
'username' => 'admin',
|
||||
'url' => $this->url,
|
||||
]);
|
||||
|
||||
$this->assertStringContainsString('successfully imported', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunUrlCommandWithTags()
|
||||
{
|
||||
$application = new Application($this->getTestClient()->getKernel());
|
||||
|
||||
$command = $application->find('wallabag:import:url');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute([
|
||||
'username' => 'admin',
|
||||
'url' => $this->url,
|
||||
'tags' => 'sport, football',
|
||||
]);
|
||||
|
||||
$this->assertStringContainsString('successfully imported', $tester->getDisplay());
|
||||
|
||||
$client = $this->getTestClient();
|
||||
$em = $client->getContainer()->get(EntityManagerInterface::class);
|
||||
$entry = $em->getRepository(Entry::class)->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
|
||||
$this->assertContains('football', $entry->getTagsLabel());
|
||||
$this->assertNotContains('basketball', $entry->getTagsLabel());
|
||||
}
|
||||
|
||||
public function testRunUrlCommandWithUserId()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
|
||||
$application = new Application($this->getTestClient()->getKernel());
|
||||
|
||||
$command = $application->find('wallabag:import:url');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute([
|
||||
'username' => $this->getLoggedInUserId(),
|
||||
'url' => $this->url,
|
||||
'--useUserId' => true,
|
||||
]);
|
||||
|
||||
$this->assertStringContainsString('successfully imported', $tester->getDisplay());
|
||||
}
|
||||
}
|
||||
@ -227,7 +227,6 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
'public' => 0,
|
||||
'notParsed' => 0,
|
||||
'http_status' => 200,
|
||||
'annotations' => 1,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
|
||||
@ -255,7 +254,6 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
$this->assertStringContainsString('tags=foo', $content['_links'][$link]['href']);
|
||||
$this->assertStringContainsString('since=1443274283', $content['_links'][$link]['href']);
|
||||
$this->assertStringContainsString('public=0', $content['_links'][$link]['href']);
|
||||
$this->assertStringContainsString('annotations=1', $content['_links'][$link]['href']);
|
||||
}
|
||||
|
||||
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
|
||||
@ -307,86 +305,6 @@ class EntryRestControllerTest extends WallabagApiTestCase
|
||||
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
|
||||
}
|
||||
|
||||
public function testGetEntriesWithAnnotationsFilter()
|
||||
{
|
||||
// Test filter for entries WITH annotations
|
||||
// From fixtures: entry1 and entry2 have annotations, entry4, entry5, entry6, entry7 don't
|
||||
$this->client->request('GET', '/api/entries', [
|
||||
'annotations' => 1,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
|
||||
|
||||
$content = json_decode($this->client->getResponse()->getContent(), true);
|
||||
|
||||
$this->assertArrayHasKey('items', $content['_embedded']);
|
||||
|
||||
// Check that only entries with annotations are returned
|
||||
$entriesWithAnnotations = ['http://0.0.0.0/entry1', 'http://0.0.0.0/entry2'];
|
||||
$entriesWithoutAnnotations = ['http://0.0.0.0/entry4', 'http://0.0.0.0/entry5', 'http://0.0.0.0/entry6', 'http://0.0.0.0/entry7'];
|
||||
|
||||
foreach ($content['_embedded']['items'] as $item) {
|
||||
if (\in_array($item['url'], $entriesWithAnnotations, true)) {
|
||||
$this->assertNotEmpty($item['annotations'], 'Entry with URL ' . $item['url'] . ' should have annotations');
|
||||
}
|
||||
$this->assertNotContains($item['url'], $entriesWithoutAnnotations, 'Entry without annotations should NOT be in the results');
|
||||
}
|
||||
|
||||
// Ensure we have at least the entries with annotations
|
||||
$foundUrls = array_column($content['_embedded']['items'], 'url');
|
||||
$this->assertContains('http://0.0.0.0/entry1', $foundUrls, 'entry1 with annotations should be in the results');
|
||||
$this->assertContains('http://0.0.0.0/entry2', $foundUrls, 'entry2 with annotations should be in the results');
|
||||
|
||||
// Check pagination links contain the filter
|
||||
$this->assertArrayHasKey('_links', $content);
|
||||
foreach (['self', 'first', 'last'] as $link) {
|
||||
$this->assertArrayHasKey('href', $content['_links'][$link]);
|
||||
$this->assertStringContainsString('annotations=1', $content['_links'][$link]['href']);
|
||||
}
|
||||
|
||||
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
|
||||
}
|
||||
|
||||
public function testGetEntriesWithoutAnnotationsFilter()
|
||||
{
|
||||
// Test filter for entries WITHOUT annotations
|
||||
// From fixtures: entry1 and entry2 have annotations, entry4, entry5, entry6, entry7 don't
|
||||
$this->client->request('GET', '/api/entries', [
|
||||
'annotations' => 0,
|
||||
]);
|
||||
|
||||
$this->assertSame(200, $this->client->getResponse()->getStatusCode());
|
||||
|
||||
$content = json_decode($this->client->getResponse()->getContent(), true);
|
||||
|
||||
$this->assertArrayHasKey('items', $content['_embedded']);
|
||||
|
||||
// Check that only entries without annotations are returned
|
||||
$entriesWithAnnotations = ['http://0.0.0.0/entry1', 'http://0.0.0.0/entry2'];
|
||||
$entriesWithoutAnnotations = ['http://0.0.0.0/entry4', 'http://0.0.0.0/entry5', 'http://0.0.0.0/entry6', 'http://0.0.0.0/entry7'];
|
||||
|
||||
foreach ($content['_embedded']['items'] as $item) {
|
||||
$this->assertNotContains($item['url'], $entriesWithAnnotations, 'Entry with annotations should NOT be in the results');
|
||||
if (\in_array($item['url'], $entriesWithoutAnnotations, true)) {
|
||||
$this->assertEmpty($item['annotations'], 'Entry with URL ' . $item['url'] . ' should not have annotations');
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have at least some entries without annotations
|
||||
$foundUrls = array_column($content['_embedded']['items'], 'url');
|
||||
$foundWithoutAnnotations = array_intersect($foundUrls, $entriesWithoutAnnotations);
|
||||
$this->assertNotEmpty($foundWithoutAnnotations, 'Should have at least one entry without annotations in the results');
|
||||
|
||||
// Check pagination links contain the filter
|
||||
$this->assertArrayHasKey('_links', $content);
|
||||
foreach (['self', 'first', 'last'] as $link) {
|
||||
$this->assertArrayHasKey('href', $content['_links'][$link]);
|
||||
$this->assertStringContainsString('annotations=0', $content['_links'][$link]['href']);
|
||||
}
|
||||
|
||||
$this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
|
||||
}
|
||||
|
||||
public function testGetEntriesOnPageTwo()
|
||||
{
|
||||
$this->client->request('GET', '/api/entries', [
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
namespace Tests\Wallabag\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Google\GoogleAuthenticatorInterface;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
@ -1224,74 +1223,27 @@ class ConfigControllerTest extends WallabagTestCase
|
||||
|
||||
public function testUserEnable2faGoogle()
|
||||
{
|
||||
$googleAuthenticatorMock = $this->createMock(GoogleAuthenticatorInterface::class);
|
||||
$googleAuthenticatorMock
|
||||
->method('generateSecret')
|
||||
->willReturn('DUMMYSECRET');
|
||||
$googleAuthenticatorMock
|
||||
->method('checkCode')
|
||||
->willReturnCallback(function ($user, $code) {
|
||||
return '123456' === $code;
|
||||
});
|
||||
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->disableReboot(); // Disable reboot to keep the mock in the container
|
||||
|
||||
// name::class notation does not work in this context
|
||||
self::getContainer()->set('scheb_two_factor.security.google_authenticator', $googleAuthenticatorMock);
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$form = $crawler->filter('form[name=config_otp_app]')->form();
|
||||
$crawler = $client->submit($form);
|
||||
$client->submit($form);
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$secret = $crawler->filter('div#config_otp_app_secret pre code')->innerText();
|
||||
$this->assertSame('DUMMYSECRET', $secret);
|
||||
|
||||
$em = $this->getEntityManager();
|
||||
$user = $em
|
||||
->getRepository(User::class)
|
||||
->findOneByUsername('admin');
|
||||
// At this phase, the user should not have 2FA enabled
|
||||
$this->assertFalse($user->isGoogleTwoFactor());
|
||||
|
||||
// First test: send invalid OTP code
|
||||
$form = $crawler->filter('form[name=config_otp_app_check]')->form();
|
||||
$data = [
|
||||
'_auth_code' => '000000',
|
||||
];
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(307, $client->getResponse()->getStatusCode());
|
||||
$this->assertStringContainsString('flashes.config.notice.otp_code_invalid', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]);
|
||||
|
||||
// Follow the redirect to the OTP check form again
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
// Second test: send valid OTP code
|
||||
$form = $crawler->filter('form[name=config_otp_app_check]')->form();
|
||||
$data = [
|
||||
'_auth_code' => '123456',
|
||||
];
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
$this->assertStringContainsString('flashes.config.notice.otp_enabled', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]);
|
||||
|
||||
// restore user
|
||||
$em = $this->getEntityManager();
|
||||
$user = $em
|
||||
->getRepository(User::class)
|
||||
->findOneByUsername('admin');
|
||||
|
||||
$this->assertTrue($user->isGoogleTwoFactor());
|
||||
$this->assertGreaterThan(0, \count($user->getBackupCodes()));
|
||||
$this->assertGreaterThan(0, $user->getBackupCodes());
|
||||
|
||||
// Restore user
|
||||
$user->setGoogleAuthenticatorSecret('');
|
||||
$user->setGoogleAuthenticator(false);
|
||||
$user->setBackupCodes([]);
|
||||
$user->setGoogleAuthenticatorSecret(false);
|
||||
$user->setBackupCodes(null);
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
}
|
||||
@ -1307,7 +1259,6 @@ class ConfigControllerTest extends WallabagTestCase
|
||||
->findOneByUsername('admin');
|
||||
|
||||
$user->setGoogleAuthenticatorSecret('Google2FA');
|
||||
$user->setGoogleAuthenticator(true);
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
@ -1320,6 +1271,7 @@ class ConfigControllerTest extends WallabagTestCase
|
||||
|
||||
$this->assertStringContainsString('flashes.config.notice.otp_disabled', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->get('notice')[0]);
|
||||
|
||||
// restore user
|
||||
$em = $this->getEntityManager();
|
||||
$user = $em
|
||||
->getRepository(User::class)
|
||||
@ -1327,7 +1279,6 @@ class ConfigControllerTest extends WallabagTestCase
|
||||
|
||||
$this->assertEmpty($user->getGoogleAuthenticatorSecret());
|
||||
$this->assertEmpty($user->getBackupCodes());
|
||||
$this->assertFalse($user->isGoogleTwoFactor());
|
||||
}
|
||||
|
||||
public function testExportTaggingRule()
|
||||
|
||||
@ -91,7 +91,7 @@ class ChromeControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithChromeFile()
|
||||
public function testImportChromeWithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -132,7 +132,7 @@ class ChromeControllerTest extends WallabagTestCase
|
||||
$this->assertSame('07', $createdAt->format('m'));
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportChromeWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -155,4 +155,17 @@ class ChromeControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportChromeDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('chrome_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/chrome');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('chrome_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,4 +200,17 @@ class DeliciousControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportDeliciousDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('delicious_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/delicious');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('delicious_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,4 +133,17 @@ class ElcuratorControllerTest extends WallabagTestCase
|
||||
$this->assertContains('tag1', $tags, 'It includes the "tag1" tag');
|
||||
$this->assertContains('tag2', $tags, 'It includes the "tag2" tag');
|
||||
}
|
||||
|
||||
public function testImportElcuratorDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('elcurator_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/elcurator');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('elcurator_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ class FirefoxControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithFirefoxFile()
|
||||
public function testImportFirefoxWithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -129,7 +129,7 @@ class FirefoxControllerTest extends WallabagTestCase
|
||||
$this->assertCount(3, $content->getTags());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportFirefoxWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -152,4 +152,17 @@ class FirefoxControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportFirefoxDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('firefox_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/firefox');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('firefox_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,6 @@ class ImportControllerTest extends WallabagTestCase
|
||||
|
||||
$crawler = $client->request('GET', '/import/');
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(14, $crawler->filter('.card-title')->count());
|
||||
$this->assertSame(13, $crawler->filter('.card-title')->count());
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,4 +213,17 @@ class InstapaperControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportInstapaperDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('instapaper_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/instapaper');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('instapaper_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,4 +200,17 @@ class OmnivoreControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportOmnivoreDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('omnivore_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/omnivore');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('omnivore_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,4 +207,17 @@ class PinboardControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportPinboardDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('pinboard_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/pinboard');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('pinboard_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,6 +75,11 @@ class PocketControllerTest extends WallabagTestCase
|
||||
->method('getRequestToken')
|
||||
->willReturn('token');
|
||||
|
||||
$pocketImport
|
||||
->expects($this->once())
|
||||
->method('isEnabled')
|
||||
->willReturn(true);
|
||||
|
||||
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
|
||||
|
||||
$client->request('POST', '/import/pocket/auth');
|
||||
@ -97,6 +102,11 @@ class PocketControllerTest extends WallabagTestCase
|
||||
->method('authorize')
|
||||
->willReturn(false);
|
||||
|
||||
$pocketImport
|
||||
->expects($this->once())
|
||||
->method('isEnabled')
|
||||
->willReturn(true);
|
||||
|
||||
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
|
||||
|
||||
$client->request('GET', '/import/pocket/callback');
|
||||
@ -131,6 +141,11 @@ class PocketControllerTest extends WallabagTestCase
|
||||
->method('import')
|
||||
->willReturn(true);
|
||||
|
||||
$pocketImport
|
||||
->expects($this->once())
|
||||
->method('isEnabled')
|
||||
->willReturn(true);
|
||||
|
||||
static::$kernel->getContainer()->set(PocketImport::class, $pocketImport);
|
||||
|
||||
$client->request('GET', '/import/pocket/callback');
|
||||
@ -139,4 +154,17 @@ class PocketControllerTest extends WallabagTestCase
|
||||
$this->assertStringContainsString('/', $client->getResponse()->headers->get('location'), 'Import is ok, redirect to homepage');
|
||||
$this->assertSame('flashes.import.notice.summary', $client->getContainer()->get(SessionInterface::class)->getFlashBag()->peek('notice')[0]);
|
||||
}
|
||||
|
||||
public function testImportPocketDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('pocket_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/pocket');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('pocket_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,168 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Wallabag\Controller\Import;
|
||||
|
||||
use Craue\ConfigBundle\Util\Config;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Predis\Client;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Tests\Wallabag\WallabagTestCase;
|
||||
use Wallabag\Entity\Entry;
|
||||
|
||||
class PocketCsvControllerTest extends WallabagTestCase
|
||||
{
|
||||
public function testImportPocketCsv()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
}
|
||||
|
||||
public function testImportPocketCsvWithRabbitEnabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
|
||||
}
|
||||
|
||||
public function testImportPocketCsvBadFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => '',
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testImportPocketCsvWithRedisEnabled()
|
||||
{
|
||||
$this->checkRedis();
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 1);
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertSame(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/pocket.csv', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$this->assertNotEmpty($client->getContainer()->get(Client::class)->lpop('wallabag.import.pocket_csv'));
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithPocketCsvFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/pocket.csv', 'Bookmarks');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
|
||||
$entries = $client->getContainer()
|
||||
->get(EntityManagerInterface::class)
|
||||
->getRepository(Entry::class)
|
||||
->findBy(['user' => $this->getLoggedInUserId()]);
|
||||
|
||||
$expectedEntries = [
|
||||
'http://youmightnotneedjquery.com/,1600322788',
|
||||
'https://jp-lambert.me/est-ce-que-jai-besoin-d-un-scrum-master-604f5a471c73',
|
||||
'https://www.monde-diplomatique.fr/2020/09/HALIMI/62165',
|
||||
'https://www.reddit.com/r/DataHoarder/comments/ioupbk/archivebox_question_how_do_i_import_links_from_a/',
|
||||
'https://www.numerama.com/politique/646826-tu-vas-pleurer-les-premieres-fois-que-se-passe-t-il-au-sein-du-studio-dubisoft-derriere-trackmania.html#utm_medium=distibuted&utm_source=rss&utm_campaign=646826',
|
||||
'https://www.nouvelobs.com/rue89/20200911.OBS33165/comment-konbini-s-est-fait-pieger-par-un-pere-masculiniste.html',
|
||||
'https://reporterre.net/Des-abeilles-pour-resoudre-les-conflits-entre-les-humains-et-les-elephants',
|
||||
];
|
||||
|
||||
$matchedEntries = array_map(function ($expectedUrl) use ($entries) {
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry->getUrl() === $expectedUrl) {
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}, $expectedEntries);
|
||||
|
||||
$this->assertCount(\count($expectedEntries), $matchedEntries, 'Should have 7 entries imported from pocket.csv');
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
|
||||
$crawler = $client->request('GET', '/import/pocket_csv');
|
||||
$form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
|
||||
|
||||
$file = new UploadedFile(__DIR__ . '/../../fixtures/Import/test.csv', 'test.csv');
|
||||
|
||||
$data = [
|
||||
'upload_import_file[file]' => $file,
|
||||
];
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertSame(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,7 @@ class PocketHtmlControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithPocketHtmlFile()
|
||||
public function testImportPocketHtmlWithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -129,7 +129,7 @@ class PocketHtmlControllerTest extends WallabagTestCase
|
||||
$this->assertCount(3, $content->getTags());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportPocketHtmlWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -152,4 +152,17 @@ class PocketHtmlControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportPocketHtmlDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('pocket_html_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/pocket_html');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('pocket_html_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,4 +205,17 @@ class ReadabilityControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportReadabilityDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('readability_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/readability');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('readability_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ class ShaarliControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithShaarliFile()
|
||||
public function testImportShaarliWithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -129,7 +129,7 @@ class ShaarliControllerTest extends WallabagTestCase
|
||||
$this->assertCount(2, $content->getTags());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportShaarliWithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -152,4 +152,17 @@ class ShaarliControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportShaarliDisabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('shaarli_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/shaarli');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('shaarli_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ use Wallabag\Entity\Entry;
|
||||
|
||||
class WallabagV1ControllerTest extends WallabagTestCase
|
||||
{
|
||||
public function testImportWallabag()
|
||||
public function testImportWallabagV1()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -23,7 +23,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithRabbitEnabled()
|
||||
public function testImportWallabagV1WithRabbitEnabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -39,7 +39,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagBadFile()
|
||||
public function testImportWallabagV1BadFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -56,7 +56,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithRedisEnabled()
|
||||
public function testImportWallabagV1WithRedisEnabled()
|
||||
{
|
||||
$this->checkRedis();
|
||||
$this->logInAs('admin');
|
||||
@ -92,7 +92,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithFile()
|
||||
public function testImportWallabagV1WithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -136,7 +136,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$this->assertInstanceOf(\DateTime::class, $content->getCreatedAt());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithFileAndMarkAllAsRead()
|
||||
public function testImportWallabagV1WithFileAndMarkAllAsRead()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -183,7 +183,7 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$this->assertStringContainsString('flashes.import.notice.summary', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportWallabagV1WithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -206,4 +206,17 @@ class WallabagV1ControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportWallabagV1Disabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('wallabag_v1_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/wallabag_v1');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('wallabag_v1_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ use Wallabag\Entity\Entry;
|
||||
|
||||
class WallabagV2ControllerTest extends WallabagTestCase
|
||||
{
|
||||
public function testImportWallabag()
|
||||
public function testImportWallabagV2()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -23,7 +23,7 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$this->assertSame(1, $crawler->filter('input[type=file]')->count());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithRabbitEnabled()
|
||||
public function testImportWallabagV2WithRabbitEnabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -39,7 +39,7 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_rabbitmq', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagBadFile()
|
||||
public function testImportWallabagV2BadFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -56,7 +56,7 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
}
|
||||
|
||||
public function testImportWallabagWithRedisEnabled()
|
||||
public function testImportWallabagV2WithRedisEnabled()
|
||||
{
|
||||
$this->checkRedis();
|
||||
$this->logInAs('admin');
|
||||
@ -92,7 +92,7 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$client->getContainer()->get(Config::class)->set('import_with_redis', 0);
|
||||
}
|
||||
|
||||
public function testImportWallabagWithFile()
|
||||
public function testImportWallabagV2WithFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -158,7 +158,7 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$this->assertTrue($content->isStarred(), 'Entry is starred');
|
||||
}
|
||||
|
||||
public function testImportWallabagWithEmptyFile()
|
||||
public function testImportWallabagV2WithEmptyFile()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
@ -181,4 +181,17 @@ class WallabagV2ControllerTest extends WallabagTestCase
|
||||
$this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
|
||||
$this->assertStringContainsString('flashes.import.notice.failed', $body[0]);
|
||||
}
|
||||
|
||||
public function testImportWallabagV2Disabled()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getTestClient();
|
||||
$client->getContainer()->get(Config::class)->set('wallabag_v2_enabled', 0);
|
||||
|
||||
$client->request('GET', '/import/wallabag_v2');
|
||||
|
||||
$this->assertSame(404, $client->getResponse()->getStatusCode());
|
||||
|
||||
$client->getContainer()->get(Config::class)->set('wallabag_v2_enabled', 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,6 @@ class SecurityControllerTest extends WallabagTestCase
|
||||
->getRepository(User::class)
|
||||
->findOneByUsername('admin');
|
||||
$user->setGoogleAuthenticatorSecret('26LDIHYGHNELOQEM');
|
||||
$user->setGoogleAuthenticator(true);
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
@ -79,7 +78,6 @@ class SecurityControllerTest extends WallabagTestCase
|
||||
->getRepository(User::class)
|
||||
->findOneByUsername('admin');
|
||||
$user->setGoogleAuthenticatorSecret(null);
|
||||
$user->setGoogleAuthenticator(false);
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
@ -1,252 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Wallabag\Import;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use M6Web\Component\RedisMock\RedisMockFactory;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Predis\Client;
|
||||
use Simpleue\Queue\RedisQueue;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Wallabag\Entity\Entry;
|
||||
use Wallabag\Entity\User;
|
||||
use Wallabag\Helper\ContentProxy;
|
||||
use Wallabag\Helper\TagsAssigner;
|
||||
use Wallabag\Import\PocketCsvImport;
|
||||
use Wallabag\Redis\Producer;
|
||||
use Wallabag\Repository\EntryRepository;
|
||||
|
||||
class PocketCsvImportTest extends TestCase
|
||||
{
|
||||
protected $user;
|
||||
protected $em;
|
||||
protected $logHandler;
|
||||
protected $contentProxy;
|
||||
protected $tagsAssigner;
|
||||
|
||||
public function testInit()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport();
|
||||
|
||||
$this->assertSame('Pocket CSV', $pocketCsvImport->getName());
|
||||
$this->assertNotEmpty($pocketCsvImport->getUrl());
|
||||
$this->assertSame('import.pocket_csv.description', $pocketCsvImport->getDescription());
|
||||
}
|
||||
|
||||
public function testImport()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport(false, 7);
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/pocket.csv');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(7))
|
||||
->method('findByUrlAndUserId')
|
||||
->willReturn(false);
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(7))
|
||||
->method('updateEntry')
|
||||
->willReturn($entry);
|
||||
|
||||
$res = $pocketCsvImport->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 7, 'queued' => 0], $pocketCsvImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportAndMarkAllAsRead()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport(false, 1);
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/pocket.csv');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->exactly(7))
|
||||
->method('findByUrlAndUserId')
|
||||
->will($this->onConsecutiveCalls(false, true));
|
||||
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('getRepository')
|
||||
->willReturn($entryRepo);
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->exactly(1))
|
||||
->method('updateEntry')
|
||||
->willReturn(new Entry($this->user));
|
||||
|
||||
// check that every entry persisted are archived
|
||||
$this->em
|
||||
->expects($this->any())
|
||||
->method('persist')
|
||||
->with($this->callback(fn ($persistedEntry) => (bool) $persistedEntry->isArchived()));
|
||||
|
||||
$res = $pocketCsvImport
|
||||
->setMarkAsRead(true)
|
||||
->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
|
||||
$this->assertSame(['skipped' => 6, 'imported' => 1, 'queued' => 0], $pocketCsvImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRabbit()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport();
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/pocket.csv');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$producer = $this->getMockBuilder(\OldSound\RabbitMqBundle\RabbitMq\Producer::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$producer
|
||||
->expects($this->exactly(7))
|
||||
->method('publish');
|
||||
|
||||
$pocketCsvImport->setProducer($producer);
|
||||
|
||||
$res = $pocketCsvImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 7], $pocketCsvImport->getSummary());
|
||||
}
|
||||
|
||||
public function testImportWithRedis()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport();
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/pocket.csv');
|
||||
|
||||
$entryRepo = $this->getMockBuilder(EntryRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$entryRepo->expects($this->never())
|
||||
->method('findByUrlAndUserId');
|
||||
|
||||
$this->em
|
||||
->expects($this->never())
|
||||
->method('getRepository');
|
||||
|
||||
$entry = $this->getMockBuilder(Entry::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy
|
||||
->expects($this->never())
|
||||
->method('updateEntry');
|
||||
|
||||
$factory = new RedisMockFactory();
|
||||
$redisMock = $factory->getAdapter(Client::class, true);
|
||||
|
||||
$queue = new RedisQueue($redisMock, 'pocket_csv');
|
||||
$producer = new Producer($queue);
|
||||
|
||||
$pocketCsvImport->setProducer($producer);
|
||||
|
||||
$res = $pocketCsvImport->setMarkAsRead(true)->import();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertSame(['skipped' => 0, 'imported' => 0, 'queued' => 7], $pocketCsvImport->getSummary());
|
||||
|
||||
$this->assertNotEmpty($redisMock->lpop('pocket_csv'));
|
||||
}
|
||||
|
||||
public function testImportBadFile()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport();
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/wallabag-v1.jsonx');
|
||||
|
||||
$res = $pocketCsvImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Pocket CSV Import: unable to read file', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
public function testImportUserNotDefined()
|
||||
{
|
||||
$pocketCsvImport = $this->getPocketCsvImport(true);
|
||||
$pocketCsvImport->setFilepath(__DIR__ . '/../fixtures/Import/pocket.csv');
|
||||
|
||||
$res = $pocketCsvImport->import();
|
||||
|
||||
$this->assertFalse($res);
|
||||
|
||||
$records = $this->logHandler->getRecords();
|
||||
$this->assertStringContainsString('Pocket CSV Import: user is not defined', $records[0]['message']);
|
||||
$this->assertSame('ERROR', $records[0]['level_name']);
|
||||
}
|
||||
|
||||
private function getPocketCsvImport($unsetUser = false, $dispatched = 0)
|
||||
{
|
||||
$this->user = new User();
|
||||
|
||||
$this->em = $this->getMockBuilder(EntityManager::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->contentProxy = $this->getMockBuilder(ContentProxy::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->tagsAssigner = $this->getMockBuilder(TagsAssigner::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher = $this->getMockBuilder(EventDispatcher::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dispatcher
|
||||
->expects($this->exactly($dispatched))
|
||||
->method('dispatch');
|
||||
|
||||
$this->logHandler = new TestHandler();
|
||||
$logger = new Logger('test', [$this->logHandler]);
|
||||
|
||||
$wallabag = new PocketCsvImport($this->em, $this->contentProxy, $this->tagsAssigner, $dispatcher, $logger);
|
||||
|
||||
if (false === $unsetUser) {
|
||||
$wallabag->setUser($this->user);
|
||||
}
|
||||
|
||||
return $wallabag;
|
||||
}
|
||||
}
|
||||
10
tests/fixtures/Import/pocket.csv
vendored
10
tests/fixtures/Import/pocket.csv
vendored
@ -1,10 +0,0 @@
|
||||
title,url,time_added,tags,status
|
||||
You Might Not Need jQuery,http://youmightnotneedjquery.com/,1600322788,,unread
|
||||
Est-ce que j’ai besoin d’un Scrum Master ? | by Jean-Pierre Lambert | Jean-,https://jp-lambert.me/est-ce-que-jai-besoin-d-un-scrum-master-604f5a471c73,1600172739,,unread
|
||||
"Avec les accusés d’El Halia, par Gisèle Halimi (Le Monde diplomatique, sept",https://www.monde-diplomatique.fr/2020/09/HALIMI/62165,1599806347,,unread
|
||||
ArchiveBox question: How do I import links from a RSS feed?,https://www.reddit.com/r/DataHoarder/comments/ioupbk/archivebox_question_how_do_i_import_links_from_a/,1600961496,,archive
|
||||
« Tu vas pleurer les premières fois » : que se passe-t-il au sein du studio,https://www.numerama.com/politique/646826-tu-vas-pleurer-les-premieres-fois-que-se-passe-t-il-au-sein-du-studio-dubisoft-derriere-trackmania.html#utm_medium=distibuted&utm_source=rss&utm_campaign=646826,1599809025,,unread
|
||||
Comment Konbini s’est fait piéger par un « père masculiniste »,https://www.nouvelobs.com/rue89/20200911.OBS33165/comment-konbini-s-est-fait-pieger-par-un-pere-masculiniste.html,1599819251,,archive
|
||||
"Des abeilles pour résoudre les « conflits » entre les humains
|
||||
|
||||
et les élépha",https://reporterre.net/Des-abeilles-pour-resoudre-les-conflits-entre-les-humains-et-les-elephants,1599890673,,unread
|
||||
|
2
tests/fixtures/Import/ril_export.html
vendored
2
tests/fixtures/Import/ril_export.html
vendored
@ -9,7 +9,7 @@
|
||||
<h1>Unread</h1>
|
||||
<ul>
|
||||
<li><a href="https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule" time_added="1688628695" tags="ifttt,new_entry_simple">Tarn : Des lapins ravagent le terrain, le match de rugby doit être annulé</a></li>
|
||||
<li><a href="https://www.20minutes.fr/paris/4100740-20240715-jo-paris-2024-courir-capitale-maintenant-quais-fermes" time_added="1688627412" tags="ifttt,new_entry_simple">JO Paris 2024 : Où courir dans la capitale maintenant que les quais sont fermés ?</a></li>
|
||||
<li><a href="https://www.20minutes.fr/paris/4100740-20240715-jo-paris-2024-courir-capitale-maintenant-quais-fermes" time_added="1688627412" tags="ifttt,new_entry_simple">JO Paris 2024 : Où courir dans la capitale maintenant que les quais sont fermés ?</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
2
tests/fixtures/Import/shaarli-bookmarks.html
vendored
2
tests/fixtures/Import/shaarli-bookmarks.html
vendored
@ -8,6 +8,6 @@
|
||||
<DL><p>
|
||||
<DT><A HREF="https://www.20minutes.fr/sport/4002755-20220928-tarn-lapins-ravagent-terrain-match-rugby-doit-etre-annule" ADD_DATE="1686813518" LAST_MODIFIED="1686813519" PRIVATE="0" TAGS="firefoxos">The Legacy of Firefox OS. In the two years or so since Mozilla… | by Ben Francis | Medium</A>
|
||||
<DD>In the two years or so since Mozilla announced the end of Firefox OS as a Mozilla-run project, the B2G source code has found its way into a surprising number of commercial products.
|
||||
<DT><A HREF="https://www.20minutes.fr/paris/4100740-20240715-jo-paris-2024-courir-capitale-maintenant-quais-fermes" ADD_DATE="1683376565" LAST_MODIFIED="1686813519" PRIVATE="0" TAGS="firefoxos">JO Paris 2024 : Où courir dans la capitale maintenant que les quais sont fermés ?</A>
|
||||
<DT><A HREF="https://www.20minutes.fr/paris/4100740-20240715-jo-paris-2024-courir-capitale-maintenant-quais-fermes" ADD_DATE="1683376565" LAST_MODIFIED="1683376571" PRIVATE="0" TAGS="eleventy,this,javascript,filter,data">Template Filters — Eleventy</A>
|
||||
</DL><p>
|
||||
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
|
||||
|
||||
0
tests/fixtures/Import/test.csv
vendored
0
tests/fixtures/Import/test.csv
vendored
|
|
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -5,7 +5,7 @@ restricted_access: Schakel authenticatie voor betaalde websites in
|
||||
download_images_enabled: Download afbeelding lokaal
|
||||
matomo_enabled: Schakel Matomo in
|
||||
matomo_site_id: ID van uw Matomo website
|
||||
matomo_host: Adres van jouw Matomo website (zonder http:// of https://)
|
||||
matomo_host: Adres van uw Matomo website (zonder http:// of https://)
|
||||
modify_settings: bevestig
|
||||
misc: overig
|
||||
import: importeer
|
||||
@ -32,5 +32,4 @@ export_epub: Schakel ePub-export in
|
||||
download_pictures: Download foto's naar jouw server
|
||||
settings_changed: Instellingen bijgewerkt
|
||||
diaspora_url: diaspora* URL, als de dienst is aangezet
|
||||
share_public: Sta openbare URL's toe voor artikelen
|
||||
share_linkding: Sta delen met Linkding toe
|
||||
share_public: Sta openbare URL's toe voor items
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
settings_changed: Ustawienia zostały zaktualizowane
|
||||
settings_changed: Ustawienia zostały zaktualizowana
|
||||
download_pictures: Pobierz obrazy na swój serwer
|
||||
diaspora_url: Adres URL Diaspora, jeżeli ta usługa jest włączona
|
||||
export_epub: Włącz eksport do ePub
|
||||
|
||||
@ -558,15 +558,11 @@ import:
|
||||
pocket_html:
|
||||
how_to: Zvolte soubor zálohy záložek a kliknutím na níže uvedené tlačítko jej naimportujte. Pamatujte na to, že tento proces může trvat dlouho, protože je třeba načíst všechny články.
|
||||
page_title: Import > Pocket HTML
|
||||
description: Tento importér naimportuje všechny vaše záložky z Pocketu (prostřednictvím HTML exportu). Stačí přejít na https://getpocket.com/export a exportovat soubor HTML, který bude stažen (například „ril_export.html“).
|
||||
description: Tento importér naimportuje všechny vaše záložky z Pocket. Stačí přejít na https://getpocket.com/export) a exportovat soubor HTML, který bude stažen (například „ril_export.html“).
|
||||
omnivore:
|
||||
how_to: Rozbalte prosím svůj export z Omnivoru, následně nahrajte jeden po druhém všechny JSON soubory s názevem "metadata_x_to_y.json".
|
||||
page_title: Import > Omnivore
|
||||
description: Tento importér naimportuje všechny vaše články z Omnivore.
|
||||
pocket_csv:
|
||||
page_title: Import > Pocket CSV
|
||||
description: Tento importér naimportuje všechny vaše záložky z Pocketu (prostřednictvím CSV exportu). Stačí přejít na https://getpocket.com/export a exportovat soubor. Stáhne se ZIP soubor (např. „pocket.zip“). Po rozbalení získáte CSV soubor, nazvaný „part_000000.csv“.
|
||||
how_to: Zvolte soubor zálohy záložek a kliknutím na níže uvedené tlačítko jej naimportujte. Pamatujte na to, že tento proces může trvat dlouho, protože je třeba načíst všechny články.
|
||||
flashes:
|
||||
config:
|
||||
notice:
|
||||
@ -589,7 +585,6 @@ flashes:
|
||||
user_updated: Informace byla aktualizována
|
||||
config_saved: Konfigurace byla uložena.
|
||||
tagging_rules_reset: Pravidla štítkování byla obnovena
|
||||
otp_code_invalid: Neplatný dvoufaktorový autentizační kód
|
||||
ignore_origin_instance_rule:
|
||||
notice:
|
||||
deleted: Globální pravidlo ignorování bylo odstraněno
|
||||
|
||||
@ -237,16 +237,6 @@ entry:
|
||||
untagged: Untagged entries
|
||||
all: All entries
|
||||
same_domain: Same domain
|
||||
sort:
|
||||
status_label: Sort by
|
||||
order_label: Order
|
||||
by:
|
||||
creation_date: Creation date
|
||||
title: Title
|
||||
url: URL
|
||||
reading_time: Reading time
|
||||
ascending: Ascending
|
||||
descending: Descending
|
||||
list:
|
||||
number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
|
||||
reading_time: estimated reading time
|
||||
@ -563,10 +553,6 @@ import:
|
||||
page_title: Import > Pocket HTML
|
||||
description: This importer will import all your Pocket bookmarks (via HTML export). Just go to https://getpocket.com/export, then export the HTML file. An HTML file will be downloaded (like "ril_export.html").
|
||||
how_to: Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched.
|
||||
pocket_csv:
|
||||
page_title: Import > Pocket CSV
|
||||
description: This importer will import all your Pocket bookmarks (via CSV export). Just go to https://getpocket.com/export, then export the file. A ZIP file will be downloaded (like "pocket.zip"). Extract it, you will obtain a CSV file, called "part_000000.csv".
|
||||
how_to: Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched.
|
||||
developer:
|
||||
page_title: API clients management
|
||||
welcome_message: Welcome to the wallabag API
|
||||
|
||||
@ -550,10 +550,6 @@ import:
|
||||
page_title: Importer > Pocket HTML
|
||||
description: Cet importateur importera toutes vos signets Pocket (via exportation HTML). Il suffit d'aller à https://getpocket.com/export, puis d'exporter le fichier HTML. Un fichier HTML sera téléchargé (comme « ril_export.html »).
|
||||
how_to: Veuillez choisir le fichier de sauvegarde de signets et cliquez sur le bouton ci-dessous pour l'importer. Pensez au fait que le processus peut prendre longtemps puisque tous les articles doivent être récupérés.
|
||||
pocket_csv:
|
||||
page_title: Importer > Pocket CSV
|
||||
description: Cet importateur importera toutes vos signets Pocket (via exportation CSV). Il suffit d'aller à https://getpocket.com/export, puis d'exporter le fichier. Un fichier ZIP sera téléchargé (comme « pocket.zip »). Décompressez le et vous obtiendrez un fichier CSV appelé "part_000000.csv".
|
||||
how_to: Veuillez choisir le fichier de sauvegarde de signets et cliquez sur le bouton ci-dessous pour l'importer. Pensez au fait que le processus peut prendre longtemps puisque tous les articles doivent être récupérés.
|
||||
omnivore:
|
||||
description: Cet outil va importer tous vos articles depuis Omnivore.
|
||||
page_title: Importer > Omnivore
|
||||
|
||||
@ -485,10 +485,6 @@ import:
|
||||
page_title: Importar > Omnivore
|
||||
how_to: Descomprime a exportación de Omnivore, e despois sube un a un cada ficheiro JSON con nome «metadata_x_to_y.json".
|
||||
description: Este importador vai traer todos os teus artigos de Omnivore.
|
||||
pocket_csv:
|
||||
how_to: Selecciona o ficheiro de copia de apoio dos marcadores e preme no botón inferior para importalo. Ten en conta que o proceso podería demorarse xa que deben procesarse todos os artigos.
|
||||
description: Con este asistente vas importar os teus marcadores desde Pocket (usando a exportación CSV). Só tes que ir a https://getpocket.com/export e exportar un ficheiro. Descargarás un ficheiro ZIP (tipo «pocket.zip»). Extrae o ficheiro CSV que contén, ten nome «part_000000.csv».
|
||||
page_title: Importar > CSV desde Pocket
|
||||
export:
|
||||
unknown: Descoñecido
|
||||
footer_template: <div style="text-align:center;"><p>Creado por wallabag con %method%</p><p>Abre <a href="https://github.com/wallabag/wallabag/issues">unha incidencia</a> se tes problemas para visualizar este E-Book no teu dispositivo.</p></div>
|
||||
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -115,26 +115,6 @@ import:
|
||||
action:
|
||||
import_contents: 콘텐츠 가져오기
|
||||
page_title: 가져오기
|
||||
delicious:
|
||||
how_to: Delicious 내보내기를 선택하고 아래 버튼을 클릭하여 업로드하고 가져오십시오.
|
||||
page_title: 가져오기 > del.icio.us
|
||||
description: '이 가져오기 도구는 모든 Delicious 북마크를 가져옵니다. 2021년부터 내보내기 페이지 (https://del.icio.us/export)를 사용하여 데이터를 다시 내보낼 수 있습니다. "JSON" 형식을 선택하고 다운로드하십시오 (예: "delicious_export.2021.02.06_21.10.json").'
|
||||
shaarli:
|
||||
page_title: 가져오기 > Shaarli
|
||||
description: 이 가져오기 도구는 모든 Shaarli 북마크를 가져옵니다. 도구 섹션으로 이동한 다음 "데이터베이스 내보내기"에서 북마크를 선택하고 내보내십시오. HTML 파일을 얻게 됩니다.
|
||||
how_to: 북마크 백업 파일을 선택하고 아래 버튼을 클릭하여 가져오십시오. 모든 문서를 가져와야하므로 처리 시간이 오래 걸릴 수 있습니다.
|
||||
omnivore:
|
||||
page_title: 가져오기 > Omnivore
|
||||
description: 이 가져오기 도구는 모든 Omnivore 문서를 가져옵니다.
|
||||
how_to: Omnivore 내보내기 압축을 풀고 "metadata_x_to_y.json" 이라는 각 JSON 파일을 하나씩 업로드하십시오.
|
||||
pocket_html:
|
||||
description: '이 가져오기 도구는 모든 Pocket 북마크 (HTML 내보내기 통해)를 가져옵니다. https://getpocket.com/export 로 이동한 다음 HTML 파일을 내보내십시오. HTML 파일이 다운로드됩니다 (예: "ril_export.html").'
|
||||
page_title: 가져오기 > Pocket HTML
|
||||
how_to: 북마크 백업 파일을 선택하고 아래 버튼을 클릭하여 가져오십시오. 모든 문서를 가져와야하므로 처리 시간이 오래 걸릴 수 있습니다.
|
||||
pocket_csv:
|
||||
description: '이 가져오기 도구는 모든 Pocket 북마크 (CSV 내보내기 통해)를 가져옵니다. https://getpocket.com/export 로 이동한 다음 파일을 내보내십시오. ZIP 파일이 다운로드됩니다 (예: "pocket.zip"). 압축을 풀면 "part_000000.csv" 라는 CSV 파일을 얻게 됩니다.'
|
||||
how_to: 북마크 백업 파일을 선택하고 아래 버튼을 클릭하여 가져오십시오. 모든 문서를 가져와야하므로 처리 시간이 오래 걸릴 수 있습니다.
|
||||
page_title: 가져오기 > Pocket CSV
|
||||
about:
|
||||
third_party:
|
||||
description: '다음은 wallabag에 사용되는 타사 라이브러리 목록입니다 (저작권 포함):'
|
||||
@ -219,8 +199,6 @@ entry:
|
||||
starred_label: 즐겨찾기
|
||||
status_label: 상태
|
||||
title: 필터
|
||||
annotated_label: 주석 있음
|
||||
parsed_label: 올바르게 가져오지 못함
|
||||
edit:
|
||||
origin_url_label: 원본 URL (원본 문서의 위치)
|
||||
page_title: 문서 수정
|
||||
@ -241,13 +219,9 @@ entry:
|
||||
filtered_tags: '태그로 필터링:'
|
||||
filtered: 필터링한 기사
|
||||
unread: 읽지않은 기사
|
||||
with_annotations: 주석이 있는 문서
|
||||
same_domain: 동일 도메인
|
||||
confirm:
|
||||
delete_tag: 문서에서 해당 태그를 제거 하시겠습니까?
|
||||
delete: 해당 문서를 제거 하시겠습니까?
|
||||
delete_entries: 이 문서를 제거 하시겠습니까?
|
||||
reload: 해당 문서를 다시 로드 하시겠습니까?
|
||||
public:
|
||||
shared_by_wallabag: 이 문서는 %username% 님이 <a href='%wallabag_instance%'>wallabag</a>와 공유했습니다
|
||||
metadata:
|
||||
@ -264,18 +238,13 @@ entry:
|
||||
toogle_as_read: 읽음으로 전환
|
||||
toogle_as_star: 즐겨찾기 전환
|
||||
original_article: 원본
|
||||
reading_time_less_one_minute_short: '< 1 분'
|
||||
reading_time_less_one_minute_short: '< 1 분'
|
||||
reading_time_minutes_short: '%readingTime% 분'
|
||||
number_of_tags: '{1} 및 1 개의 다른 태그|]1,Inf[및 %count% 다른 태그'
|
||||
reading_time_less_one_minute: '예상 읽기 시간: < 1 분'
|
||||
reading_time_less_one_minute: '예상 읽기 시간: < 1 분'
|
||||
reading_time_minutes: '예상 읽기 시간: %readingTime% 분'
|
||||
reading_time: 예상 읽기 시간
|
||||
number_on_the_page: '{0} 기사가 없습니다.|{1} 기사가 하나 있습니다.|]1,Inf[ %count%개 기사가 있습니다.'
|
||||
assign_search_tag: 이 검색을 각 결과에 태그로 할당
|
||||
show_same_domain: 동일 도메인을 가진 문서 보기
|
||||
toggle_mass_action: 대량 작업 전환
|
||||
mass_action_tags_input_placeholder: 태그1, 태그2, 태그3
|
||||
add_tags: 태그 추가
|
||||
number_on_the_page: '{0} 기사가 없습니다.|{1} 기사가 하나 있습니다.|]1,Inf[ %count % 기사가 있습니다.'
|
||||
default_title: 기사의 제목
|
||||
howto:
|
||||
bookmarklet:
|
||||
@ -314,7 +283,7 @@ howto:
|
||||
via_google_play: 구글 플레이를 통해
|
||||
via_f_droid: F-Droid를 통해
|
||||
windows: 마이크로소프트 스토어에서
|
||||
ios: 앱스토어에서
|
||||
ios: 아이튠즈 스토어에서
|
||||
browser_addons:
|
||||
opera: 오페라 애드온
|
||||
chrome: 크롬 애드온
|
||||
@ -362,7 +331,6 @@ flashes:
|
||||
tagging_rules_deleted: 태그 지정 규칙이 삭제되었습니다
|
||||
tagging_rules_updated: 태그 지정 규칙이 업데이트되었습니다
|
||||
password_updated: 비밀번호가 업데이트 되었습니다
|
||||
otp_code_invalid: 2단계 인증 코드가 유효하지 않습니다
|
||||
ignore_origin_instance_rule:
|
||||
notice:
|
||||
deleted: 전역 원본 무시 규칙이 삭제되었습니다
|
||||
@ -395,7 +363,6 @@ flashes:
|
||||
notice:
|
||||
tag_renamed: 태그 이름이 변경되었습니다
|
||||
tag_added: 태그가 추가되었습니다
|
||||
too_much_tags: 성능 문제 방지를 위해 한 번에 %tags%개 이상의 태그나 %characters%자 이상의 태그를 추가할 수 없습니다.
|
||||
config:
|
||||
form_ignore_origin_rules:
|
||||
faq:
|
||||
@ -429,7 +396,7 @@ config:
|
||||
title: 문서 제목
|
||||
label: 변수
|
||||
tagging_rules_definition_description: wallabag 에서 자동으로 새 문서에 태그를 지정하는 데 사용하는 규칙입니다. <br /> 태그 지정 규칙이 새 문서가 추가 될 때마다 태그를 구성하는 데 사용되므로, 수동으로 분류하는 수고를 덜 수 있습니다.
|
||||
how_to_use_them_description: '읽기 시간이 3 분 미만인 경우 «<i> 짧은 읽기 </i>» 와 같은 새 기사에 태그를 지정한다고 가정합니다. <br />이 경우 <i> 규칙</i> 을 입력해야합니다. <i>태그</i> 필드에 « readingTime <= 3 » 을 입력하고 « <i>짧은 읽기</i>» 를 입력하십시오. <br /> 여러 태그를 쉼표로구분하여 한 번에 추가 할 수 있습니다: « <i> 짧은 읽기, 반드시 읽기</i> » <br /> 사전 정의 된 연산자를 사용하여 복잡한 규칙을 작성할 수 있습니다: 만약 « <i>readingTime >= 5 AND domainName = "www.php.net"</i> » 다음으로 태그 «<i> 긴 읽기, php</i>»'
|
||||
how_to_use_them_description: '읽기 시간이 3 분 미만인 경우 «<i> 짧은 읽기 </i>» 와 같은 새 기사에 태그를 지정한다고 가정합니다. <br />이 경우 <i> 규칙</i> 을 입력해야합니다. <i>태그</i> 필드에 « readingTime <= 3 » 을 입력하고 « <i>짧은 읽기</i>» 를 입력하십시오. <br /> 여러 태그를 쉼표로구분하여 한 번에 추가 할 수 있습니다: « <i> 짧은 읽기, 반드시 읽기</i> » <br /> 사전 정의 된 연산자를 사용하여 복잡한 규칙을 작성할 수 있습니다: 만약 « <i>readingTime >= 5 AND domainName = "www.php.net"</i> » 다음으로 태그 «<i> 긴 읽기, php</i>»'
|
||||
operator_description:
|
||||
and: 하나의 규칙 그리고 다른 규칙
|
||||
or: 하나의 규칙 또는 다른 규칙
|
||||
@ -471,7 +438,6 @@ config:
|
||||
annotations: 모든 주석 제거
|
||||
confirm: 정말 하시겠습니까? (되돌릴 수 없습니다)
|
||||
tags: 모든 태그 제거
|
||||
tagging_rules: 모든 태그 지정 규칙 제거
|
||||
form_feed:
|
||||
feed_link:
|
||||
archive: 보관
|
||||
@ -527,16 +493,6 @@ config:
|
||||
help_message: '온라인 도구를 사용하여 읽기 속도를 측정 할 수 있습니다:'
|
||||
label: 읽기 속도
|
||||
language_label: 언어
|
||||
help_font: 사용하고 싶은 글꼴 모음을 선택할 수 있습니다.
|
||||
help_fontsize: 사용하고 싶은 글꼴 크기를 선택할 수 있습니다.
|
||||
help_lineheight: 사용하고 싶은 줄 높이를 선택할 수 있습니다.
|
||||
lineheight_label: 줄 높이
|
||||
maxwidth_label: 최대 너비
|
||||
help_maxwidth: 사용하고 싶은 최대 너비를 선택할 수 있습니다.
|
||||
font_label: 글꼴 모음
|
||||
fontsize_label: 글꼴 크기
|
||||
help_display_thumbnails: 문서 썸네일을 표시할지 여부를 결정할 수 있습니다. 느린 연결에 유용합니다.
|
||||
display_thumbnails_label: 문서 썸네일 표시 (느린 연결에 유용).
|
||||
otp:
|
||||
app:
|
||||
qrcode_label: QR 코드
|
||||
@ -557,7 +513,6 @@ config:
|
||||
user_info: 사용자 정보
|
||||
feed: 피드
|
||||
settings: 설정
|
||||
article_display: 문서 표시
|
||||
form:
|
||||
save: 저장
|
||||
page_title: 설정
|
||||
@ -571,7 +526,7 @@ menu:
|
||||
random_entry: 해당 목록에서 임의의 문서로 이동
|
||||
add_new_entry: 새 문서 추가
|
||||
filter_entries: 기사 필터
|
||||
account: 내 계정
|
||||
account: 나의 계정
|
||||
export: 내보내기
|
||||
search: 검색
|
||||
left:
|
||||
@ -586,7 +541,7 @@ menu:
|
||||
theme_toggle_auto: 자동 테마
|
||||
theme_toggle_dark: 어두운 테마
|
||||
theme_toggle_light: 밝은 테마
|
||||
quickstart: 빠른 시작
|
||||
quickstart: 빠른시작
|
||||
search: 검색
|
||||
users_management: 사용자 관리
|
||||
save_link: 링크 저장
|
||||
@ -597,7 +552,6 @@ menu:
|
||||
tags: 태그
|
||||
config: 설정
|
||||
starred: 즐겨찾기
|
||||
with_annotations: 주석 있음
|
||||
search_form:
|
||||
input_label: 여기에 검색어 입력
|
||||
error:
|
||||
@ -682,7 +636,7 @@ quickstart:
|
||||
configure:
|
||||
tagging_rules: 문서를 자동으로 태그하는 규칙 작성
|
||||
feed: 피드 활성화
|
||||
language: 언어 및 인터페이스 변경
|
||||
language: 언어 및 디자인 변경
|
||||
description: 자신에게 맞는 앱을 얻으려면, wallabag의 구성을 살펴보십시오.
|
||||
title: 응용 프로그램 구성
|
||||
more: 더보기…
|
||||
@ -739,5 +693,3 @@ tag:
|
||||
see_untagged_entries: 태그가 없는 문서보기
|
||||
number_on_the_page: '{0} 태그가 없습니다.|{1} 태그가 1 개 있습니다.|]1,Inf[태그가 %count% 개 있습니다.'
|
||||
page_title: 태그
|
||||
confirm:
|
||||
delete: '%name% 태그 삭제'
|
||||
|
||||
@ -9,32 +9,22 @@ config:
|
||||
300_word: Ik lees ~300 woorden per minuut
|
||||
200_word: Ik lees ~200 woorden per minuut
|
||||
100_word: Ik lees ~100 woorden per minuut
|
||||
help_message: 'Je kunt online programma''s gebruiken om je leessnelheid te bepalen:'
|
||||
help_message: 'U can online tooling gebruiken om uw leessnelheid te bepalen:'
|
||||
label: Leessnelheid
|
||||
language_label: Taal
|
||||
items_per_page_label: Artikelen per pagina
|
||||
help_pocket_consumer_key: Verplicht voor het importeren uit Pocket. Je kan dit aanmaken in je Pocket account.
|
||||
items_per_page_label: Items per pagina
|
||||
help_pocket_consumer_key: Verplicht voor het importeren uit Pocket. U kan dit aanmaken in uw Pocket account.
|
||||
help_language: U kan de taal van wallabag aanpassen.
|
||||
help_reading_speed: wallabag berekend een leestijd voor ieder artikel aan de hand van hoe snel je leest. Hier kan je aangeven hoe snel je leest.
|
||||
help_reading_speed: wallabag berekend een leestijd voor ieder artikel. U kan hier aangeven of u een snelle of langzame lezer bent waardoor wallabag een accurate tijd kan berekenen per artikel.
|
||||
help_items_per_page: U kan de hoeveelheid getoonde artikelen per pagina aanpassen.
|
||||
android_instruction: Tik hier om je Android-app vooraf in te vullen
|
||||
android_configuration: Configureer je Android applicatie
|
||||
android_instruction: Tik hier om uw Android-appvooraf in te vullen
|
||||
android_configuration: Configureer uw Android applicatie
|
||||
pocket_consumer_key_label: Consumer key voor Pocket om inhoud te importeren
|
||||
help_display_thumbnails: Jij bepaalt of je de artikel mini-afbeelding wilt zien. Uitzetten is handig bij een langzame verbinding.
|
||||
display_thumbnails_label: Toon artikel mini-afbeelding (handig bij langzame verbindingen).
|
||||
help_font: Kies de lettertypefamilie die je wil gebruiken.
|
||||
help_lineheight: Kies de regelhoogte die je wil gebruiken.
|
||||
help_maxwidth: Kies de maximale breedte die je wil gebruiken.
|
||||
font_label: Lettertypefamilie
|
||||
help_fontsize: Kies de lettergrootte die je wil gebruiken.
|
||||
fontsize_label: Lettergrootte
|
||||
lineheight_label: Regelhoogte
|
||||
maxwidth_label: Maximale breedte
|
||||
form:
|
||||
save: Opslaan
|
||||
tab_menu:
|
||||
new_user: Voeg gebruiker toe
|
||||
rules: Labelregels
|
||||
rules: Label regels
|
||||
password: Wachtwoord
|
||||
user_info: Gebruikers informatie
|
||||
rss: RSS
|
||||
@ -42,33 +32,32 @@ config:
|
||||
ignore_origin: Negeer oorsprong regels
|
||||
feed: Feeds
|
||||
reset: Reset gebied
|
||||
article_display: Artikel weergave
|
||||
page_title: Configuratie
|
||||
form_user:
|
||||
delete:
|
||||
title: Verwijder mijn account (a.k.a gevaarlijke zone)
|
||||
button: Verwijder mijn account
|
||||
confirm: Weet je het zeker? (DIT KAN NIET ONGEDAAN GEMAAKT WORDEN)
|
||||
description: Als je je account verwijdert, worden AL je artikelen, AL je labels, AL je annotaties en je account PERMANENT verwijderd (het kan niet ONGEDAAN gemaakt worden). Je wordt vervolgens uitgelogd.
|
||||
confirm: Weet u het zeker? (DIT KAN NIET ONGEDAAN GEMAAKT WORDEN)
|
||||
description: Als je je account verwijdert, worden AL je artikelen, AL je tags, AL je annotaties en je account PERMANENT verwijderd (het kan niet ONGEDAAN gemaakt worden). U wordt vervolgens uitgelogd.
|
||||
help_twoFactorAuthentication: Wanneer u 2FA inschakelt, krijgt u bij elke inlogactie bij wallabag een code per mail.
|
||||
twoFactorAuthentication_label: Twee factor authenticatie
|
||||
email_label: E-mailadres
|
||||
name_label: Naam
|
||||
two_factor_description: Inschakelen van tweestapsverificatie betekend dat je een e-mail krijgt met een code, elke keer als je verbinding maakt met een nieuw, niet vertrouwd apparaat.
|
||||
two_factor_description: Inschakken van 2-factor-authenticatie betekend dat u een email krijgt met een code elke keer als verbinding maakt met een nieuw niet vertrouwd apparaat.
|
||||
two_factor:
|
||||
action_app: Gebruik OTP app
|
||||
action_email: Gebruik e-mail
|
||||
action_email: Gebruik email
|
||||
state_disabled: Uitgeschakeld
|
||||
state_enabled: Ingeschakeld
|
||||
table_action: Actie
|
||||
table_state: Status
|
||||
table_method: Methode
|
||||
googleTwoFactor_label: Gebruik tweestapsverificatie met eenmalige codes van een OTP app (zoals Google Authenticator, Authy of FreeOTP)
|
||||
emailTwoFactor_label: Gebruik tweestapsverificatie met eenmalige codes die je per e-mail ontvangt
|
||||
googleTwoFactor_label: Gebruik maken van OTP app (open de app, zoals Google Authenticator, Authy of FreeOTP, om een eenmalige code te krijgen)
|
||||
emailTwoFactor_label: Gebruik maken van email (ontvang een code per mail)
|
||||
login_label: Login (kan niet veranderd worden)
|
||||
form_rules:
|
||||
faq:
|
||||
tagging_rules_definition_description: Dit zijn regels die door Wallabag worden gebruikt om automatisch nieuwe artikelen te labelen. <br /> Elke keer dat een nieuw artikel wordt toegevoegd, worden de labelregels gebruikt om labels toe te voegen. Hierdoor bespaar je de moeite van handmatig classificeren.
|
||||
tagging_rules_definition_description: Dit zijn regels die door Wallabag worden gebruikt om automatisch nieuwe items te labelen. <br /> Elke keer dat een nieuw item wordt toegevoegd, worden alle labelregels gebruikt om de labels toe te voegen die je hebt geconfigureerd, waardoor je de moeite van het handmatig classificeren van je items bespaart.
|
||||
operator_description:
|
||||
matches: 'Valideert dat een <i>onderwerp</i> gelijk is aan <i>zoek</i> (hoofdletter-ongevoelig.<br />Voorbeeld: <code>titel gelijk aan "voetbal"</code>'
|
||||
notmatches: 'Valideert dat een <i>onderwerp</i> niet gelijk is aan <i>zoek</i> (hoofdletter-ongevoelig.<br />Voorbeeld: <code>titel niet gelijk aan "voetbal"</code>'
|
||||
@ -82,23 +71,23 @@ config:
|
||||
less_than: Minder dan…
|
||||
label: Operator
|
||||
variable_description:
|
||||
domainName: De domeinnaam van het artikel
|
||||
readingTime: De verwachte leestijd van het artikel, in minuten
|
||||
mimetype: Media type van het artikel
|
||||
language: Taal van het artikel
|
||||
content: Inhoud van het artikel
|
||||
isStarred: Of het artikel een ster heeft of niet
|
||||
isArchived: Of het artikel gearchiveerd is of niet
|
||||
url: URL van het artikel
|
||||
title: Titel van het artikel
|
||||
domainName: De domeinnaam van het item
|
||||
readingTime: De verwachte leestijd van het item, in minuten
|
||||
mimetype: Media type van het item
|
||||
language: Taal van het item
|
||||
content: Inhoud van het item
|
||||
isStarred: Of het item gemarkeerd is of niet
|
||||
isArchived: Of het item gearchiveerd is of niet
|
||||
url: URL van het item
|
||||
title: Titel van het item
|
||||
label: Variabel
|
||||
meaning: Betekenis
|
||||
variables_available_description: 'De volgende variabelen en operatoren kunnen gebruikt worden om labelregels te maken:'
|
||||
variables_available_description: 'De volgende variabelen en operatoren kunnen gebruikt worden om label regels te maken:'
|
||||
variables_available_title: Welke variabelen en operatoren kan ik gebruiken om regels te schrijven?
|
||||
how_to_use_them_title: Hoe gebruik is ze?
|
||||
tagging_rules_definition_title: Wat zijn “labelregels”?
|
||||
tagging_rules_definition_title: Wat betekend "label regels"?
|
||||
title: FAQ
|
||||
how_to_use_them_description: 'Als voorbeeld nemen we aan dat je artikelen wil labelen als « <i>korte lezing</i> » wanneer de leestijd minder dan 3 minuten is.<br />In dat geval zet je « readingTime <= 3 » in het <i>Regelveld</i> en « <i>korte lezing</i> » in het <i>Labels</i> veld.<br />Meerdere labels kunnen tegelijkertijd worden toegevoegd door ze te scheiden met een komma: « <i>korte lezing, belangrijk</i> »<br />Complexe regels kunnen worden geschreven met behulp van de beschikbare operators: als « <i>readingTime >= 5 AND domainName = "www.php.net"</i> » label dan als « <i>lange lezing, php</i> »'
|
||||
how_to_use_them_description: 'Laten we aannemen dat u nieuwe vermeldingen wilt labelen als « <i>korte lezing</i> » wanneer de leestijd minder dan 3 minuten bedraagt.<br />In dat geval moet u « readingTime <= 3 » in het <i>Regelveld</i> en « <i>korte lezing</i> » in het <i>Labels</i> veld.<br />Meerdere labels kunnen tegelijkertijd worden toegevoegd door ze te scheiden met een komma:« <i>korte lezing, belangrijk</i> »<br />Complexe regels kunnen worden geschreven met behulp van vooraf gedefinieerde operators: if « <i>readingTime >= 5 AND domainName = "www.php.net"</i> » label dan als« <i>lange lezing, php</i> »'
|
||||
tags_label: Labels
|
||||
rule_label: Regel
|
||||
edit_rule_label: wijzig
|
||||
@ -109,36 +98,33 @@ config:
|
||||
import_submit: Importeer
|
||||
file_label: JSON bestand
|
||||
card:
|
||||
export_tagging_rules_detail: Hiermee wordt een JSON-bestand gedownload dat je kan gebruiken om labelregels elders te importeren of om er een back-up van te maken.
|
||||
export_tagging_rules_detail: Hiermee wordt een JSON-bestand gedownload dat u kunt gebruiken om labelregels elders te importeren of om er een back-up van te maken.
|
||||
new_tagging_rule: Maak een labelregel
|
||||
import_tagging_rules: Importeer labelregels
|
||||
export_tagging_rules: Exporteer labelregels
|
||||
import_tagging_rules_detail: Kies het JSON-bestand dat je eerder hebt geëxporteerd.
|
||||
import_tagging_rules_detail: Selecteer het JSON-bestand dat u eerder hebt geëxporteerd.
|
||||
form_password:
|
||||
repeat_new_password_label: Herhaal nieuw wachtwoord
|
||||
new_password_label: Nieuw wachtwoord
|
||||
old_password_label: Huidig wachtwoord
|
||||
description: Je kan hier je wachtwoord wijzigen. Je nieuwe wachtwoord moet minimaal 8 tekens lang zijn.
|
||||
description: U kan hier uw wachtwoord wijzigen. Uw nieuwe wachtwoord moet minimaal 8 tekens lang zijn.
|
||||
reset:
|
||||
confirm: Weet je het zeker? (DIT IS ONOMKEERBAAR)
|
||||
archived: Verwijder ALLE gearchiveerde artikelen
|
||||
entries: Verwijder ALLE artikelen
|
||||
confirm: Weet u het zeker? (DIT IS ONOMKEERBAAR)
|
||||
archived: Verwijder ALLE gearchiveerde items
|
||||
entries: Verwijder ALLE items
|
||||
tags: Verwijder ALLE labels
|
||||
annotations: Verwijder ALLE annotaties
|
||||
description: Door onderstaande knoppen te gebruiken kan je bepaalde informatie van je account verwijderen. Wees gewaarschuwd, de verwijderde informatie kan NIET HERSTELD worden.
|
||||
description: Door onderstaande knoppen te gebruiken kan u bepaalde informatie van uw account verwijderen. Wees gewaarschuwd dat NIET niet ongedaan gemaakt kan worden.
|
||||
title: Reset opties (a.k.a gevaarlijke zone)
|
||||
tagging_rules: Verwijder ALLE labelregels
|
||||
otp:
|
||||
app:
|
||||
enable: Inschakelen
|
||||
cancel: Annuleer
|
||||
two_factor_code_description_4: 'Test een OTP-code van jouw OTP-app:'
|
||||
two_factor_code_description_3: 'Bewaar deze back-upcodes op een veilige plaats, je kunt deze gebruiken voor het geval je de toegang tot je OTP-app verliest:'
|
||||
two_factor_code_description_2: 'Je kunt de QR-code scannen met jouw app:'
|
||||
two_factor_code_description_1: Je hebt zojuist de tweestapsverificatie met OTP app ingeschakeld. Open jouw OTP-app en gebruik de QR-code om een eenmalig wachtwoord te krijgen. Let op, de QR-code verdwijnt na het verlaten of opnieuw laden van deze pagina.
|
||||
qrcode_label: QR code
|
||||
two_factor_code_description_5: 'Als je de QR code niet kan scannen, voer dan het geheim in:'
|
||||
page_title: Tweestapsverificatie
|
||||
two_factor_code_description_4: 'Test een OTP-code van uw geconfigureerde app:'
|
||||
two_factor_code_description_3: 'Bewaar deze back-upcodes op een veilige plaats, u kunt dit gebruiken voor het geval u de toegang tot uw OTP-app verliest:'
|
||||
two_factor_code_description_2: 'U kunt de QR-code scannen met uw app:'
|
||||
two_factor_code_description_1: U hebt zojuist de OTP-tweefactorauthenticatie ingeschakeld, uw OTP-app geopend en die code gebruikt om een eenmalig wachtwoord te krijgen. Het verdwijnt nadat de pagina opnieuw is geladen.
|
||||
page_title: Twee-factor authenticatie
|
||||
form_ignore_origin_rules:
|
||||
faq:
|
||||
ignore_origin_rules_definition_title: Wat betekent “negeer oorsprong regels”?
|
||||
@ -153,41 +139,41 @@ config:
|
||||
meaning: Betekenis
|
||||
variables_available_description: 'De volgende variabelen en operatoren kunnen worden gebruikt om regels voor het negeren van oorsprong te creëren:'
|
||||
variables_available_title: Welke variabelen en operatoren kunnen gebruikt worden om regels te schrijven?
|
||||
how_to_use_them_description: Als je de bron van een artikel wil negeren als het afkomstig is van «<i>rss.example.com</i>» (<i>wetende dat na een omleiding het daadwerkelijke adres example.com is</i>). <br />In dat geval kun je «host = "rss.example.com"» in het veld <i>Regel</i> plaatsen.
|
||||
how_to_use_them_description: Laten we aannemen dat u de oorsprong van een item wilt negeren dat afkomstig is van «<i>rss.example.com</i>» (<i>wetende dat na een omleiding het daadwerkelijke adres example.com is</i>) . <br />In dat geval moet u «host =" rss.example.com "» in het veld <i> Regel </i> plaatsen.
|
||||
how_to_use_them_title: Hoe gebruik ik ze?
|
||||
ignore_origin_rules_definition_description: Ze worden door wallabag gebruikt om automatisch een bronadres te negeren na een omleiding. <br />Als een omleiding plaatsvindt tijdens het ophalen van een nieuw artikel, zullen alle regels voor het negeren van de bron (<i>door de gebruiker gedefinieerd en door het systeem gedefinieerd</i>) gebruikt worden om het bronadres te negeren.
|
||||
ignore_origin_rules_definition_description: Ze worden door wallabag gebruikt om automatisch een oorsprongsadres te negeren na een omleiding. <br />Als een omleiding plaatsvindt tijdens het ophalen van een nieuw item, zullen alle regels voor het negeren van de oorsprong (<i>door de gebruiker gedefinieerd en door de instantie gedefinieerd</i>) gebruikt worden om het oorspronkelijke adres te negeren.
|
||||
title: Veelgestelde vragen
|
||||
form_feed:
|
||||
feed_links: Feedlinks
|
||||
feed_limit: Aantal artikelen in de feed
|
||||
feed_limit: Aantal items in de feed
|
||||
feed_link:
|
||||
all: Alles
|
||||
archive: Gearchiveerd
|
||||
starred: Met ster
|
||||
starred: Gemarkeerd
|
||||
unread: Ongelezen
|
||||
token_revoke: Token intrekken
|
||||
token_reset: Token opnieuw genereren
|
||||
token_create: Creëer een token
|
||||
token_create: Creëer uw token
|
||||
no_token: Geen token
|
||||
token_label: Feed token
|
||||
description: Met Atom-feeds van wallabag kunt je je opgeslagen artikelen lezen met je favoriete Atom-lezer. Je moet wel eerst een token genereren.
|
||||
description: Met Atom-feeds van wallabag kunt u uw opgeslagen artikelen lezen met uw favoriete Atom-lezer. U moet wel eerst een token genereren.
|
||||
footer:
|
||||
stats: Sinds %user_creation% heb je %nb_archives% artikelen gelezen. Dat is ongeveer %per_day% per dag!
|
||||
stats: Sinds %user_creation% heeft u %nb_archives% artikelen gelezen. Dat is ongeveer %per_day% per dag!
|
||||
wallabag:
|
||||
about: Over
|
||||
powered_by: mogelijk gemaakt door
|
||||
social: Sociaal
|
||||
elsewhere: Neem wallabag met je mee
|
||||
elsewhere: Neem wallabag met u mee
|
||||
menu:
|
||||
search_form:
|
||||
input_label: Vul je zoeksuggestie hier in
|
||||
input_label: Vul uw zoeksuggestie hier in
|
||||
top:
|
||||
export: Exporteer
|
||||
filter_entries: Filter artikelen
|
||||
filter_entries: Filter items
|
||||
search: Zoeken
|
||||
add_new_entry: Voeg nieuw artikel toe
|
||||
add_new_entry: Voeg nieuw item toe
|
||||
account: Mijn account
|
||||
random_entry: Spring naar een willekeurig artikel in de lijst
|
||||
random_entry: Spring naar een willekeurig item van de lijst
|
||||
left:
|
||||
site_credentials: Site inloggegevens
|
||||
users_management: Gebruikersbeheer
|
||||
@ -202,16 +188,15 @@ menu:
|
||||
internal_settings: Interne Instellingen
|
||||
tags: Labels
|
||||
config: Configuratie
|
||||
all_articles: Alle artikelen
|
||||
all_articles: Alle items
|
||||
archive: Archief
|
||||
starred: Met ster
|
||||
starred: Gemarkeerd
|
||||
unread: Ongelezen
|
||||
ignore_origin_instance_rules: Globaal negeer-oorsprongsregels
|
||||
quickstart: Snelstart
|
||||
theme_toggle_auto: Thema automatisch
|
||||
theme_toggle_dark: Donker thema
|
||||
theme_toggle_light: Licht thema
|
||||
with_annotations: Met aantekeningen
|
||||
security:
|
||||
login:
|
||||
password: Wachtwoord
|
||||
@ -223,10 +208,10 @@ security:
|
||||
forgot_password: Wachtwoord vergeten?
|
||||
keep_logged_in: Houdt mij ingelogd
|
||||
register:
|
||||
go_to_account: Ga naar je account
|
||||
go_to_account: Ga naar uw account
|
||||
page_title: Maak een account
|
||||
resetting:
|
||||
description: Voer je e-mailadres hieronder in en wij sturen je instructies voor het opnieuw instellen van je wachtwoord.
|
||||
description: Voer uw e-mailadres hieronder in en wij sturen u instructies voor het opnieuw instellen van uw wachtwoord.
|
||||
flashes:
|
||||
site_credential:
|
||||
notice:
|
||||
@ -246,33 +231,33 @@ flashes:
|
||||
notice:
|
||||
summary_with_queue: 'Importeren samenvatting: %queued% in wachtrij.'
|
||||
summary: 'Importeren samenvatting: %imported% imported, %skipped% reeds opgeslagen.'
|
||||
failed_on_file: Fout bij het verwerken van importeren. Controleer het geïmporteerde bestand.
|
||||
failed: Importeren mislukt, probeer opnieuw.
|
||||
failed_on_file: Fout bij het verwerken van importeren. Controleer uw geïmporteerde bestand.
|
||||
failed: Importeren gefaald, probeer opnieuw.
|
||||
error:
|
||||
rabbit_enabled_not_installed: RabbitMQ is ingeschakeld voor het afhandelen van asynchroon importeren, maar het lijkt erop dat <u> we er geen verbinding mee kunnen maken </u>. Controleer de RabbitMQ-configuratie.
|
||||
redis_enabled_not_installed: Redis is ingeschakeld voor het afhandelen van asynchroon importeren, maar het lijkt erop dat <u> we er geen verbinding mee kunnen maken </u>. Controleer de Redis-configuratie.
|
||||
entry:
|
||||
notice:
|
||||
entry_reloaded_failed: Artikelen opnieuw geladen maar ophalen van inhoud mislukt
|
||||
entry_saved_failed: Artikel opgeslagen maar ophalen van inhoud is mislukt
|
||||
entry_already_saved: Artikel is reeds opgeslagen op %date%
|
||||
entry_deleted: Artikel verwijderd
|
||||
entry_unstarred: Artikel is nu zonder ster
|
||||
entry_starred: Artikel is nu met ster
|
||||
entry_unarchived: Artikel gedearchiveerd
|
||||
entry_archived: Artikel gearchiveerd
|
||||
entry_reloaded: Artikel is opnieuw geladen
|
||||
entry_updated: Artikel geüpdatet
|
||||
entry_saved: Artikel opgeslagen
|
||||
entry_reloaded_failed: Item herladen maar ophalen van inhoud gefaald
|
||||
entry_saved_failed: Item opgeslagen maar ophalen van inhoud is gefaald
|
||||
entry_already_saved: Item is reeds opgeslagen op %date%
|
||||
entry_deleted: Item verwijderd
|
||||
entry_unstarred: Item gedemarkeerd
|
||||
entry_starred: Item gemarkeerd
|
||||
entry_unarchived: Item gedearchiveerd
|
||||
entry_archived: Item gearchiveerd
|
||||
entry_reloaded: Item herladen
|
||||
entry_updated: Item geüpdatet
|
||||
entry_saved: Item opgeslagen
|
||||
no_random_entry: Er is geen artikel met deze criteria gevonden
|
||||
config:
|
||||
notice:
|
||||
archived_reset: Gearchiveerde artikelen verwijderd
|
||||
archived_reset: Gearchiveerde items verwijderd
|
||||
rss_token_updated: RSS token geüpdatet
|
||||
tagging_rules_deleted: Labelregel verwijderd
|
||||
tagging_rules_updated: Labelregels geüpdatet
|
||||
tagging_rules_deleted: Labeling regel verwijderd
|
||||
tagging_rules_updated: Labeling regels geüpdatet
|
||||
rss_updated: RSS informatie geüpdatet
|
||||
entries_reset: Artikelen gereset
|
||||
entries_reset: Items gereset
|
||||
tags_reset: Labels gereset
|
||||
annotations_reset: Annotaties gereset
|
||||
user_updated: Informatie veranderd
|
||||
@ -280,20 +265,17 @@ flashes:
|
||||
config_saved: Configuratie opgeslagen.
|
||||
ignore_origin_rules_updated: Negeer oorsprongregel gewijzigd
|
||||
ignore_origin_rules_deleted: Negeer oorsprongregel verwijderd
|
||||
tagging_rules_not_imported: Fout bij importeren van labelregels
|
||||
tagging_rules_imported: Labelregels geïmporteerd
|
||||
otp_disabled: Tweestapsverificatie uitgeschakeld
|
||||
otp_enabled: Tweestapsverificatie ingeschakeld
|
||||
tagging_rules_not_imported: Fout bij importeren van labeling regels
|
||||
tagging_rules_imported: Labeling regels geïmporteerd
|
||||
otp_disabled: Twee factor authenticatie uitgeschakeld
|
||||
otp_enabled: Twee factor authenticatie ingeschakeld
|
||||
feed_token_revoked: Feed token ingetrokken
|
||||
feed_token_updated: Feed token gewijzigd
|
||||
feed_updated: Feed informatie gewijzigd
|
||||
tagging_rules_reset: Reset labelregels
|
||||
otp_code_invalid: Foute tweestapsverificatie code
|
||||
tag:
|
||||
notice:
|
||||
tag_added: Label toegevoegd
|
||||
tag_renamed: Label hernoemd
|
||||
too_much_tags: Om performance problemen te vermijden, kun je niet meer dan %tags% labels tegelijk toevoegen, en zijn labels met meer dan %characters% tekens niet toegestaan.
|
||||
ignore_origin_instance_rule:
|
||||
notice:
|
||||
deleted: Globale oorsprongregel voor negeren verwijderd
|
||||
@ -304,7 +286,7 @@ error:
|
||||
site_credential:
|
||||
form:
|
||||
back_to_list: Terug naar lijst
|
||||
delete_confirm: Weet je het zeker?
|
||||
delete_confirm: Weet u het zeker?
|
||||
delete: Verwijder
|
||||
save: Opslaan
|
||||
password_label: Wachtwoord
|
||||
@ -319,7 +301,7 @@ site_credential:
|
||||
edit_site_credential: Wijzig bestaande inloggegevens
|
||||
new_site_credential: Creëer inloggegevens
|
||||
page_title: Beheer van inloggegevens van de site
|
||||
description: Hier kunt je alle inloggegevens beheren voor sites die dit nodig hebben (maken, bewerken en verwijderen), zoals een betaalmuur, een authenticatie, enz.
|
||||
description: Hier kunt u alle inloggegevens beheren voor sites die dit nodig hebben (maken, bewerken en verwijderen), zoals een betaalmuur, een authenticatie, enz.
|
||||
user:
|
||||
form:
|
||||
repeat_new_password_label: Herhaal nieuw wachtwoord
|
||||
@ -327,7 +309,7 @@ user:
|
||||
name_label: Naam
|
||||
username_label: Gebruikersnaam
|
||||
back_to_list: Terug naar lijst
|
||||
delete_confirm: Weet je het zeker?
|
||||
delete_confirm: Weet u het zeker?
|
||||
delete: Verwijder
|
||||
save: Opslaan
|
||||
twofactor_label: Twee factor authenticatie
|
||||
@ -335,37 +317,37 @@ user:
|
||||
email_label: E-mail
|
||||
plain_password_label: ????
|
||||
last_login_label: Laatste login
|
||||
twofactor_google_label: Tweestapsverificatie met OTP app
|
||||
twofactor_email_label: Tweestapsverificatie via e-mail
|
||||
twofactor_google_label: Twee factor authenticatie met OTP app
|
||||
twofactor_email_label: Twee factor authenticatie met email
|
||||
list:
|
||||
create_new_one: Maak een nieuwe gebruiker
|
||||
no: Nee
|
||||
yes: Ja
|
||||
edit_action: Wijzig
|
||||
actions: Acties
|
||||
description: Hier kan je alle gebruikers beheren (creëren, wijzigen en verwijderen)
|
||||
description: Hier kan u alle gebruikers beheren (creëren, wijzigen en verwijderen)
|
||||
edit_user: Wijzig een bestaande gebruiker
|
||||
new_user: Maak een nieuwe gebruiker
|
||||
search:
|
||||
placeholder: Filter op gebruikersnaam of e-mail
|
||||
placeholder: Filter op username of email
|
||||
page_title: Gebruikersbeheer
|
||||
developer:
|
||||
howto:
|
||||
back: Terug
|
||||
description:
|
||||
paragraph_7: Dit verzoek geeft als resultaat alle artikelen voor deze gebruiker.
|
||||
paragraph_7: Dit verzoek geeft als resultaat alle items voor deze gebruiker.
|
||||
paragraph_6: 'Het acces_token is handig om een verzoek op de API te doen. Bijvoorbeeld:'
|
||||
paragraph_5: 'De API geeft een vergelijkbare reactie:'
|
||||
paragraph_4: 'Dus, creëer een token(vervang client_id, client_geheim, gebruikersnaam en wachtwoord met de juiste waardes):'
|
||||
paragraph_3: Om het token te maken, moet je <a href="%link%">een nieuwe client creëren</a>.
|
||||
paragraph_2: Je hebt een token nodig om te communiceren tussen applicaties van derde partijen en de wallabag API.
|
||||
paragraph_3: Om deze token te maken, moet u <a href="%link%">een nieuwe client creëren</a>.
|
||||
paragraph_2: U heeft een token nodig om te communiceren tussen applicaties van derde partijen en de wallabag API.
|
||||
paragraph_8: Als je alle API-eindpunten wilt zien, kun je <a href="%link%"> onze API-documentatie </a> bekijken.
|
||||
paragraph_1: De volgende commando's maken gebruik van de <a href="https://github.com/jkbrzt/httpie">HTTPie-bibliotheek</a>. Zorg ervoor dat deze op jouw systeem is geïnstalleerd voordat je het gebruikt.
|
||||
paragraph_1: De volgende commando's maken gebruik van de <a href="https://github.com/jkbrzt/httpie"> HTTPie-bibliotheek </a>. Zorg ervoor dat het op uw systeem is geïnstalleerd voordat u het gebruikt.
|
||||
page_title: API client beheren > Hoe creëer je je eerste applicatie
|
||||
client_parameter:
|
||||
read_howto: Lees de beschrijving "Hoe creëer je je eerste applicatie"
|
||||
back: Terug
|
||||
page_description: Dit zijn de client parameters.
|
||||
page_description: Dit zijn uw client parameters.
|
||||
page_title: API client beheer > Client parameters
|
||||
field_secret: Client geheim
|
||||
field_id: Client ID
|
||||
@ -377,7 +359,7 @@ developer:
|
||||
save_label: Maak een nieuwe client
|
||||
redirect_uris_label: Omleiding URLs (optioneel)
|
||||
name_label: Naam van de client
|
||||
page_description: Je staat op het punt een nieuwe client aan te maken. Vul het onderstaande veld in voor de omleidings-URI van jouw applicatie.
|
||||
page_description: U staat op het punt een nieuwe client aan te maken. Vul het onderstaande veld in voor de omleidings-URI van uw applicatie.
|
||||
copy_to_clipboard: Kopieer
|
||||
existing_clients:
|
||||
field_grant_types: Grant type toegestaan
|
||||
@ -392,7 +374,7 @@ developer:
|
||||
welcome_message: Welkom bij de wallabag API
|
||||
remove:
|
||||
action: Verwijder client %name%
|
||||
warn_message_2: Als je dit verwijdert, kan elke app die met deze client is geconfigureerd, niet meer verbinden met jouw wallabag.
|
||||
warn_message_2: Als u dit verwijdert, kan elke app die met die client is geconfigureerd, niet meer verbinden met uw wallabag.
|
||||
warn_message_1: U heeft de mogelijkheid om client %name% te verwijderen. Deze actie is ONOMKEERBAAR!
|
||||
clients:
|
||||
create_new: Maak een nieuwe client
|
||||
@ -401,28 +383,28 @@ developer:
|
||||
page_title: API client beheren
|
||||
import:
|
||||
pinboard:
|
||||
how_to: Kies je Pinboard exportbestand en klik op de knop om deze te uploaden en importeren.
|
||||
how_to: Selecteer uw Pinboard exporteur en klik onderstaande knop om die te uploaden en importeren.
|
||||
page_title: Importeer > Pinboard
|
||||
description: Importeer je Pinboard-artikelen. Klik op de "back-uppagina" (https://pinboard.in/settings/backup) op "JSON" in het gedeelte "Bladwijzers". Er wordt een JSON-bestand gedownload (zoals "pinboard_export").
|
||||
description: Deze importeur importeert al je Pinboard-artikelen. Klik op de "back-uppagina" (https://pinboard.in/settings/backup) op "JSON" in het gedeelte "Bladwijzers". Er wordt een JSON-bestand gedownload (zoals "pinboard_export").
|
||||
instapaper:
|
||||
how_to: Kies je Instapaper exportbestand en klik de knop om deze te uploaden en importeren.
|
||||
how_to: Selecteer uw Instapaper exporteur en klik onderstaande knop om die te uploaden en importeren.
|
||||
page_title: Importeer > Instapaper
|
||||
description: Importeer je Instapaper-artikelen. Klik op de instellingenpagina (https://www.instapaper.com/user) op "Download .CSV-bestand" in het gedeelte "Exporteren". Er wordt een CSV-bestand gedownload (zoals "instapaper-export.csv").
|
||||
description: Deze importeur importeert al uw Instapaper-artikelen. Klik op de instellingenpagina (https://www.instapaper.com/user) op "Download .CSV-bestand" in het gedeelte "Exporteren". Er wordt een CSV-bestand gedownload (zoals "instapaper-export.csv").
|
||||
chrome:
|
||||
description: 'Importeer je Chrome-bladwijzers. De locatie van het bestand is afhankelijk van je besturingssysteem: <ul><li>Onder Linux, ga naar de <code>~/.config/chromium/Default/</code>directory</li><li>In Windows, zou het in <code>%LOCALAPPDATA%\Google\Chrome\User Data\Default</code></li><li>Onder OS X moet het staan in <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Zodra je daar bent, kopieer je het <code>Bookmarks</code> bestand ergens waar je het kan vinden.<em><br>Let op dat als je Chromium gebruikt in plaats van Chrome, dat de paden dan aangepast moeten worden.</em></p>'
|
||||
description: 'Deze importeur importeert al uw Chrome-bladwijzers. De locatie van het bestand is afhankelijk van uw besturingssysteem: <ul> <li> Onder Linux, ga naar de <code> ~ /.config/chromium/Default/</code>directory </li> <li> In Windows, het zou in <code>% LOCALAPPDATA%\Google\Chrome\User Data\Default </code> </li> <li> Op OS X moeten staan in <code> ~/Library/Application Support/Google/Chrome/Default /Bookmarks </code> </li> </ul> Zodra u daar bent, kopieert u het <code> bladwijzer </code> -bestand ergens waar u het kunt vinden. <em> <br> Let op dat als u Chromium in plaats van Chrome heeft, u de paden dienovereenkomstig corrigeren moet. </em> </p>'
|
||||
page_title: Importeer > Chrome
|
||||
how_to: Kies het back-upbestand van de bladwijzer en klik op de onderstaande knop om het te importeren. Houd er rekening mee dat het proces lang kan duren, aangezien alle artikelen moeten worden opgehaald.
|
||||
readability:
|
||||
how_to: Kies het Readability exportbestand en klik de knop om deze te uploaden en importeren.
|
||||
how_to: Selecteer uw Readability exporteur en klik onderstaande knop om die te uploaden en importeren.
|
||||
page_title: Importeer > Readability
|
||||
description: Importeer je Readability-artikelen.
|
||||
description: Deze importeur importeert al uw Readability-artikelen. Klik bij tools (https://www.readability.com/tools/) op "Uw gegevens exporteren" in het gedeelte "Gegevensexport". U ontvangt een e-mail om een json te downloaden (die in feite niet op .json eindigt).
|
||||
wallabag_v2:
|
||||
page_title: Importeren > Wallabag v2
|
||||
description: Importeer al uw Wallabag v2-artikelen. Ga naar "Alle artikelen" en klik in de exporteer zijbalk op "JSON". Je hebt een "All Articles.json" -bestand.
|
||||
description: Deze importeur importeert al uw Wallabag v2-artikelen. Ga naar "Alle artikelen" en klik in de exporteer zijbalk op "JSON". Je hebt een "All Articles.json" -bestand.
|
||||
wallabag_v1:
|
||||
how_to: Kies je wallabag exportbestand en klik op de knop om deze te uploaden en importeren.
|
||||
how_to: Selecteer uw wallabag exporteur en klik onderstaande knop om die te uploaden en importeren.
|
||||
page_title: Importeren > Wallabag v1
|
||||
description: Importeer al je Wallabag v1-artikelen. Klik in de configuratiepagina op "JSON-exporteren" in de sectie "Exporteer je wallabag-gegevens". Je krijgt dan het bestand "wallabag-export-1-xxxx-xx-xx.json".
|
||||
description: Deze importeur importeert al uw Wallabag v1-artikelen. Klik op je configuratiepagina op "JSON-exporteren" in de sectie "Exporteer je wallabag-gegevens". Je hebt het bestand "wallabag-export-1-xxxx-xx-xx.json".
|
||||
pocket:
|
||||
connect_to_pocket: Verbind Pocket en importeer data
|
||||
config_missing:
|
||||
@ -430,66 +412,43 @@ import:
|
||||
admin_message: U moet %keyurls%a pocket_consumer_key%keyurle% definiëren.
|
||||
description: Pocket importeren is niet geconfigureerd.
|
||||
page_title: Importeer > Pocket
|
||||
authorize_message: Je kunt je gegevens importeren vanuit jouw Pocket-account. Je hoeft alleen maar op de onderstaande knop te klikken en de applicatie te autoriseren om verbinding te maken met getpocket.com.
|
||||
description: Importeer je gegevens van Pocket. Pocket staat het niet toe om inhoud van hun dienst op te halen, dus de leesbare inhoud van elk artikel wordt opnieuw opgehaald door wallabag.
|
||||
authorize_message: U kunt uw gegevens importeren vanuit uw Pocket-account. U hoeft alleen maar op de onderstaande knop te klikken en de applicatie te autoriseren om verbinding te maken met getpocket.com.
|
||||
description: Deze importeur importeert al uw Pocket-gegevens. Pocket staat niet toe om inhoud van hun dienst op te halen, dus de leesbare inhoud van elk artikel wordt opnieuw opgehaald door wallabag.
|
||||
form:
|
||||
file_label: Bestand
|
||||
mark_as_read_label: Markeer alle geïmporteerde artikelen als gelezen
|
||||
mark_as_read_label: Markeer alle geïmporteerde items als gelezen
|
||||
mark_as_read_title: Markeer als gelezen?
|
||||
save_label: Upload bestand
|
||||
page_description: Welkom bij de wallabag importeur. Selecteer de dienst waarvan je wil migreren.
|
||||
page_description: Welkom bij de wallabag importeur. Selecteer uw vorige dienst waarvan u wilt migreren.
|
||||
page_title: Importeren
|
||||
firefox:
|
||||
page_title: Importeer > Firefox
|
||||
description: Importeer je Firefox-bladwijzers. Ga naar je Bibliotheek (Ctrl + Shift + O), klik op de knop "↓↑" en dan "Reserve kopie maken…". Je krijgt een .json-bestand.
|
||||
description: Deze importeur importeert al uw Firefox-bladwijzers. Ga naar uw bladwijzers (Ctrl + Shift + O), en kies dan "Importeren en back-up", kies "Back-up…". U krijgt een .json-bestand.
|
||||
how_to: Kies het back-upbestand van de bladwijzer en klik op de onderstaande knop om het te importeren. Houd er rekening mee dat het proces lang kan duren, aangezien alle artikelen moeten worden opgehaald.
|
||||
action:
|
||||
import_contents: Importeer inhoud
|
||||
worker:
|
||||
enabled: 'Het importeren wordt asynchroon uitgevoerd. Zodra de importeer taak is gestart, zal een extern proces de taken één voor één afhandelen. De huidige service is:'
|
||||
download_images_warning: Je hebt het downloaden van afbeeldingen voor je artikelen ingeschakeld. In combinatie met de klassieke import kan dat een eeuwigheid duren (of het mislukt misschien). We <strong>raden sterk aan</strong> om asynchroon importeren in te schakelen om fouten te voorkomen.
|
||||
download_images_warning: U heeft het downloaden van afbeeldingen voor uw artikelen ingeschakeld. In combinatie met de klassieke import kan het eeuwen duren om door te gaan (of het mislukt misschien). We <strong> raden sterk aan </strong> om asynchroon importeren in te schakelen om fouten te voorkomen.
|
||||
elcurator:
|
||||
description: Importeer al je elCurator-artikelen.
|
||||
description: Deze importeur importeert al je elCurator-artikelen. Ga naar voorkeuren in uw elCurator-account en exporteer vervolgens uw inhoud. Je krijgt een JSON-bestand.
|
||||
page_title: Importeer > elCurator
|
||||
how_to: Kies je elCurator exportbestand en druk op de knop om deze uploaden en importeren.
|
||||
pocket_html:
|
||||
page_title: Importeer > Pocket HTML
|
||||
how_to: Kies het Pocket exportbestand en druk op de knop om het te importeren. Let op, het proces kan lang duren omdat alle artikelen opgehaald moeten worden.
|
||||
description: Importeer je Pocket bookmarks (via HTML export). Ga naar https://getpocket.com/export, exporteer dan een HTML bestand. Een HTML bestand genaamd "ril_export.html" wordt gedownload.
|
||||
shaarli:
|
||||
how_to: Kies een bookmark-backupbestand en druk op de knop om het te importeren. Let op, het proces kan lang duren omdat alle artikelen opgehaald moeten worden.
|
||||
description: Importeer je Shaarli bookmarks. Log in, ga naar de Tools sectie, kies "Export database", kies je bookmarks en exporteer. Je krijgt een HTML bestand.
|
||||
page_title: Importeer > Shaarli
|
||||
delicious:
|
||||
how_to: Kies je Delicious exportbestand en druk op de knop om deze te importeren.
|
||||
page_title: Importeer > del.icio.us
|
||||
description: Importeer je Delicious bookmarks. Sinds 2021 kun je je data weer exporteren via de pagina https://del.icio.us/export. Kies het "JSON" formaat. Je krijgt een bestand met de naam die lijkt op "delicious_export.2021.02.06_21.10.json".
|
||||
omnivore:
|
||||
page_title: Importeer > Omnivore
|
||||
how_to: Unzip het Omnivore exportbestand, upload dan, een voor een, elk JSON bestand met de naam "metadata_x_to_y.json".
|
||||
description: Importeer al je Omnivore artikelen.
|
||||
pocket_csv:
|
||||
page_title: Importeer > Pocket CSV
|
||||
how_to: Kies het bookmark backupbestand en druk op de knop om het te importeren. Let op, het proces kan lang duren omdat alle artikelen opgehaald moeten worden.
|
||||
description: Importeer je Pocket bookmarks (via CSV export). Ga naar https://getpocket.com/export, exporteer dan een CSV bestand. Een ZIP bestand genaamd "pocket.zip" wordt gedownload. Unzip het krijgt dan een csv bestand genaamd "part_000000.csv".
|
||||
export:
|
||||
unknown: Onbekend
|
||||
footer_template: <div style="text-align:center;"><p>Gemaakt door wallabag met %method%</p><p>Make een <a href="https://github.com/wallabag/wallabag/issues">issue</a> aan (in het Engels) als je problemen ondervind met dit E-Book op jouw apparaat.</p></div>
|
||||
footer_template: <div style="text-align:center;"><p>Gemaakt door wallabag met %method%</p><p>Open <a href="https://github.com/wallabag/wallabag/issues">een probleem</a> als u problemen ondervind met dit E-Book op uw apparaat.</p></div>
|
||||
tag:
|
||||
new:
|
||||
placeholder: Je kan meerdere labels toevoegen, gescheiden door een komma.
|
||||
placeholder: U kan meerdere labels toevoegen door ze te splitsen met comma.
|
||||
add: Toevoegen
|
||||
list:
|
||||
number_on_the_page: '{0} Er zijn geen labels.|{1} Er is één label.|]1,Inf[ Er zijn %count% labels.'
|
||||
see_untagged_entries: Toon niet gelabelde artikelen
|
||||
no_untagged_entries: Er zijn geen artikelen zonder label.
|
||||
untagged: Niet gelabelde artikelen
|
||||
see_untagged_entries: Toon niet gelabelde items
|
||||
no_untagged_entries: Er zijn geen items zonder labels.
|
||||
untagged: Niet gelabelde items
|
||||
page_title: Labels
|
||||
confirm:
|
||||
delete: Verwijder het label %name%
|
||||
quickstart:
|
||||
support:
|
||||
description: Als je wat hulp kan gebruiken, wij zijn er voor jou.
|
||||
description: Wij zijn er voor u als u hulp nodig heeft.
|
||||
title: Ondersteuning
|
||||
matrix: Op Matrix
|
||||
email: Per e-mail
|
||||
@ -497,26 +456,26 @@ quickstart:
|
||||
docs:
|
||||
all_docs: En zo veel andere artikelen!
|
||||
fetching_errors: Wat kan ik doen als bij het ophalen van een artikel iets fout gaat?
|
||||
search_filters: Bekijk hoe je jouw artikelen kan vinden door middel van zoeken en filteren
|
||||
export: Converteer je artikelen naar ePUB of PDF
|
||||
annotate: Annoteer je artikel
|
||||
search_filters: Bekijk hoe u uw artikelen kan vinden door middel van zoeken en filteren
|
||||
export: Converteer uw artikelen naar ePUB of PDF
|
||||
annotate: Annoteer uw artikel
|
||||
title: Volledige documentatie
|
||||
description: Er zijn zoveel functies in wallabag. Aarzel niet om de handleiding te lezen om ze te leren kennen en te leren hoe u ze kunt gebruiken.
|
||||
developer:
|
||||
use_docker: Gebruiker Docker om wallabag te installeren
|
||||
create_application: Creëer applicaties van derden
|
||||
create_application: Creëer uw applicaties van derden
|
||||
description: 'We hebben ook aan de ontwikkelaars gedacht: Docker, API, vertalingen, etc.'
|
||||
title: Ontwikkelaars
|
||||
migrate:
|
||||
wallabag_v2: Migreren van wallabag v2
|
||||
wallabag_v1: Migreren van wallabag v1
|
||||
description: Gebruik je een andere dienst? Wij helpen je jouw data naar wallabag te halen.
|
||||
description: Gebruikt u een andere dienst? Wij helpen u uw data naar wallabag te halen.
|
||||
title: Migreer van een bestaande dienst
|
||||
instapaper: Migreer van Instapaper
|
||||
readability: Migreer van Readability
|
||||
pocket: Migreer van Pocket
|
||||
first_steps:
|
||||
new_article: Sla je eerste artikel op
|
||||
new_article: Sla uw eerste artikel op
|
||||
unread_articles: En classificeer het!
|
||||
title: Eerste stappen
|
||||
description: Nu wallabag goed is geconfigureerd, is het tijd om het web te archiveren. U kunt op het teken rechtsboven + klikken om een link toe te voegen.
|
||||
@ -526,17 +485,17 @@ quickstart:
|
||||
export: Configureer exporteren
|
||||
analytics: Configureer analytics
|
||||
new_user: Creëer een nieuwe gebruiker
|
||||
description: 'Als een administrator heb je privileges op wallabag. Je kan:'
|
||||
description: 'Als een administrator heeft u privileges op wallabag. U kan:'
|
||||
title: Administratie
|
||||
intro:
|
||||
paragraph_1: We begeleiden je tijdens je bezoek aan wallabag en laten je enkele functies zien die je vast interesseren.
|
||||
paragraph_1: We begeleiden u tijdens uw bezoek aan wallabag en laten u enkele functies zien die u mogelijk interesseren.
|
||||
paragraph_2: Volg ons!
|
||||
title: Welkom bij wallabag!
|
||||
configure:
|
||||
tagging_rules: Schrijf regels om automatisch labels toe te voegen aan artikelen
|
||||
rss: Schakel RSS-feeds in
|
||||
language: Verander taal en uiterlijk
|
||||
description: Om een applicatie te vinden die bij je past kan je een kijkje nemen op de configuratiepagina van wallabag.
|
||||
description: Om een applicatie te vinden die bij u past kan u een kijkje nemen op de configuratiepagina van wallabag.
|
||||
title: Configureer de applicatie
|
||||
feed: Ingeschakelde feeds
|
||||
more: Meer…
|
||||
@ -544,14 +503,14 @@ quickstart:
|
||||
howto:
|
||||
shortcuts:
|
||||
article_title: Snelkoppelingen beschikbaar op startscherm
|
||||
open_article: Toon het geselecteerde artikel
|
||||
open_article: Toon het geselecteerde item
|
||||
arrows_navigation: Navigeer door artikelen
|
||||
hide_form: Verberg het huidige formulier (zoeken of nieuwe link)
|
||||
add_link: Voeg nieuwe link toe
|
||||
delete: Verwijder het artikel
|
||||
toggle_archive: Verander lees status van het artikel
|
||||
toggle_favorite: Wissel met/zonder ster van het artikel
|
||||
open_original: Open originele URL van het artikel
|
||||
delete: Verwijder het item
|
||||
toggle_archive: Verander lees status van het item
|
||||
toggle_favorite: Verander gemarkeerd status van het item
|
||||
open_original: Open originele URL van het item
|
||||
search: Toon het zoekformulier
|
||||
list_title: Snelkoppelingen beschikbaar in overzicht pagina's
|
||||
go_logout: Uitloggen
|
||||
@ -560,9 +519,9 @@ howto:
|
||||
go_import: Ga naar importeren
|
||||
go_config: Ga naar configuratie
|
||||
go_tags: Ga naar labels
|
||||
go_all: Ga naar alle artikelen
|
||||
go_all: Ga naar alle items
|
||||
go_archive: Ga naar gearchiveerd
|
||||
go_starred: Ga naar met ster
|
||||
go_starred: Ga naar gemarkeerd
|
||||
go_unread: Ga naar ongelezen
|
||||
all_pages_title: Snelkoppelingen beschikbaar op alle paginas
|
||||
action: Actie
|
||||
@ -575,7 +534,7 @@ howto:
|
||||
mobile_apps: Mobiele apps
|
||||
browser_addons: Browser plugins
|
||||
bookmarklet:
|
||||
description: 'Sleep deze link naar je bladwijzerbalk:'
|
||||
description: 'Sleep deze link naar uw bladwijzerbalk:'
|
||||
mobile_apps:
|
||||
ios: met de App Store
|
||||
windows: met de Microsoft Store
|
||||
@ -642,7 +601,7 @@ entry:
|
||||
delete: Verwijder
|
||||
re_fetch_content: Opnieuw ophalen van inhoud
|
||||
view_original_article: Origineel artikel
|
||||
set_as_starred: Wissel met/zonder ster
|
||||
set_as_starred: Verander gemarkeerd
|
||||
set_as_unread: Markeer als ongelezen
|
||||
set_as_read: Markeer als gelezen
|
||||
back_to_homepage: Terug
|
||||
@ -658,25 +617,23 @@ entry:
|
||||
reading_time: Geschatte leestijd
|
||||
published_on: Gepubliceerd op
|
||||
confirm:
|
||||
delete_tag: Weet je zeker dat je dit label wilt verwijderen van dit artikel?
|
||||
delete: Weet je zeker dat je dit artikel wilt verwijderen?
|
||||
reload: Weet je zeker dat je dit artikel opnieuw wil ophalen?
|
||||
delete_entries: Weet je zeker dat je deze artikelen wilt verwijderen?
|
||||
delete_tag: Weet u zeker dat u dit label wilt verwijderen van dit artikel?
|
||||
delete: Weet u zeker dat u dit artikel wilt verwijderen?
|
||||
public:
|
||||
shared_by_wallabag: Dit artikel is gedeeld door %username% met <a href='%wallabag_instance%'>wallabag</a>
|
||||
edit:
|
||||
save_label: Opslaan
|
||||
origin_url_label: Oorspronkelijke url (waar je dit artikel gevonden hebt)
|
||||
origin_url_label: Oorspronkelijke url (waar je dit item gevonden hebt)
|
||||
url_label: Url
|
||||
title_label: Titel
|
||||
page_title: Wijzig een artikel
|
||||
page_title: Wijzig een item
|
||||
search:
|
||||
placeholder: Waar ben je naar op zoek?
|
||||
new:
|
||||
form_new:
|
||||
url_label: Url
|
||||
placeholder: http://website.nl
|
||||
page_title: Sla nieuw artikel op
|
||||
page_title: Sla nieuw item op
|
||||
filters:
|
||||
action:
|
||||
filter: Filter
|
||||
@ -697,17 +654,15 @@ entry:
|
||||
preview_picture_help: Voorbeeld afbeelding
|
||||
preview_picture_label: Heeft een voorbeeld afbeelding
|
||||
unread_label: Ongelezen
|
||||
starred_label: Met ster
|
||||
starred_label: Gemarkeerd
|
||||
archived_label: Gearchiveerd
|
||||
status_label: Status
|
||||
title: Filters
|
||||
parsed_label: Niet correct opgehaald
|
||||
annotated_label: Geannoteerd
|
||||
list:
|
||||
export_title: Exporteer
|
||||
delete: Verwijder
|
||||
toogle_as_star: Wissel met/zonder ster
|
||||
toogle_as_read: Als gelezen markeren
|
||||
toogle_as_star: Verander gemarkeerd
|
||||
toogle_as_read: Verander gemarkeerd als gelezen
|
||||
original_article: origineel
|
||||
reading_time_less_one_minute_short: '< 1 min'
|
||||
reading_time_minutes_short: '%readingTime% min'
|
||||
@ -715,24 +670,17 @@ entry:
|
||||
reading_time_less_one_minute: 'geschatte leestijd: < 1 min'
|
||||
reading_time_minutes: 'geschatte leestijd: %readingTime% min'
|
||||
reading_time: geschatte leestijd
|
||||
number_on_the_page: '{0} Er zijn geen artikelen.|{1} Er is één artikel.|]1,Inf[ Er zijn %count% artikelen.'
|
||||
toggle_mass_action: Massaal schakelen actie
|
||||
mass_action_tags_input_placeholder: label1, label2, label3
|
||||
add_tags: Voeg labels toe
|
||||
show_same_domain: Toon artikelen met hetzelfde domein
|
||||
assign_search_tag: Label elke resultaat met deze zoekopdracht
|
||||
number_on_the_page: '{0} Er zijn geen items.|{1} Er is één item.|]1,Inf[ Er zijn %count% items.'
|
||||
page_titles:
|
||||
all: Alle artikelen
|
||||
untagged: Ongelabelde artikelen
|
||||
all: Alle items
|
||||
untagged: Ongelabelde items
|
||||
filtered_search: 'Gefilterd met zoeken:'
|
||||
filtered_tags: 'Gefilterd op labels:'
|
||||
filtered: Gefilterde artikelen
|
||||
archived: Gearchiveerde artikelen
|
||||
starred: Artikelen met ster
|
||||
unread: Ongelezen artikelen
|
||||
with_annotations: Artikelen met annotatie
|
||||
same_domain: Hetzelfde domein
|
||||
default_title: Titel van het artikel
|
||||
filtered: Gefilterde items
|
||||
archived: Gearchiveerde items
|
||||
starred: Gemarkeerde items
|
||||
unread: Ongelezen items
|
||||
default_title: Titel van het item
|
||||
ignore_origin_instance_rule:
|
||||
list:
|
||||
edit_action: Wijzig
|
||||
@ -740,13 +688,13 @@ ignore_origin_instance_rule:
|
||||
create_new_one: Maak een nieuwe algemene regel voor het negeren van de oorsprong
|
||||
no: Nee
|
||||
yes: Ja
|
||||
description: Hier kunt je de algemene regels voor het negeren van oorsprong beheren die worden gebruikt om bepaalde patronen van de oorspronkelijke URL te negeren.
|
||||
description: Hier kunt u de algemene regels voor het negeren van oorsprong beheren die worden gebruikt om bepaalde patronen van de oorspronkelijke URL te negeren.
|
||||
edit_ignore_origin_instance_rule: Bewerk een bestaande regel voor het negeren van de oorsprong
|
||||
new_ignore_origin_instance_rule: Maak een algemene regel voor het negeren van de oorsprong
|
||||
page_title: Globale negeer oorsprongsregels
|
||||
form:
|
||||
back_to_list: Terug naar lijst
|
||||
delete_confirm: Weet je het zeker?
|
||||
delete_confirm: Weet u het zeker?
|
||||
delete: Verwijder
|
||||
save: Opslaan
|
||||
rule_label: Regel
|
||||
|
||||
@ -51,7 +51,7 @@ footer:
|
||||
wallabag:
|
||||
elsewhere: Weż wallabag ze sobą
|
||||
social: Społeczność
|
||||
powered_by: działa dzięki
|
||||
powered_by: Kontrolowany przez
|
||||
about: O nas
|
||||
stats: Od %user_creation% przeczytałeś %nb_archives% artykułów. To jest %per_day% dziennie!
|
||||
config:
|
||||
@ -231,13 +231,13 @@ entry:
|
||||
default_title: Tytuł wpisu
|
||||
page_titles:
|
||||
unread: Nieprzeczytane wpisy
|
||||
starred: Wyróżnione wpisy
|
||||
starred: Wpisy wyróżnione
|
||||
archived: Zarchiwizowane wpisy
|
||||
filtered: Odfiltrowane wpisy
|
||||
filtered_tags: 'Filtrowane po tagach:'
|
||||
filtered_search: 'Filtrowanie po wyszukiwaniu:'
|
||||
untagged: Nieotagowane wpisy
|
||||
all: Wszystkie wpisy
|
||||
all: Wszystkie przedmioty
|
||||
with_annotations: Wpisy z adnotacjami
|
||||
same_domain: Ta sama domena
|
||||
list:
|
||||
@ -557,10 +557,6 @@ import:
|
||||
description: Ten importer zaimportuje wszystkie Twoje artykuły z Omnivore.
|
||||
page_title: Importuj > Omnivore
|
||||
how_to: Rozpakuj eksport z Omnivore, a następnie prześlij po kolei wszystkie pliki JSON o nazwie „metadata_x_to_y.json”.
|
||||
pocket_csv:
|
||||
description: Ten importer zaimportuje wszystkie zakładki Pocket (poprzez eksport CSV). Po prostu przejdź do https://getpocket.com/export, a następnie wyeksportuj plik. Zostanie pobrany plik ZIP (taki jak „pocket.zip”). Wypakuj go, otrzymasz plik CSV o nazwie „part_000000.csv”.
|
||||
page_title: Importuj > Pocket CSV
|
||||
how_to: Wybierz plik kopii zapasowej zakładek i kliknij przycisk poniżej, aby go zaimportować. Należy pamiętać, że proces ten może potrwać długo, ponieważ wszystkie artykuły muszą zostać pobrane.
|
||||
developer:
|
||||
page_title: Zarządzanie klientami API
|
||||
welcome_message: Witaj w API wallabag
|
||||
|
||||
@ -20,7 +20,7 @@ config:
|
||||
tagging_rules_definition_title: “குறிச்சொல் விதிகள்” என்றால் என்ன?
|
||||
tagging_rules_definition_description: அவை புதிய உள்ளீடுகளை தானாகக் குறிக்க வாலபாக் பயன்படுத்தும் விதிகள். <br /> ஒவ்வொரு முறையும் ஒரு புதிய நுழைவு சேர்க்கப்படும்போது, நீங்கள் கட்டமைத்த குறிச்சொற்களைச் சேர்க்க அனைத்து குறிச்சொல் விதிகளும் பயன்படுத்தப்படும், இதனால் உங்கள் உள்ளீடுகளை கைமுறையாக வகைப்படுத்துவதில் சிக்கலைச் சேமிக்கிறது.
|
||||
how_to_use_them_title: அவற்றை எவ்வாறு பயன்படுத்துவது?
|
||||
how_to_use_them_description: 'புதிய உள்ளீடுகளை «<i> குறுகிய வாசிப்பு </i>» எனக் குறிக்க விரும்புகிறீர்கள் என்று வைத்துக் கொள்வோம். வாசிப்பு நேரம் 3 நிமிடங்களுக்குள் இருக்கும்போது. <br /> அந்த விசயத்தில், நீங்கள் «வாசிப்பு நேரத்தை < = 3» <i> விதி </i> புலம் மற்றும் «<i> குறுகிய வாசிப்பு </i>» <i> குறிச்சொற்கள் </i> புலத்தில். <br /> பல குறிச்சொற்கள் ஒரே நேரத்தில் கமாவுடன் பிரிப்பதன் மூலம் சேர்க்கலாம்: «<i> குறுகிய வாசிப்பு, கட்டாயம் படிக்க வேண்டும் </i> »<br /> முன் வரையறுக்கப்பட்ட ஆபரேட்டர்களைப் பயன்படுத்துவதன் மூலம் சிக்கலான விதிகளை எழுதலாம்: என்றால்« <i> வாசிப்பு நேரம் > = 5 மற்றும் டொமைன் பெயர் = "www.php.net" </i> »பின்னர்« <i> நீண்ட வாசிப்பு, பிஎச்பி </i> »எனக் குறிக்கவும்'
|
||||
how_to_use_them_description: 'புதிய உள்ளீடுகளை «<i> குறுகிய வாசிப்பு < /i>» எனக் குறிக்க விரும்புகிறீர்கள் என்று வைத்துக் கொள்வோம். வாசிப்பு நேரம் 3 நிமிடங்களுக்குள் இருக்கும்போது. <br /> அந்த விசயத்தில், நீங்கள் «வாசிப்பு நேரத்தை & lt; = 3» <i> விதி </i> புலம் மற்றும் «<i> குறுகிய வாசிப்பு </i>» <i> குறிச்சொற்கள் </i> புலத்தில். <br /> பல குறிச்சொற்கள் ஒரே நேரத்தில் கமாவுடன் பிரிப்பதன் மூலம் சேர்க்கலாம்: « <i> குறுகிய வாசிப்பு, கட்டாயம் படிக்க வேண்டும் </i> »<br /> முன் வரையறுக்கப்பட்ட ஆபரேட்டர்களைப் பயன்படுத்துவதன் மூலம் சிக்கலான விதிகளை எழுதலாம்: என்றால்« <i> வாசிப்பு நேரம் & gt; = 5 மற்றும் டொமைன் பெயர் = "www.php.net" </i > »பின்னர்« <i> நீண்ட வாசிப்பு, பிஎச்பி </i> »என குறிக்கவும்'
|
||||
variables_available_title: விதிகளை எழுத எந்த மாறிகள் மற்றும் ஆபரேட்டர்கள் நான் பயன்படுத்தலாம்?
|
||||
variables_available_description: 'குறிச்சொல் விதிகளை உருவாக்க பின்வரும் மாறிகள் மற்றும் ஆபரேட்டர்கள் பயன்படுத்தப்படலாம்:'
|
||||
operator_description:
|
||||
@ -33,8 +33,8 @@ config:
|
||||
not_equal_to: சமமாக இல்லை…
|
||||
or: ஒரு விதி அல்லது மற்றொரு
|
||||
and: ஒரு விதி மற்றும் மற்றொரு விதி
|
||||
matches: 'ஒரு <i> பொருள் </i> பொருந்தக்கூடிய சோதனைகள் <i> தேடல் </i> (வழக்கு-உணர்திறன்).<br />எடுத்துக்காட்டு: <code>தலைப்பு போட்டிகள் "கால்பந்து"</code>'
|
||||
notmatches: 'ஒரு <i> பொருள் </i> பொருந்தாத சோதனைகள் ஒரு <i> தேடல் </i> (வழக்கு-பாதுகாப்பற்ற).<br />எடுத்துக்காட்டு: <code>தலைப்பு பெருந்தாதவைகள் "கால்பந்து"</code>'
|
||||
matches: ஒரு <i> பொருள் </i> பொருந்தக்கூடிய சோதனைகள் <i> தேடல் </i> (வழக்கு-உணர்திறன்).
|
||||
notmatches: ஒரு <i> பொருள் </i> பொருந்தாத சோதனைகள் ஒரு <i> தேடல் </is> (வழக்கு-பாதுகாப்பற்ற).
|
||||
then_tag_as_label: பின்னர் குறிக்கவும்
|
||||
delete_rule_label: அழி
|
||||
edit_rule_label: தொகு
|
||||
@ -143,9 +143,9 @@ config:
|
||||
faq:
|
||||
title: கேள்விகள்
|
||||
ignore_origin_rules_definition_title: '"தோற்றம் விதிகளை புறக்கணிக்கவும்" என்றால் என்ன?'
|
||||
ignore_origin_rules_definition_description: திருப்பிவிடப்பட்ட பிறகு ஒரு மூல முகவரியைத் தானாகவே புறக்கணிக்க அவை வாலபாக் பயன்படுத்துகின்றன. <br /> புதிய நுழைவைப் பெறும்போது ஒரு வழிமாற்றல் ஏற்பட்டால், அனைத்து புறக்கணிப்பு மூல விதிகளும் (<i> பயனர் வரையறுக்கப்பட்ட மற்றும் உதாரணமாக வரையறுக்கப்பட்ட </i>) மூல முகவரியைப் புறக்கணிக்கப் பயன்படுத்தப்படும்.
|
||||
ignore_origin_rules_definition_description: திருப்பிவிடப்பட்ட பிறகு ஒரு மூல முகவரியை தானாக புறக்கணிக்க அவை வாலபாக் பயன்படுத்துகின்றன. தோற்றம் முகவரியை புறக்கணிக்கப் பயன்படுகிறது.
|
||||
how_to_use_them_title: அவற்றை எவ்வாறு பயன்படுத்துவது?
|
||||
how_to_use_them_description: «<i> rss.example.com </i>» என்பதிலிருந்து வரும் நுழைவின் தோற்றத்தை நீங்கள் புறக்கணிக்க விரும்புகிறீர்கள் என்று வைத்துக் கொள்வோம்(<i> திருப்பி விடப்பட்ட பிறகு, உண்மையான முகவரி எடுத்துக்காட்டு.காம் </i>). <br />அவ்வாறான நிலையில், நீங்கள் <i> விதி </i> புலத்தில் «புரவலன் =" rss.example.com "ஐ வைக்க வேண்டும்.
|
||||
how_to_use_them_description: «<i> rss.example.com </i>» (<i> திருப்பி விடப்பட்ட பிறகு, உண்மையான முகவரி எடுத்துக்காட்டு.காம் </i> என்பதிலிருந்து வரும் நுழைவின் தோற்றத்தை நீங்கள் புறக்கணிக்க விரும்புகிறீர்கள் என்று வைத்துக் கொள்வோம்) .
|
||||
variables_available_title: விதிகளை எழுத எந்த மாறிகள் மற்றும் ஆபரேட்டர்கள் நான் பயன்படுத்தலாம்?
|
||||
variables_available_description: 'புறக்கணிப்பு தோற்றம் விதிகளை உருவாக்க பின்வரும் மாறிகள் மற்றும் ஆபரேட்டர்கள் பயன்படுத்தப்படலாம்:'
|
||||
meaning: பொருள்
|
||||
@ -156,7 +156,7 @@ config:
|
||||
operator_description:
|
||||
label: ஆபரேட்டர்
|
||||
equal_to: சமமாக…
|
||||
matches: 'ஒரு <i> பொருள் </i> ஒரு <i> தேடல் </i> (வழக்கு-கவர்ச்சியான) உடன் பொருந்துகிறது. <br />எடுத்துக்காட்டு: <code> _all~ "https?://rss.example.com/foobar/.*"</code>'
|
||||
matches: ஒரு <i> பொருள் </i> ஒரு <i> தேடல் </i> (வழக்கு-கவர்ச்சியான) உடன் பொருந்துகிறது. foobar /.*"</ குறியீடு>
|
||||
otp:
|
||||
page_title: இரண்டு காரணி ஏற்பு
|
||||
app:
|
||||
@ -233,14 +233,13 @@ import:
|
||||
elcurator:
|
||||
page_title: இறக்குமதி> எல்குரேட்டர்
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் எல்குரேட்டர் கட்டுரைகள் அனைத்தையும் இறக்குமதி செய்வார்.
|
||||
how_to: உங்கள் எல்குரேட்டர் ஏற்றுமதியைத் தேர்ந்தெடுத்து பதிவேற்றவும் இறக்குமதி செய்யவும் கீழே உள்ள பொத்தானைக் சொடுக்கு செய்க.
|
||||
readability:
|
||||
page_title: இறக்குமதி> வாசிப்பு
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் வாசிப்பு கட்டுரைகள் அனைத்தையும் இறக்குமதி செய்வார்.
|
||||
how_to: உங்கள் வாசிப்பு ஏற்றுமதியைத் தேர்ந்தெடுத்து பதிவேற்றவும் இறக்குமதி செய்யவும் கீழே உள்ள பொத்தானைக் சொடுக்கு செய்க.
|
||||
worker:
|
||||
enabled: 'இறக்குமதி ஒத்திசைவற்ற முறையில் செய்யப்படுகிறது. இறக்குமதி பணி தொடங்கப்பட்டதும், ஒரு வெளிப்புற தொழிலாளி ஒரு நேரத்தில் வேலைகளை கையாள்வார். தற்போதைய சேவை:'
|
||||
download_images_warning: உங்கள் கட்டுரைகளுக்கான படங்களைப் பதிவிறக்குவதற்கு உதவினீர்கள். கிளாசிக் இறக்குமதியுடன் இணைந்து, தொடர பல ஆண்டுகள் ஆகலாம் (அல்லது தோல்வியுற்றிருக்கலாம்). பிழைகளைத் தவிர்க்க ஒத்திசைவற்ற இறக்குமதியை இயக்குவதற்கு நாங்கள் <strong> கடுமையாகப் பரிந்துரைக்கிறோம் </strong>.
|
||||
download_images_warning: உங்கள் கட்டுரைகளுக்கான படங்களை பதிவிறக்குவதற்கு உதவினீர்கள். கிளாசிக் இறக்குமதியுடன் இணைந்து, தொடர பல ஆண்டுகள் ஆகலாம் (அல்லது தோல்வியுற்றிருக்கலாம்). பிழைகளைத் தவிர்க்க ஒத்திசைவற்ற இறக்குமதியை இயக்குவதற்கு நாங்கள் <strong> கடுமையாக பரிந்துரைக்கிறோம் </strong.
|
||||
firefox:
|
||||
page_title: இறக்குமதி> பயர்பாக்ச்
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் பயர்பாக்ச் புக்மார்க்குகளை இறக்குமதி செய்வார். உங்கள் புக்மார்க்குகளுக்கு (Ctrl+Shift+O), பின்னர் "இறக்குமதி மற்றும் காப்புப்பிரதி" க்குச் செல்லுங்கள், "காப்புப்பிரதி…" என்பதைத் தேர்வுசெய்க. நீங்கள் ஒரு சாதொபொகு கோப்பைப் பெறுவீர்கள்.
|
||||
@ -261,14 +260,6 @@ import:
|
||||
page_title: இறக்குமதி> பாக்கெட் உஉகுமொ
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் அனைத்து பாக்கெட் புக்மார்க்குகளையும் (HTML ஏற்றுமதி வழியாக) இறக்குமதி செய்வார். Https://getpocket.com/export க்குச் சென்று, பின்னர் உஉகுமொ கோப்பை ஏற்றுமதி செய்யுங்கள். ஒரு உஉகுமொ கோப்பு பதிவிறக்கம் செய்யப்படும் ("RIL_EXPORT.HTML" போன்றவை).
|
||||
how_to: புக்மார்க்கு காப்புப்பிரதி கோப்பைத் தேர்ந்தெடுத்து அதை இறக்குமதி செய்ய கீழே உள்ள பொத்தானைக் சொடுக்கு செய்க. அனைத்து கட்டுரைகளையும் பெற வேண்டியிருப்பதால் செயல்முறை நீண்ட நேரம் ஆகலாம் என்பதை நினைவில் கொள்க.
|
||||
omnivore:
|
||||
how_to: தயவுசெய்து உங்கள் சர்வவல்லமையுள்ள ஏற்றுமதியை அவிழ்த்து, பின்னர் "மெட்டாடேட்டா_எக்ச்_.டி.இ_ஒய்.சோன்" என்ற பெயரில் ஒவ்வொரு சாதொபொகு கோப்பையும் ஒவ்வொன்றாக பதிவேற்றவும்.
|
||||
page_title: இறக்குமதி> சர்வவல்லவர்
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் சர்வவல்லமையுள்ள அனைத்து கட்டுரைகளையும் இறக்குமதி செய்வார்.
|
||||
pocket_csv:
|
||||
description: இந்த இறக்குமதியாளர் உங்கள் பாக்கெட் புக்மார்க்குகள் (சி.எச்.வி ஏற்றுமதி வழியாக) இறக்குமதி செய்வார். Https://getpocket.com/export க்குச் சென்று, பின்னர் கோப்பை ஏற்றுமதி செய்யுங்கள். ஒரு சிப் கோப்பு பதிவிறக்கம் செய்யப்படும் ("பாக்கெட்.சிப்" போன்றவை). அதைப் பிரித்தெடுக்கவும், "Part_000000.CSV" எனப்படும் காபிம கோப்பைப் பெறுவீர்கள்.
|
||||
how_to: புக்மார்க்கு காப்புப்பிரதி கோப்பைத் தேர்ந்தெடுத்து அதை இறக்குமதி செய்ய கீழே உள்ள பொத்தானைக் சொடுக்கு செய்க. அனைத்து கட்டுரைகளையும் பெற வேண்டியிருப்பதால் செயல்முறை நீண்ட நேரம் ஆகலாம் என்பதை நினைவில் கொள்க.
|
||||
page_title: இறக்குமதி> பாக்கெட் கபிம
|
||||
developer:
|
||||
howto:
|
||||
description:
|
||||
@ -279,7 +270,7 @@ developer:
|
||||
paragraph_4: 'இப்போது, உங்கள் கிள்ளாக்கை உருவாக்கவும் (கிளையன்ட்_ஐடி, கிளையன்ட்_செக்ரெட், பயனர்பெயர் மற்றும் கடவுச்சொல்லை நல்ல மதிப்புகளுடன் மாற்றவும்):'
|
||||
paragraph_6: 'பநிஇ இறுதிப்புள்ளிக்கு அழைப்பு செய்ய அணுகல்_டோகன் பயனுள்ளதாக இருக்கும். உதாரணமாக:'
|
||||
paragraph_7: இந்த அழைப்பு உங்கள் பயனருக்கான அனைத்து உள்ளீடுகளையும் திருப்பித் தரும்.
|
||||
paragraph_8: எல்லா பநிஇ இறுதிப் புள்ளிகளையும் நீங்கள் காண விரும்பினால், <a href="%link%">எங்கள் பநிஇ ஆவணங்களுக்கு </a> ஐப் பார்க்கலாம்.
|
||||
paragraph_8: எல்லா பநிஇ இறுதிப் புள்ளிகளையும் நீங்கள் காண விரும்பினால், எங்கள் பநிஇ ஆவணங்களுக்கு </a> க்கு <a href = "%இணைப்பு%"> ஐப் பார்க்கலாம்.
|
||||
back: பின்
|
||||
page_title: பநிஇ கிளையண்ட்ச் மேனேச்மென்ட்> எனது முதல் பயன்பாட்டை எவ்வாறு உருவாக்குவது
|
||||
page_title: பநிஇ கிளையண்ட்ச் மேலாண்மை
|
||||
@ -391,7 +382,6 @@ flashes:
|
||||
tagging_rules_not_imported: குறிச்சொல் விதிகளை இறக்குமதி செய்யும் போது பிழை
|
||||
ignore_origin_rules_deleted: தோற்ற விதி நீக்கப்பட்டது
|
||||
ignore_origin_rules_updated: தோற்ற விதி புதுப்பிக்கப்பட்டது
|
||||
otp_code_invalid: தவறான இரண்டு காரணி அங்கீகாரக் குறியீடு
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: நுழைவு ஏற்கனவே %தேதியில் சேமிக்கப்பட்டது %
|
||||
@ -618,7 +608,7 @@ howto:
|
||||
description: இந்த படிவத்திற்கு நன்றி
|
||||
browser_addons:
|
||||
firefox: பயர்பாக்ச் addon
|
||||
chrome: நிறமி செருகுநிரல்
|
||||
chrome: Chrome addon
|
||||
opera: ஓபரா துணை
|
||||
mobile_apps:
|
||||
android:
|
||||
@ -707,7 +697,6 @@ quickstart:
|
||||
github: கிட்அப்பில்
|
||||
email: மின்னஞ்சல் மூலம்
|
||||
gitter: கிட்டரில்
|
||||
matrix: மேட்ரிக்சில்
|
||||
tag:
|
||||
confirm:
|
||||
delete: '% பெயர் % குறிச்சொல்லை நீக்கவும்'
|
||||
@ -721,7 +710,7 @@ tag:
|
||||
add: கூட்டு
|
||||
placeholder: கமாவால் பிரிக்கப்பட்ட பல குறிச்சொற்களை நீங்கள் சேர்க்கலாம்.
|
||||
export:
|
||||
footer_template: '<div style="text-align:center;"> <p> %முறையுடன் வாலபாக் தயாரித்த </p> <p> தயவுசெய்து <a href="https://github.com/wallabag/wallabag/issues"> ஒரு சிக்கல் </a>ஐத் திறக்கவும், உங்கள் சாதனத்தில் இந்த மின் புத்தகத்தின் காட்சியில் சிக்கல் இருந்தால். </p> </div>'
|
||||
footer_template: '<div சூல் தண்டு = "text-align: மையம்;"> <p> %முறையுடன் வாலபாக் தயாரித்த </p> <p> தயவுசெய்து <a href = "https://github.com/wallabag/wallabag/issues ஐத் திறக்கவும் "> ஒரு சிக்கல் </a> உங்கள் சாதனத்தில் இந்த மின் புத்தகத்தின் காட்சியில் சிக்கல் இருந்தால். </p> </viv>'
|
||||
unknown: தெரியவில்லை
|
||||
site_credential:
|
||||
page_title: தள நற்சான்றிதழ் மேலாண்மை
|
||||
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -1 +0,0 @@
|
||||
{}
|
||||
@ -2,9 +2,9 @@ auth_code:
|
||||
mailer:
|
||||
body:
|
||||
signature: Het wallabag team
|
||||
support: 'Twijfel niet om contact met ons op te nemen als je problemen ervaart:'
|
||||
support: 'Twijfel niet om contact met ons op te nemen als u problemen ervaart:'
|
||||
second_para: 'Dit is de code:'
|
||||
first_para: Omdat tweestapsverificatie verplicht is voor je wallabag account en een nieuw apparaat dit zojuist gebruikt heeft, sturen we je een code ter verificatie.
|
||||
first_para: Omdat twee-factor-authenticatie verplicht is voor uw wallabag account en een nieuw apparaat dit zojuist gebruikt heeft, sturen we u een code ter verificatie.
|
||||
hello: Hallo %user%,
|
||||
subject: wallabag authenticatiecode
|
||||
on: aan
|
||||
|
||||
Reference in New Issue
Block a user