diff --git a/.editorconfig b/.editorconfig index d4ef73490..92c9a4c35 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,6 +9,6 @@ indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true -[*.css] +[*.{js,css}] indent_style = space indent_size = 2 diff --git a/.eslintrc.json b/.eslintrc.json index 1137e2fc7..3aee614ff 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,11 @@ "extends": "airbnb-base", "parser": "babel-eslint", "env": { - "browser": true + "browser": true, + "es6": true + }, + "globals": { + "Routing": true }, "rules": { "import/no-extraneous-dependencies": ["error", {"devDependencies": true, "optionalDependencies": true, "peerDependencies": true}] diff --git a/.gitignore b/.gitignore index 32b0fbbb5..84fb95d7e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,8 @@ web/uploads/ !web/bundles web/bundles/* !web/bundles/wallabagcore +/web/assets/images/* +!web/assets/images/.gitkeep # Build /app/build @@ -34,7 +36,6 @@ web/bundles/* /composer.phar # Data for wallabag -data/assets/* data/db/wallabag*.sqlite # Docker container logs and data diff --git a/.travis.yml b/.travis.yml index a8f6a7441..8c8093bf4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,6 @@ before_script: - if [[ ! $PHP = hhvm* ]]; then echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi; # xdebug isn't enable for PHP 7.1 - if [[ ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi - - if [[ $PHP = 5.5 ]]; then composer require "phpunit/phpunit:4.*" --no-update; fi; - composer self-update --no-progress - if [[ $DB = pgsql ]]; then psql -c 'create database wallabag_test;' -U postgres; fi; @@ -72,9 +71,9 @@ before_install: script: - travis_wait bash composer install -o --no-interaction --no-progress --prefer-dist - ant prepare-$DB - - if [[ $VALIDATE_TRANSLATION_FILE = '' ]]; then phpunit -v ; fi; + - if [[ $VALIDATE_TRANSLATION_FILE = '' ]]; then ./bin/simple-phpunit -v ; fi; - if [[ $CS_FIXER = run ]]; then php bin/php-cs-fixer fix src/ --verbose --dry-run ; fi; - if [[ $VALIDATE_TRANSLATION_FILE = run ]]; then php bin/console lint:yaml src/Wallabag/CoreBundle/Resources/translations -v ; fi; - if [[ $VALIDATE_TRANSLATION_FILE = run ]]; then php bin/console lint:yaml app/Resources/CraueConfigBundle/translations -v ; fi; - - if [[ $VALIDATE_TRANSLATION_FILE = run ]]; then php bin/console lint:yaml app/Resources/FOSUserBundle/translations -v ; fi; + - if [[ $VALIDATE_TRANSLATION_FILE = run ]]; then php bin/console lint:yaml src/Wallabag/UserBundle/Resources/translations -v ; fi; - if [[ $ASSETS = build ]]; then ./node_modules/grunt-cli/bin/grunt tests; fi; diff --git a/Makefile b/Makefile index 83c5f37ad..b33352616 100755 --- a/Makefile +++ b/Makefile @@ -27,8 +27,7 @@ build: ## Run grunt @grunt test: ## Launch wallabag testsuite - @if [ ! -d "vendor/phpunit" ]; then composer install; fi - @ant prepare && vendor/phpunit/phpunit/phpunit -v + @ant prepare && bin/simple-phpunit -v release: ## Create a package. Need a VERSION parameter (eg: `make release VERSION=master`). ifndef VERSION diff --git a/app/AppKernel.php b/app/AppKernel.php index 52f855585..c8382d5f6 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -29,8 +29,9 @@ class AppKernel extends Kernel new KPhoen\RulerZBundle\KPhoenRulerZBundle(), new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(), new Craue\ConfigBundle\CraueConfigBundle(), - new Lexik\Bundle\MaintenanceBundle\LexikMaintenanceBundle(), new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(), + new FOS\JsRoutingBundle\FOSJsRoutingBundle(), + new BD\GuzzleSiteAuthenticatorBundle\BDGuzzleSiteAuthenticatorBundle(), // wallabag bundles new Wallabag\CoreBundle\WallabagCoreBundle(), diff --git a/app/DoctrineMigrations/Version20160410190541.php b/app/DoctrineMigrations/Version20160410190541.php index f034b0e46..ebf4135f9 100644 --- a/app/DoctrineMigrations/Version20160410190541.php +++ b/app/DoctrineMigrations/Version20160410190541.php @@ -7,6 +7,9 @@ use Doctrine\DBAL\Schema\Schema; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Added foreign keys for account resetting + */ class Version20160410190541 extends AbstractMigration implements ContainerAwareInterface { /** @@ -21,7 +24,7 @@ class Version20160410190541 extends AbstractMigration implements ContainerAwareI private function getTable($tableName) { - return $this->container->getParameter('database_table_prefix') . $tableName; + return $this->container->getParameter('database_table_prefix').$tableName; } /** @@ -29,13 +32,15 @@ class Version20160410190541 extends AbstractMigration implements ContainerAwareI */ public function up(Schema $schema) { - if ($this->connection->getDatabasePlatform()->getName() == 'postgresql') { - $this->addSql('ALTER TABLE "'.$this->getTable('entry').'" ADD uuid UUID DEFAULT NULL'); - } else { - $this->addSql('ALTER TABLE "'.$this->getTable('entry').'" ADD uuid LONGTEXT DEFAULT NULL'); - } + $entryTable = $schema->getTable($this->getTable('entry')); - $this->addSql("INSERT INTO \"".$this->getTable('craue_config_setting')."\" (name, value, section) VALUES ('share_public', '1', 'entry')"); + $this->skipIf($entryTable->hasColumn('uid'), 'It seems that you already played this migration.'); + + $entryTable->addColumn('uid', 'string', [ + 'notnull' => false, + 'length' => 23, + ]); + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('share_public', '1', 'entry')"); } /** @@ -43,9 +48,9 @@ class Version20160410190541 extends AbstractMigration implements ContainerAwareI */ public function down(Schema $schema) { - $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'sqlite', 'This down migration can\'t be executed on SQLite databases, because SQLite don\'t support DROP COLUMN.'); + $entryTable = $schema->getTable($this->getTable('entry')); + $entryTable->dropColumn('uid'); - $this->addSql('ALTER TABLE "'.$this->getTable('entry').'" DROP uuid'); - $this->addSql("DELETE FROM \"".$this->getTable('craue_config_setting')."\" WHERE name = 'share_public'"); + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'share_public'"); } } diff --git a/app/DoctrineMigrations/Version20160812120952.php b/app/DoctrineMigrations/Version20160812120952.php index 3aafea644..bd6e8d636 100644 --- a/app/DoctrineMigrations/Version20160812120952.php +++ b/app/DoctrineMigrations/Version20160812120952.php @@ -7,6 +7,9 @@ use Doctrine\DBAL\Schema\Schema; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Added name field on wallabag_oauth2_clients + */ class Version20160812120952 extends AbstractMigration implements ContainerAwareInterface { /** @@ -21,7 +24,7 @@ class Version20160812120952 extends AbstractMigration implements ContainerAwareI private function getTable($tableName) { - return $this->container->getParameter('database_table_prefix') . $tableName; + return $this->container->getParameter('database_table_prefix').$tableName; } /** @@ -29,16 +32,10 @@ class Version20160812120952 extends AbstractMigration implements ContainerAwareI */ public function up(Schema $schema) { - switch ($this->connection->getDatabasePlatform()->getName()) { - case 'sqlite': - $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext DEFAULT NULL'); - break; - case 'mysql': - $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name longtext COLLATE \'utf8_unicode_ci\' DEFAULT NULL'); - break; - case 'postgresql': - $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' ADD name text DEFAULT NULL'); - } + $clientsTable = $schema->getTable($this->getTable('oauth2_clients')); + $this->skipIf($clientsTable->hasColumn('name'), 'It seems that you already played this migration.'); + + $clientsTable->addColumn('name', 'blob'); } /** @@ -46,8 +43,7 @@ class Version20160812120952 extends AbstractMigration implements ContainerAwareI */ public function down(Schema $schema) { - $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); - - $this->addSql('ALTER TABLE '.$this->getTable('oauth2_clients').' DROP COLUMN name'); + $clientsTable = $schema->getTable($this->getTable('oauth2_clients')); + $clientsTable->dropColumn('name'); } } diff --git a/app/DoctrineMigrations/Version20160911214952.php b/app/DoctrineMigrations/Version20160911214952.php index f14f7bc6f..edef81ed5 100644 --- a/app/DoctrineMigrations/Version20160911214952.php +++ b/app/DoctrineMigrations/Version20160911214952.php @@ -7,6 +7,9 @@ use Doctrine\DBAL\Schema\Schema; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Added settings for RabbitMQ and Redis imports + */ class Version20160911214952 extends AbstractMigration implements ContainerAwareInterface { /** @@ -21,7 +24,7 @@ class Version20160911214952 extends AbstractMigration implements ContainerAwareI private function getTable($tableName) { - return $this->container->getParameter('database_table_prefix') . $tableName; + return $this->container->getParameter('database_table_prefix').$tableName; } /** @@ -29,8 +32,25 @@ class Version20160911214952 extends AbstractMigration implements ContainerAwareI */ public function up(Schema $schema) { - $this->addSql('INSERT INTO "'.$this->getTable('craue_config_setting').'" (name, value, section) VALUES (\'import_with_redis\', \'0\', \'import\')'); - $this->addSql('INSERT INTO "'.$this->getTable('craue_config_setting').'" (name, value, section) VALUES (\'import_with_rabbitmq\', \'0\', \'import\')'); + $redis = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'import_with_redis'"); + + if (false === $redis) { + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('import_with_redis', 0, 'import')"); + } + + $rabbitmq = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'import_with_rabbitmq'"); + + if (false === $rabbitmq) { + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('import_with_rabbitmq', 0, 'import')"); + } + + $this->skipIf(false !== $rabbitmq && false !== $redis, 'It seems that you already played this migration.'); } /** @@ -38,5 +58,7 @@ class Version20160911214952 extends AbstractMigration implements ContainerAwareI */ public function down(Schema $schema) { + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'import_with_redis';"); + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'import_with_rabbitmq';"); } } diff --git a/app/DoctrineMigrations/Version20160916201049.php b/app/DoctrineMigrations/Version20160916201049.php index 0d2edf9ef..9f8e77e73 100644 --- a/app/DoctrineMigrations/Version20160916201049.php +++ b/app/DoctrineMigrations/Version20160916201049.php @@ -7,6 +7,9 @@ use Doctrine\DBAL\Schema\Schema; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Added pocket_consumer_key field on wallabag_config + */ class Version20160916201049 extends AbstractMigration implements ContainerAwareInterface { /** @@ -21,7 +24,7 @@ class Version20160916201049 extends AbstractMigration implements ContainerAwareI private function getTable($tableName) { - return $this->container->getParameter('database_table_prefix') . $tableName; + return $this->container->getParameter('database_table_prefix').$tableName; } /** @@ -29,8 +32,12 @@ class Version20160916201049 extends AbstractMigration implements ContainerAwareI */ public function up(Schema $schema) { - $this->addSql('ALTER TABLE "'.$this->getTable('config').'" ADD pocket_consumer_key VARCHAR(255) DEFAULT NULL'); - $this->addSql("DELETE FROM \"".$this->getTable('craue_config_setting')."\" WHERE name = 'pocket_consumer_key';"); + $configTable = $schema->getTable($this->getTable('config')); + + $this->skipIf($configTable->hasColumn('pocket_consumer_key'), 'It seems that you already played this migration.'); + + $configTable->addColumn('pocket_consumer_key', 'string', ['notnull' => false]); + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'pocket_consumer_key';"); } /** @@ -38,9 +45,8 @@ class Version20160916201049 extends AbstractMigration implements ContainerAwareI */ public function down(Schema $schema) { - $this->abortIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); - - $this->addSql('ALTER TABLE "'.$this->getTable('config').'" DROP pocket_consumer_key'); - $this->addSql("INSERT INTO \"".$this->getTable('craue_config_setting')."\" (name, value, section) VALUES ('pocket_consumer_key', NULL, 'import')"); + $configTable = $schema->getTable($this->getTable('config')); + $configTable->dropColumn('pocket_consumer_key'); + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('pocket_consumer_key', NULL, 'import')"); } } diff --git a/app/DoctrineMigrations/Version20161001072726.php b/app/DoctrineMigrations/Version20161001072726.php new file mode 100644 index 000000000..f247c236f --- /dev/null +++ b/app/DoctrineMigrations/Version20161001072726.php @@ -0,0 +1,127 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $this->skipIf($this->connection->getDatabasePlatform()->getName() == 'sqlite', 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); + + // remove all FK from entry_tag + switch ($this->connection->getDatabasePlatform()->getName()) { + case 'mysql': + $query = $this->connection->query(" + SELECT CONSTRAINT_NAME + FROM information_schema.key_column_usage + WHERE TABLE_NAME = '".$this->getTable('entry_tag')."' AND CONSTRAINT_NAME LIKE 'FK_%' + AND TABLE_SCHEMA = '".$this->connection->getDatabase()."'" + ); + $query->execute(); + + foreach ($query->fetchAll() as $fk) { + $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' DROP FOREIGN KEY '.$fk['CONSTRAINT_NAME']); + } + break; + + case 'postgresql': + // http://dba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk + $query = $this->connection->query(" + SELECT conrelid::regclass AS table_from + ,conname + ,pg_get_constraintdef(c.oid) + FROM pg_constraint c + JOIN pg_namespace n ON n.oid = c.connamespace + WHERE contype = 'f' + AND conrelid::regclass::text = '".$this->getTable('entry_tag')."' + AND n.nspname = 'public';" + ); + $query->execute(); + + foreach ($query->fetchAll() as $fk) { + $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' DROP CONSTRAINT '.$fk['conname']); + } + break; + } + + $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' ADD CONSTRAINT FK_entry_tag_entry FOREIGN KEY (entry_id) REFERENCES '.$this->getTable('entry').' (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE '.$this->getTable('entry_tag').' ADD CONSTRAINT FK_entry_tag_tag FOREIGN KEY (tag_id) REFERENCES '.$this->getTable('tag').' (id) ON DELETE CASCADE'); + + // remove entry FK from annotation + + switch ($this->connection->getDatabasePlatform()->getName()) { + case 'mysql': + $query = $this->connection->query(" + SELECT CONSTRAINT_NAME + FROM information_schema.key_column_usage + WHERE TABLE_NAME = '".$this->getTable('annotation')."' + AND CONSTRAINT_NAME LIKE 'FK_%' + AND COLUMN_NAME = 'entry_id' + AND TABLE_SCHEMA = '".$this->connection->getDatabase()."'" + ); + $query->execute(); + + foreach ($query->fetchAll() as $fk) { + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' DROP FOREIGN KEY '.$fk['CONSTRAINT_NAME']); + } + break; + + case 'postgresql': + // http://dba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk + $query = $this->connection->query(" + SELECT conrelid::regclass AS table_from + ,conname + ,pg_get_constraintdef(c.oid) + FROM pg_constraint c + JOIN pg_namespace n ON n.oid = c.connamespace + WHERE contype = 'f' + AND conrelid::regclass::text = '".$this->getTable('annotation')."' + AND n.nspname = 'public' + AND pg_get_constraintdef(c.oid) LIKE '%entry_id%';" + ); + $query->execute(); + + foreach ($query->fetchAll() as $fk) { + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' DROP CONSTRAINT '.$fk['conname']); + } + break; + } + + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' ADD CONSTRAINT FK_annotation_entry FOREIGN KEY (entry_id) REFERENCES '.$this->getTable('entry').' (id) ON DELETE CASCADE'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + throw new SkipMigrationException('Too complex ...'); + } +} diff --git a/app/DoctrineMigrations/Version20161022134138.php b/app/DoctrineMigrations/Version20161022134138.php new file mode 100644 index 000000000..c71166a00 --- /dev/null +++ b/app/DoctrineMigrations/Version20161022134138.php @@ -0,0 +1,85 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'This migration only apply to MySQL'); + + $this->addSql('ALTER DATABASE '.$this->connection->getParams()['dbname'].' CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;'); + + // convert field length for utf8mb4 + // http://stackoverflow.com/a/31474509/569101 + $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE confirmation_token confirmation_token VARCHAR(180) DEFAULT NULL;'); + $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE salt salt VARCHAR(180) NOT NULL;'); + $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE password password VARCHAR(180) NOT NULL;'); + + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('tag').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('user').' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `text` `text` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `quote` `quote` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `title` `title` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `content` `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('tag').' CHANGE `label` `label` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE `name` `name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $this->skipIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'This migration only apply to MySQL'); + + $this->addSql('ALTER DATABASE '.$this->connection->getParams()['dbname'].' CHARACTER SET = utf8 COLLATE = utf8_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('tag').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('user').' CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `text` `text` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('annotation').' CHANGE `quote` `quote` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `title` `title` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE `content` `content` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('tag').' CHANGE `label` `label` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + + $this->addSql('ALTER TABLE '.$this->getTable('user').' CHANGE `name` `name` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci;'); + } +} diff --git a/app/DoctrineMigrations/Version20161024212538.php b/app/DoctrineMigrations/Version20161024212538.php new file mode 100644 index 000000000..ecb872d10 --- /dev/null +++ b/app/DoctrineMigrations/Version20161024212538.php @@ -0,0 +1,67 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $clientsTable = $schema->getTable($this->getTable('oauth2_clients')); + + $this->skipIf($clientsTable->hasColumn('user_id'), 'It seems that you already played this migration.'); + + $clientsTable->addColumn('user_id', 'integer', ['notnull' => false]); + + $clientsTable->addForeignKeyConstraint( + $this->getTable('user'), + ['user_id'], + ['id'], + ['onDelete' => 'CASCADE'], + $this->constraintName + ); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $clientsTable = $schema->getTable($this->getTable('oauth2_clients')); + + $this->skipIf(!$clientsTable->hasColumn('user_id'), 'It seems that you already played this migration.'); + + $clientsTable->dropColumn('user_id', 'integer'); + + if ($this->connection->getDatabasePlatform()->getName() != 'sqlite') { + $clientsTable->removeForeignKey($this->constraintName); + } + } +} diff --git a/app/DoctrineMigrations/Version20161031132655.php b/app/DoctrineMigrations/Version20161031132655.php new file mode 100644 index 000000000..83b97ca99 --- /dev/null +++ b/app/DoctrineMigrations/Version20161031132655.php @@ -0,0 +1,52 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $images = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'download_images_enabled'"); + + $this->skipIf(false !== $images, 'It seems that you already played this migration.'); + + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('download_images_enabled', 0, 'misc')"); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'download_images_enabled';"); + } +} diff --git a/app/DoctrineMigrations/Version20161104073720.php b/app/DoctrineMigrations/Version20161104073720.php new file mode 100644 index 000000000..fb8f5fa1e --- /dev/null +++ b/app/DoctrineMigrations/Version20161104073720.php @@ -0,0 +1,53 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + $this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); + + $entryTable->addIndex(['created_at'], $this->indexName); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + $this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); + + $entryTable->dropIndex($this->indexName); + } +} diff --git a/app/DoctrineMigrations/Version20161106113822.php b/app/DoctrineMigrations/Version20161106113822.php new file mode 100644 index 000000000..de3702a40 --- /dev/null +++ b/app/DoctrineMigrations/Version20161106113822.php @@ -0,0 +1,56 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $configTable = $schema->getTable($this->getTable('config')); + + $this->skipIf($configTable->hasColumn('action_mark_as_read'), 'It seems that you already played this migration.'); + + $configTable->addColumn('action_mark_as_read', 'integer', [ + 'default' => 0, + 'notnull' => false, + ]); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $configTable = $schema->getTable($this->getTable('config')); + + $this->skipIf(!$configTable->hasColumn('action_mark_as_read'), 'It seems that you already played this migration.'); + + $configTable->dropColumn('action_mark_as_read'); + } +} diff --git a/app/DoctrineMigrations/Version20161117071626.php b/app/DoctrineMigrations/Version20161117071626.php new file mode 100644 index 000000000..8daa2142b --- /dev/null +++ b/app/DoctrineMigrations/Version20161117071626.php @@ -0,0 +1,64 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $share = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'share_unmark'"); + + if (false === $share) { + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('share_unmark', 0, 'entry')"); + } + + $unmark = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'unmark_url'"); + + if (false === $unmark) { + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('unmark_url', 'https://unmark.it', 'entry')"); + } + + $this->skipIf(false !== $share && false !== $unmark, 'It seems that you already played this migration.'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'share_unmark';"); + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'unmark_url';"); + } +} diff --git a/app/DoctrineMigrations/Version20161118134328.php b/app/DoctrineMigrations/Version20161118134328.php new file mode 100644 index 000000000..7b2eeb7bd --- /dev/null +++ b/app/DoctrineMigrations/Version20161118134328.php @@ -0,0 +1,56 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + + $this->skipIf($entryTable->hasColumn('http_status'), 'It seems that you already played this migration.'); + + $entryTable->addColumn('http_status', 'string', [ + 'length' => 3, + 'notnull' => false, + ]); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + + $this->skipIf(!$entryTable->hasColumn('http_status'), 'It seems that you already played this migration.'); + + $entryTable->dropColumn('http_status'); + } +} diff --git a/app/DoctrineMigrations/Version20161122144743.php b/app/DoctrineMigrations/Version20161122144743.php new file mode 100644 index 000000000..388a0e4b0 --- /dev/null +++ b/app/DoctrineMigrations/Version20161122144743.php @@ -0,0 +1,52 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $access = $this->container + ->get('doctrine.orm.default_entity_manager') + ->getConnection() + ->fetchArray('SELECT * FROM '.$this->getTable('craue_config_setting')." WHERE name = 'restricted_access'"); + + $this->skipIf(false !== $access, 'It seems that you already played this migration.'); + + $this->addSql('INSERT INTO '.$this->getTable('craue_config_setting')." (name, value, section) VALUES ('restricted_access', 0, 'entry')"); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $this->addSql('DELETE FROM '.$this->getTable('craue_config_setting')." WHERE name = 'restricted_access';"); + } +} diff --git a/app/DoctrineMigrations/Version20161122203647.php b/app/DoctrineMigrations/Version20161122203647.php new file mode 100644 index 000000000..9b17d6efd --- /dev/null +++ b/app/DoctrineMigrations/Version20161122203647.php @@ -0,0 +1,63 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $userTable = $schema->getTable($this->getTable('user')); + + $this->skipIf(false === $userTable->hasColumn('expired') || false === $userTable->hasColumn('credentials_expired'), 'It seems that you already played this migration.'); + + $userTable->dropColumn('expired'); + $userTable->dropColumn('credentials_expired'); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $userTable = $schema->getTable($this->getTable('user')); + + $this->skipIf(true === $userTable->hasColumn('expired') || true === $userTable->hasColumn('credentials_expired'), 'It seems that you already played this migration.'); + + $userTable->addColumn('expired', 'smallint', ['notnull' => false]); + $userTable->addColumn('credentials_expired', 'smallint', ['notnull' => false]); + } +} diff --git a/app/DoctrineMigrations/Version20161128084725.php b/app/DoctrineMigrations/Version20161128084725.php new file mode 100644 index 000000000..ea370076c --- /dev/null +++ b/app/DoctrineMigrations/Version20161128084725.php @@ -0,0 +1,49 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $configTable = $schema->getTable($this->getTable('config')); + $this->skipIf($configTable->hasColumn('list_mode'), 'It seems that you already played this migration.'); + + $configTable->addColumn('list_mode', 'integer', ['notnull' => false]); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $configTable = $schema->getTable($this->getTable('config')); + $configTable->dropColumn('list_mode'); + } +} diff --git a/app/DoctrineMigrations/Version20161128131503.php b/app/DoctrineMigrations/Version20161128131503.php new file mode 100644 index 000000000..b71aa38bc --- /dev/null +++ b/app/DoctrineMigrations/Version20161128131503.php @@ -0,0 +1,61 @@ + 'smallint', + 'credentials_expire_at' => 'datetime', + 'expires_at' => 'datetime', + ]; + + /** + * @var ContainerInterface + */ + private $container; + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $userTable = $schema->getTable($this->getTable('user')); + + foreach ($this->fields as $field => $type) { + $this->skipIf(!$userTable->hasColumn($field), 'It seems that you already played this migration.'); + $userTable->dropColumn($field); + } + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $userTable = $schema->getTable($this->getTable('user')); + + foreach ($this->fields as $field => $type) { + $this->skipIf($userTable->hasColumn($field), 'It seems that you already played this migration.'); + $userTable->addColumn($field, $type, ['notnull' => false]); + } + } +} diff --git a/app/DoctrineMigrations/Version20161214094402.php b/app/DoctrineMigrations/Version20161214094402.php new file mode 100644 index 000000000..db125f763 --- /dev/null +++ b/app/DoctrineMigrations/Version20161214094402.php @@ -0,0 +1,75 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + + $this->skipIf($entryTable->hasColumn('uid'), 'It seems that you already played this migration.'); + + switch ($this->connection->getDatabasePlatform()->getName()) { + case 'sqlite': + $this->addSql('CREATE TEMPORARY TABLE __temp__wallabag_entry AS SELECT id, user_id, uuid, title, url, is_archived, is_starred, content, created_at, updated_at, mimetype, language, reading_time, domain_name, preview_picture, is_public FROM '.$this->getTable('entry')); + $this->addSql('DROP TABLE '.$this->getTable('entry')); + $this->addSql('CREATE TABLE '.$this->getTable('entry').' (id INTEGER NOT NULL, user_id INTEGER DEFAULT NULL, uid CLOB DEFAULT NULL COLLATE BINARY, title CLOB DEFAULT NULL COLLATE BINARY, url CLOB DEFAULT NULL COLLATE BINARY, is_archived BOOLEAN NOT NULL, is_starred BOOLEAN NOT NULL, content CLOB DEFAULT NULL COLLATE BINARY, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, mimetype CLOB DEFAULT NULL COLLATE BINARY, language CLOB DEFAULT NULL COLLATE BINARY, reading_time INTEGER DEFAULT NULL, domain_name CLOB DEFAULT NULL COLLATE BINARY, preview_picture CLOB DEFAULT NULL COLLATE BINARY, is_public BOOLEAN DEFAULT "0", PRIMARY KEY(id));'); + $this->addSql('INSERT INTO '.$this->getTable('entry').' (id, user_id, uid, title, url, is_archived, is_starred, content, created_at, updated_at, mimetype, language, reading_time, domain_name, preview_picture, is_public) SELECT id, user_id, uuid, title, url, is_archived, is_starred, content, created_at, updated_at, mimetype, language, reading_time, domain_name, preview_picture, is_public FROM __temp__wallabag_entry;'); + $this->addSql('DROP TABLE __temp__wallabag_entry'); + break; + case 'mysql': + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE uuid uid VARCHAR(23)'); + break; + case 'postgresql': + $this->addSql('ALTER TABLE '.$this->getTable('entry').' RENAME uuid TO uid'); + } + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + + $this->skipIf($entryTable->hasColumn('uuid'), 'It seems that you already played this migration.'); + + switch ($this->connection->getDatabasePlatform()->getName()) { + case 'sqlite': + throw new SkipMigrationException('Too complex ...'); + break; + case 'mysql': + $this->addSql('ALTER TABLE '.$this->getTable('entry').' CHANGE uid uuid VARCHAR(23)'); + break; + case 'postgresql': + $this->addSql('ALTER TABLE '.$this->getTable('entry').' RENAME uid TO uuid'); + } + } +} diff --git a/app/DoctrineMigrations/Version20161214094403.php b/app/DoctrineMigrations/Version20161214094403.php new file mode 100644 index 000000000..5948b5fa5 --- /dev/null +++ b/app/DoctrineMigrations/Version20161214094403.php @@ -0,0 +1,53 @@ +container = $container; + } + + private function getTable($tableName) + { + return $this->container->getParameter('database_table_prefix').$tableName; + } + + /** + * @param Schema $schema + */ + public function up(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + $this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); + + $entryTable->addIndex(['uid'], $this->indexName); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema) + { + $entryTable = $schema->getTable($this->getTable('entry')); + $this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); + + $entryTable->dropIndex($this->indexName); + } +} diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml index 3e11d675c..c65463dba 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Download billeder på din server carrot: Aktiver deling til Carrot diaspora_url: Diaspora URL, hvis tjenesten er aktiv @@ -15,6 +16,7 @@ share_diaspora: Aktiver deling til Diaspora share_mail: Aktiver deling med email share_shaarli: Aktiver deling gennem Shaarli share_twitter: Aktiver deling gennem Twitter +share_unmark: Aktiver deling gennem Unmark.it show_printlink: Vis et link til print-indhold wallabag_support_url: Support-URL for wallabag wallabag_url: URL for *sin* wallabag-installation @@ -29,3 +31,5 @@ piwik_enabled: Aktiver Piwik demo_mode_enabled: "Aktiver demo-indstilling? (anvendes kun til wallabags offentlige demo)" demo_mode_username: "Demobruger" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml index c74b5c1ff..bc378147b 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Bilder auf den Server herunterladen carrot: Teilen zu Carrot aktivieren diaspora_url: Diaspora-URL, sofern der Service aktiviert ist @@ -15,6 +16,7 @@ share_diaspora: Teilen zu Diaspora aktiveren share_mail: Teilen via E-Mail aktiveren share_shaarli: Teilen zu Shaarli aktiveren share_twitter: Teilen zu Twitter aktiveren +share_unmark: Teilen zu Unmark.it aktiveren show_printlink: Link anzeigen, um den Inhalt auszudrucken wallabag_support_url: Support-URL für wallabag wallabag_url: URL von *deiner* wallabag-Instanz @@ -29,3 +31,5 @@ piwik_enabled: Piwik aktivieren demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-Demo genutzt)" demo_mode_username: "Test-Benutzer" share_public: Erlaube eine öffentliche URL für Einträge +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml index 77c09db43..52cb8e202 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml @@ -1,3 +1,4 @@ +settings_changed: Configuration updated download_pictures: Download pictures on your server carrot: Enable share to Carrot diaspora_url: Diaspora URL, if the service is enabled @@ -15,6 +16,7 @@ share_diaspora: Enable share to Diaspora share_mail: Enable share by email share_shaarli: Enable share to Shaarli share_twitter: Enable share to Twitter +share_unmark: Enable share to Unmark.it show_printlink: Display a link to print content wallabag_support_url: Support URL for wallabag wallabag_url: URL of *your* wallabag instance @@ -29,3 +31,5 @@ piwik_enabled: Enable Piwik demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)" demo_mode_username: "Demo user" share_public: Allow public url for entries +download_images_enabled: Download images locally +restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml index baa838493..dbec0e818 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Descargar imágenes carrot: Activar compartir con Carrot diaspora_url: Diaspora URL, si el servicio está activado @@ -15,6 +16,7 @@ share_diaspora: Activar compartir con Diaspora share_mail: Activar compartir con email share_shaarli: Activar compartir con Shaarli share_twitter: Activar compartir con Twitter +share_unmark: Activar compartir con Unmark.it show_printlink: Mostrar un enlace para imprimir contenido wallabag_support_url: URL de soporte de wallabag wallabag_url: URL de *tu* instancia de wallabag @@ -29,3 +31,5 @@ piwik_enabled: Activar Piwik demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)" demo_mode_username: "Nombre de usuario demo" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml index b394977e2..7a341e0b7 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: تصاویر را در کارگزار خودتان باربگیرید carrot: فعالسازی همرسانی به Carrot diaspora_url: نشانی Diaspora، اگر فعال بود @@ -15,6 +16,7 @@ share_diaspora: فعالسازی همرسانی به Diaspora share_mail: فعالسازی همرسانی با ایمیل share_shaarli: فعالسازی همرسانی به Shaarli share_twitter: فعالسازی همرسانی به Twitter +share_unmark: فعالسازی همرسانی به Unmark.it show_printlink: نمایش پیوندی برای چاپ مطلب wallabag_support_url: نشانی صفحهٔ پشتیبانی wallabag wallabag_url: نشانی صفحهٔ wallabag *شما* @@ -29,3 +31,5 @@ modify_settings: "اعمال" # demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)" # demo_mode_username: "Demo user" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml index 31a808804..f5c886d6e 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml @@ -1,3 +1,4 @@ +settings_changed: Configuration mise à jour download_pictures: Télécharger les images sur le serveur carrot: Activer le partage vers Carrot diaspora_url: URL de Diaspora, si le service Diaspora est activé @@ -15,6 +16,7 @@ share_diaspora: Activer le partage vers Diaspora share_mail: Activer le partage par email share_shaarli: Activer le partage vers Shaarli share_twitter: Activer le partage vers Twitter +share_unmark: Activer le partage vers Unmark.it show_printlink: Afficher un lien pour imprimer wallabag_support_url: URL de support de wallabag wallabag_url: URL de *votre* instance de wallabag @@ -29,3 +31,5 @@ piwik_enabled: Activer Piwik demo_mode_enabled: "Activer le mode démo ? (utiliser uniquement pour la démo publique de wallabag)" demo_mode_username: "Utilisateur de la démo" share_public: Autoriser une URL publique pour les articles +download_images_enabled: Télécharger les images en local +restricted_access: Activer l'authentification pour les articles derrière un paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml index ba0385561..88a1b4f6f 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Scarica le immagini sul tuo server carrot: Abilita la condivisione con Carrot diaspora_url: Diaspora URL, se il servizio è abilitato @@ -15,6 +16,7 @@ share_diaspora: Abilita la condivisione con Diaspora share_mail: Abilita la condivisione per email share_shaarli: Abilita la condivisione con Shaarli share_twitter: Abilita la condivisione con Twitter +share_unmark: Abilita la condivisione con Unmark.it show_printlink: Mostra un collegamento per stampare il contenuto wallabag_support_url: URL di supporto per wallabag wallabag_url: URL della *tua* installazione di wallabag @@ -29,3 +31,5 @@ piwik_enabled: Abilita Piwik demo_mode_enabled: "Abilita modalità demo ? (usato solo per la demo pubblica di wallabag)" demo_mode_username: "Utente Demo" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml index 55249e33b..00deeade0 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Telecargar los imatges sul servidor carrot: Activar lo partatge cap a Carrot diaspora_url: URL de Diaspora, se lo servici Diaspora es activat @@ -15,6 +16,7 @@ share_diaspora: Activar lo partatge cap a Diaspora share_mail: Activar lo partatge per corrièl share_shaarli: Activar lo partatge cap a Shaarli share_twitter: Activar lo partatge cap a Twitter +share_unmark: Activar lo partatge cap a Unmark.it show_printlink: Afichar un ligam per imprimir wallabag_support_url: URL d'assisténcia de wallabag wallabag_url: URL de *vòstra* instància de wallabag @@ -29,3 +31,5 @@ piwik_enabled: Activar Piwik demo_mode_enabled: "Activar lo mode demostracion ? (utilizar solament per la demostracion publica de wallabag)" demo_mode_username: "Utilizaire de la demostracion" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml index 42cc5b525..744031e8e 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Pobierz obrazy na swój serwer carrot: Włącz udostępnianie dla Carrot diaspora_url: Adres URL Diaspora, jeżeli usługa jest włączona @@ -15,6 +16,7 @@ share_diaspora: Włącz udostępnianie dla Diaspora share_mail: Włącz udostępnianie przez email share_shaarli: Włącz udostępnianie dla Shaarli share_twitter: Włącz udostępnianie dla Twitter +share_unmark: Włącz udostępnianie dla Unmark.it show_printlink: Pokaż link do wydrukowania zawartości wallabag_support_url: Adres URL wsparcia dla wallabag wallabag_url: Adres *twojej* instacji wallabag @@ -29,3 +31,5 @@ piwik_enabled: Włacz Piwik demo_mode_enabled: "Włacz tryb demo? (używany wyłącznie dla publicznej demonstracji Wallabag)" demo_mode_username: "Użytkownik Demonstracyjny" share_public: Zezwalaj na publiczny adres url dla wpisow +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml index e82604220..1edde87ac 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Download imagens no seu servidor carrot: Habilitar compartilhamento para o Carrot diaspora_url: URL Diaspora, se o serviço está habilitado @@ -8,12 +9,14 @@ export_csv: Habilita exportação para CSV export_json: Habilita exportação para JSON export_txt: Habilita exportação para TXT export_xml: Habilita exportação para XML -pocket_consumer_key: Chave de consumidor do Pocket para importar conteúdo (https://getpocket.com/developer/docs/authentication) +# import_with_rabbitmq: Enable RabbitMQ to import data asynchronously +# import_with_redis: Enable Redis to import data asynchronously shaarli_url: URL Shaarli, se o serviço está habilitado share_diaspora: Habilitar compartilhamento para o Diaspora share_mail: Habilitar compartilhamento por e-mail share_shaarli: Habilitar compartilhamento para o Shaarli share_twitter: Habilitar compartilhamento para o Twitter +share_unmark: Habilitar compartilhamento para o Unmark.it show_printlink: Mostrar um link para imprimir o conteúdo wallabag_support_url: URL de Suporte do wallabag wallabag_url: URL de *sua* instância do wallabag @@ -27,3 +30,6 @@ piwik_site_id: ID de seu website Piwik piwik_enabled: Habilitar Piwik demo_mode_enabled: "Habilitar modo demo? (somente usado para o demo público do wallabag)" demo_mode_username: "Usuário demo" +# share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml index 8e72b9555..f0c935d3f 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Descarcă poze pe server carrot: Permite share către Carrot diaspora_url: Diaspora URL, dacă serviciul este permis @@ -15,6 +16,7 @@ share_diaspora: Permite share către Diaspora share_mail: Permite share prin email share_shaarli: Permite share către Shaarli share_twitter: Permite share către Twitter +share_unmark: Permite share către Unmark.it show_printlink: Afișează un link pentru a printa content-ul wallabag_support_url: URL-ul de suport pentru wallabag wallabag_url: URL-ul instanței tale wallabag @@ -29,3 +31,5 @@ modify_settings: "aplică" # demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)" # demo_mode_username: "Demo user" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml index 55f708433..eb40fc5ed 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated # download_pictures: Download pictures on your server # carrot: Enable share to Carrot # diaspora_url: Diaspora URL, if the service is enabled @@ -15,6 +16,7 @@ # share_mail: Enable share by email # share_shaarli: Enable share to Shaarli # share_twitter: Enable share to Twitter +# share_unmark: Enable share to Unmark.it # show_printlink: Display a link to print content # wallabag_support_url: Support URL for wallabag # wallabag_url: URL of *your* wallabag instance @@ -29,3 +31,5 @@ # demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)" # demo_mode_username: "Demo user" # share_public: Allow public url for entries +# download_images_enabled: Download images locally +# restricted_access: Enable authentication for websites with paywall diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.da.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.da.yml deleted file mode 100644 index 015989ef1..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.da.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Log ind" -Enter your email address below and we'll send you password reset instructions.: "Indtast din emailadresse nedenfor, så sender vi dig instrukser til at nulstille din adgangskode." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.de.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.de.yml deleted file mode 100644 index 944a0d416..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.de.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Anmelden" -Enter your email address below and we'll send you password reset instructions.: "Tippe deine E-Mail-Adresse unten ein und wir senden dir die Anweisungen, wie du dein Kennwort zurücksetzen kannst." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml deleted file mode 100644 index 968eb2416..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Logearse" -Enter your email address below and we'll send you password reset instructions.: "Introduzca su dirección de email y le enviaremos las instrucciones para resetear su contraseña." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.fr.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.fr.yml deleted file mode 100644 index 1c5ea6400..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.fr.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Se connecter" -Enter your email address below and we'll send you password reset instructions.: "Renseignez votre adresse courriel, nous vous enverrons les instructions pour réinitialiser votre mot de passe." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.oc.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.oc.yml deleted file mode 100644 index b8a751723..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.oc.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Se connectar" -Enter your email address below and we'll send you password reset instructions.: "Picatz vòstra adreça de corrièl çai-jos, vos mandarem las instruccions per reïnicializar vòstre senhal." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.pl.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.pl.yml deleted file mode 100644 index 7e0a24904..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.pl.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Logowanie" -Enter your email address below and we'll send you password reset instructions.: "Wpisz poniżej swój adres email, abyśmy mogli wysłać ci instrukcję resetowania hasła." diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.pt.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.pt.yml deleted file mode 100644 index 85eadfd87..000000000 --- a/app/Resources/FOSUserBundle/translations/FOSUserBundle.pt.yml +++ /dev/null @@ -1,2 +0,0 @@ -Login: "Login" -Enter your email address below and we'll send you password reset instructions.: "Digite seu endereço de e-mail para enviarmos as instruções de recupeção de sua senha." diff --git a/app/Resources/static/themes/_global/img/icons/unmark-icon--black.png b/app/Resources/static/themes/_global/img/icons/unmark-icon--black.png new file mode 100644 index 000000000..45f679eec Binary files /dev/null and b/app/Resources/static/themes/_global/img/icons/unmark-icon--black.png differ diff --git a/app/Resources/static/themes/_global/img/list.png b/app/Resources/static/themes/_global/img/list.png new file mode 100755 index 000000000..bd5aff5ae Binary files /dev/null and b/app/Resources/static/themes/_global/img/list.png differ diff --git a/app/Resources/static/themes/_global/img/table.png b/app/Resources/static/themes/_global/img/table.png new file mode 100755 index 000000000..859c4cd8f Binary files /dev/null and b/app/Resources/static/themes/_global/img/table.png differ diff --git a/app/Resources/static/themes/_global/js/bookmarklet.js b/app/Resources/static/themes/_global/js/bookmarklet.js index 5174ff472..a497628b2 100644 --- a/app/Resources/static/themes/_global/js/bookmarklet.js +++ b/app/Resources/static/themes/_global/js/bookmarklet.js @@ -1,4 +1,3 @@ - top['bookmarklet-url@wallabag.org'] = '
Unable to retrieve readable content.
'; + $html = $this->fetchingErrorMessage; if (isset($content['open_graph']['og_description'])) { $html .= 'But we found a short description:
'; @@ -69,8 +77,10 @@ class ContentProxy $entry->setUrl($content['url'] ?: $url); $entry->setTitle($title); $entry->setContent($html); - $entry->setLanguage($content['language']); - $entry->setMimetype($content['content_type']); + $entry->setHttpStatus(isset($content['status']) ? $content['status'] : ''); + + $entry->setLanguage(isset($content['language']) ? $content['language'] : ''); + $entry->setMimetype(isset($content['content_type']) ? $content['content_type'] : ''); $entry->setReadingTime(Utils::getReadingTime($html)); $domainName = parse_url($entry->getUrl(), PHP_URL_HOST); @@ -78,12 +88,12 @@ class ContentProxy $entry->setDomainName($domainName); } - if (isset($content['open_graph']['og_image'])) { + if (isset($content['open_graph']['og_image']) && $content['open_graph']['og_image']) { $entry->setPreviewPicture($content['open_graph']['og_image']); } // if content is an image define as a preview too - if (in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { + if (isset($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { $entry->setPreviewPicture($content['url']); } diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php new file mode 100644 index 000000000..c83f96187 --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php @@ -0,0 +1,233 @@ +client = $client; + $this->baseFolder = $baseFolder; + $this->wallabagUrl = rtrim($wallabagUrl, '/'); + $this->logger = $logger; + $this->mimeGuesser = new MimeTypeExtensionGuesser(); + + $this->setFolder(); + } + + /** + * Setup base folder where all images are going to be saved. + */ + private function setFolder() + { + // if folder doesn't exist, attempt to create one and store the folder name in property $folder + if (!file_exists($this->baseFolder)) { + mkdir($this->baseFolder, 0755, true); + } + } + + /** + * Process the html and extract image from it, save them to local and return the updated html. + * + * @param int $entryId ID of the entry + * @param string $html + * @param string $url Used as a base path for relative image and folder + * + * @return string + */ + public function processHtml($entryId, $html, $url) + { + $crawler = new Crawler($html); + $result = $crawler + ->filterXpath('//img') + ->extract(array('src')); + + $relativePath = $this->getRelativePath($entryId); + + // download and save the image to the folder + foreach ($result as $image) { + $imagePath = $this->processSingleImage($entryId, $image, $url, $relativePath); + + if (false === $imagePath) { + continue; + } + + $html = str_replace($image, $imagePath, $html); + } + + return $html; + } + + /** + * Process a single image: + * - retrieve it + * - re-saved it (for security reason) + * - return the new local path. + * + * @param int $entryId ID of the entry + * @param string $imagePath Path to the image to retrieve + * @param string $url Url from where the image were found + * @param string $relativePath Relative local path to saved the image + * + * @return string Relative url to access the image from the web + */ + public function processSingleImage($entryId, $imagePath, $url, $relativePath = null) + { + if (null === $relativePath) { + $relativePath = $this->getRelativePath($entryId); + } + + $this->logger->debug('DownloadImages: working on image: '.$imagePath); + + $folderPath = $this->baseFolder.'/'.$relativePath; + + // build image path + $absolutePath = $this->getAbsoluteLink($url, $imagePath); + if (false === $absolutePath) { + $this->logger->error('DownloadImages: Can not determine the absolute path for that image, skipping.'); + + return false; + } + + try { + $res = $this->client->get($absolutePath); + } catch (\Exception $e) { + $this->logger->error('DownloadImages: Can not retrieve image, skipping.', ['exception' => $e]); + + return false; + } + + $ext = $this->mimeGuesser->guess($res->getHeader('content-type')); + $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); + if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) { + $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping '.$imagePath); + + return false; + } + $hashImage = hash('crc32', $absolutePath); + $localPath = $folderPath.'/'.$hashImage.'.'.$ext; + + try { + $im = imagecreatefromstring($res->getBody()); + } catch (\Exception $e) { + $im = false; + } + + if (false === $im) { + $this->logger->error('DownloadImages: Error while regenerating image', ['path' => $localPath]); + + return false; + } + + switch ($ext) { + case 'gif': + imagegif($im, $localPath); + $this->logger->debug('DownloadImages: Re-creating gif'); + break; + case 'jpeg': + case 'jpg': + imagejpeg($im, $localPath, self::REGENERATE_PICTURES_QUALITY); + $this->logger->debug('DownloadImages: Re-creating jpg'); + break; + case 'png': + imagepng($im, $localPath, ceil(self::REGENERATE_PICTURES_QUALITY / 100 * 9)); + $this->logger->debug('DownloadImages: Re-creating png'); + } + + imagedestroy($im); + + return $this->wallabagUrl.'/assets/images/'.$relativePath.'/'.$hashImage.'.'.$ext; + } + + /** + * Remove all images for the given entry id. + * + * @param int $entryId ID of the entry + */ + public function removeImages($entryId) + { + $relativePath = $this->getRelativePath($entryId); + $folderPath = $this->baseFolder.'/'.$relativePath; + + $finder = new Finder(); + $finder + ->files() + ->ignoreDotFiles(true) + ->in($folderPath); + + foreach ($finder as $file) { + @unlink($file->getRealPath()); + } + + @rmdir($folderPath); + } + + /** + * Generate the folder where we are going to save images based on the entry url. + * + * @param int $entryId ID of the entry + * + * @return string + */ + private function getRelativePath($entryId) + { + $hashId = hash('crc32', $entryId); + $relativePath = $hashId[0].'/'.$hashId[1].'/'.$hashId; + $folderPath = $this->baseFolder.'/'.$relativePath; + + if (!file_exists($folderPath)) { + mkdir($folderPath, 0777, true); + } + + $this->logger->debug('DownloadImages: Folder used for that Entry id', ['folder' => $folderPath, 'entryId' => $entryId]); + + return $relativePath; + } + + /** + * Make an $url absolute based on the $base. + * + * @see Graby->makeAbsoluteStr + * + * @param string $base Base url + * @param string $url Url to make it absolute + * + * @return false|string + */ + private function getAbsoluteLink($base, $url) + { + if (preg_match('!^https?://!i', $url)) { + // already absolute + return $url; + } + + $base = new \SimplePie_IRI($base); + + // remove '//' in URL path (causes URLs not to resolve properly) + if (isset($base->ipath)) { + $base->ipath = preg_replace('!//+!', '/', $base->ipath); + } + + if ($absolute = \SimplePie_IRI::absolutize($base, $url)) { + return $absolute->get_uri(); + } + + $this->logger->error('DownloadImages: Can not make an absolute link', ['base' => $base, 'url' => $url]); + + return false; + } +} diff --git a/src/Wallabag/CoreBundle/Helper/EntriesExport.php b/src/Wallabag/CoreBundle/Helper/EntriesExport.php index 4bf292a4f..93c01fcb4 100644 --- a/src/Wallabag/CoreBundle/Helper/EntriesExport.php +++ b/src/Wallabag/CoreBundle/Helper/EntriesExport.php @@ -89,6 +89,11 @@ class EntriesExport throw new \InvalidArgumentException(sprintf('The format "%s" is not yet supported.', $format)); } + public function exportJsonData() + { + return $this->prepareSerializingContent('json'); + } + /** * Use PHPePub to dump a .epub file. * diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php new file mode 100644 index 000000000..8891887b6 --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php @@ -0,0 +1,54 @@ +authenticatorSubscriber = $authenticatorSubscriber; + $this->cookieJar = $cookieJar; + $this->restrictedAccess = $restrictedAccess; + } + + /** + * @return \GuzzleHttp\Client|null + */ + public function buildHttpClient() + { + if (0 === (int) $this->restrictedAccess) { + return null; + } + + // we clear the cookie to avoid websites who use cookies for analytics + $this->cookieJar->clear(); + // need to set the (shared) cookie jar + $client = new Client(['handler' => new SafeCurlHandler(), 'defaults' => ['cookies' => $this->cookieJar]]); + $client->getEmitter()->attach($this->authenticatorSubscriber); + + return $client; + } +} diff --git a/src/Wallabag/CoreBundle/Helper/Redirect.php b/src/Wallabag/CoreBundle/Helper/Redirect.php index c14c79d11..f78b7fe0d 100644 --- a/src/Wallabag/CoreBundle/Helper/Redirect.php +++ b/src/Wallabag/CoreBundle/Helper/Redirect.php @@ -3,6 +3,8 @@ namespace Wallabag\CoreBundle\Helper; use Symfony\Component\Routing\Router; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Wallabag\CoreBundle\Entity\Config; /** * Manage redirections to avoid redirecting to empty routes. @@ -10,10 +12,12 @@ use Symfony\Component\Routing\Router; class Redirect { private $router; + private $tokenStorage; - public function __construct(Router $router) + public function __construct(Router $router, TokenStorageInterface $tokenStorage) { $this->router = $router; + $this->tokenStorage = $tokenStorage; } /** @@ -24,6 +28,16 @@ class Redirect */ public function to($url, $fallback = '') { + $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; + + if (null === $user || !is_object($user)) { + return $url; + } + + if (Config::REDIRECT_TO_HOMEPAGE === $user->getConfig()->getActionMarkAsRead()) { + return $this->router->generate('homepage'); + } + if (null !== $url) { return $url; } diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 4f03ae0f1..b9532fa25 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -20,8 +20,7 @@ class EntryRepository extends EntityRepository private function getBuilderByUser($userId) { return $this->createQueryBuilder('e') - ->leftJoin('e.user', 'u') - ->andWhere('u.id = :userId')->setParameter('userId', $userId) + ->andWhere('e.user = :userId')->setParameter('userId', $userId) ->orderBy('e.createdAt', 'desc') ; } @@ -85,6 +84,36 @@ class EntryRepository extends EntityRepository ; } + /** + * Retrieves entries filtered with a search term for a user. + * + * @param int $userId + * @param string $term + * @param strint $currentRoute + * + * @return QueryBuilder + */ + public function getBuilderForSearchByUser($userId, $term, $currentRoute) + { + $qb = $this + ->getBuilderByUser($userId); + + if ('starred' === $currentRoute) { + $qb->andWhere('e.isStarred = true'); + } elseif ('unread' === $currentRoute) { + $qb->andWhere('e.isArchived = false'); + } elseif ('archive' === $currentRoute) { + $qb->andWhere('e.isArchived = true'); + } + + $qb + ->andWhere('e.content LIKE :term OR e.title LIKE :term')->setParameter('term', '%'.$term.'%') + ->leftJoin('e.tags', 't') + ->groupBy('e.id'); + + return $qb; + } + /** * Retrieves untagged entries for a user. * @@ -96,9 +125,7 @@ class EntryRepository extends EntityRepository { return $this ->getBuilderByUser($userId) - ->leftJoin('e.tags', 't') - ->groupBy('e.id') - ->having('count(t.id) = 0'); + ->andWhere('size(e.tags) = 0'); } /** @@ -144,7 +171,7 @@ class EntryRepository extends EntityRepository $qb->orderBy('e.updatedAt', $order); } - $pagerAdapter = new DoctrineORMAdapter($qb); + $pagerAdapter = new DoctrineORMAdapter($qb, true, false); return new Pagerfanta($pagerAdapter); } @@ -329,4 +356,18 @@ class EntryRepository extends EntityRepository return $qb->getQuery()->getSingleScalarResult(); } + + /** + * Remove all entries for a user id. + * Used when a user want to reset all informations. + * + * @param int $userId + */ + public function removeAllByUserId($userId) + { + $this->getEntityManager() + ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = :userId') + ->setParameter('userId', $userId) + ->execute(); + } } diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index e76878d49..2182df254 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php @@ -34,6 +34,9 @@ class TagRepository extends EntityRepository /** * Find all tags per user. + * Instead of just left joined on the Entry table, we select only id and group by id to avoid tag multiplication in results. + * Once we have all tags id, we can safely request them one by one. + * This'll still be fastest than the previous query. * * @param int $userId * @@ -41,15 +44,21 @@ class TagRepository extends EntityRepository */ public function findAllTags($userId) { - return $this->createQueryBuilder('t') - ->select('t.slug', 't.label', 't.id') + $ids = $this->createQueryBuilder('t') + ->select('t.id') ->leftJoin('t.entries', 'e') ->where('e.user = :userId')->setParameter('userId', $userId) - ->groupBy('t.slug') - ->addGroupBy('t.label') - ->addGroupBy('t.id') + ->groupBy('t.id') + ->orderBy('t.slug') ->getQuery() ->getArrayResult(); + + $tags = []; + foreach ($ids as $id) { + $tags[] = $this->find($id); + } + + return $tags; } /** diff --git a/src/Wallabag/CoreBundle/Resources/config/parameters.yml b/src/Wallabag/CoreBundle/Resources/config/parameters.yml index 6068e84cd..4948f3851 100644 --- a/src/Wallabag/CoreBundle/Resources/config/parameters.yml +++ b/src/Wallabag/CoreBundle/Resources/config/parameters.yml @@ -1,8 +1,9 @@ parameters: addons_url: - firefox: https://addons.mozilla.org/firefox/addon/wallabag-v2/ - chrome: https://chrome.google.com/webstore/detail/wallabagit/peehlcgckcnclnjlndmoddifcicdnabm + firefox: https://addons.mozilla.org/firefox/addon/wallabagger/ + chrome: https://chrome.google.com/webstore/detail/wallabagger/gbmgphmejlcoihgedabhgjdkcahacjlj + opera: https://addons.opera.com/en/extensions/details/wallabagger/?display=en f_droid: https://f-droid.org/app/fr.gaulupeau.apps.InThePoche google_play: https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche - ios: https://itunes.apple.com/app/wallabag/id828331015?mt=8 + ios: https://itunes.apple.com/app/wallabag-2/id1170800946?mt=8 windows: https://www.microsoft.com/store/apps/wallabag/9nblggh11646 diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index ed66d2bee..fadd5e490 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml @@ -30,7 +30,7 @@ services: - "@doctrine" wallabag_core.subscriber.table_prefix: - class: Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber + class: Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber arguments: - "%database_table_prefix%" tags: @@ -41,11 +41,44 @@ services: arguments: - error_message: '%wallabag_core.fetching_error_message%' + - "@wallabag_core.guzzle.http_client" + - "@wallabag_core.graby.config_builder" calls: - [ setLogger, [ "@logger" ] ] tags: - { name: monolog.logger, channel: graby } + wallabag_core.graby.config_builder: + class: Graby\SiteConfig\ConfigBuilder + arguments: + - {} + - "@logger" + + wallabag_core.guzzle.http_client: + class: GuzzleHttp\ClientInterface + factory: ["@wallabag_core.guzzle.http_client_factory", buildHttpClient] + + wallabag_core.guzzle_authenticator.config_builder: + class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder + arguments: + - "@wallabag_core.graby.config_builder" + - "%sites_credentials%" + + # service alias override + bd_guzzle_site_authenticator.site_config_builder: + alias: wallabag_core.guzzle_authenticator.config_builder + + wallabag_core.guzzle.http_client_factory: + class: Wallabag\CoreBundle\Helper\HttpClientFactory + arguments: + - "@bd_guzzle_site_authenticator.authenticator_subscriber" + - "@wallabag_core.guzzle.cookie_jar" + - '@=service(''craue_config'').get(''restricted_access'')' + + wallabag_core.guzzle.cookie_jar: + class: GuzzleHttp\Cookie\FileCookieJar + arguments: ["%kernel.cache_dir%/cookiejar.json"] + wallabag_core.content_proxy: class: Wallabag\CoreBundle\Helper\ContentProxy arguments: @@ -53,6 +86,7 @@ services: - "@wallabag_core.rule_based_tagger" - "@wallabag_core.tag_repository" - "@logger" + - '%wallabag_core.fetching_error_message%' wallabag_core.rule_based_tagger: class: Wallabag\CoreBundle\Helper\RuleBasedTagger @@ -94,6 +128,7 @@ services: class: Wallabag\CoreBundle\Helper\Redirect arguments: - "@router" + - "@security.token_storage" wallabag_core.helper.prepare_pager_for_entries: class: Wallabag\CoreBundle\Helper\PreparePagerForEntries @@ -109,9 +144,38 @@ services: host: '%redis_host%' port: '%redis_port%' path: '%redis_path%' + password: '%redis_password%' wallabag_core.exception_controller: class: Wallabag\CoreBundle\Controller\ExceptionController arguments: - '@twig' - '%kernel.debug%' + + wallabag_core.subscriber.sqlite_cascade_delete: + class: Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber + arguments: + - "@doctrine" + tags: + - { name: doctrine.event_subscriber } + + wallabag_core.subscriber.download_images: + class: Wallabag\CoreBundle\Event\Subscriber\DownloadImagesSubscriber + arguments: + - "@doctrine.orm.default_entity_manager" + - "@wallabag_core.entry.download_images" + - '@=service(''craue_config'').get(''download_images_enabled'')' + - "@logger" + tags: + - { name: kernel.event_subscriber } + + wallabag_core.entry.download_images: + class: Wallabag\CoreBundle\Helper\DownloadImages + arguments: + - "@wallabag_core.entry.download_images.client" + - "%kernel.root_dir%/../web/assets/images" + - '@=service(''craue_config'').get(''wallabag_url'')' + - "@logger" + + wallabag_core.entry.download_images.client: + class: GuzzleHttp\Client diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml index a1bee173d..34d4021c9 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml @@ -70,7 +70,12 @@ config: # 200_word: 'I read ~200 words per minute' # 300_word: 'I read ~300 words per minute' # 400_word: 'I read ~400 words per minute' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: Brugers nøgle til Pocket for at importere materialer + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'Emailadresse' # twoFactorAuthentication_label: 'Two factor authentication' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Gammel adgangskode' @@ -145,15 +162,16 @@ entry: # archived: 'Archived entries' # filtered: 'Filtered entries' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' reading_time: 'estimeret læsetid' reading_time_minutes: 'estimeret læsetid: %readingTime% min' - reading_time_less_one_minute: 'estimeret læsetid: < 1 min' + reading_time_less_one_minute: 'estimeret læsetid: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Marker som læst' toogle_as_star: 'Skift favoritstatus' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Har et vist billede' preview_picture_help: 'Forhåndsvis billede' language_label: 'Sprog' + # http_status_label: 'HTTP status' reading_time: label: 'Læsetid i minutter' from: 'fra' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: # page_title: 'Edit an entry' # title_label: 'Title' @@ -252,6 +273,9 @@ about: howto: page_title: 'How-to' # page_description: 'There are several ways to save an article:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Browserudvidelser' mobile_apps: 'Apps' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Standardudvidelse til Firefox' chrome: 'Chrome-udvidelse' + opera: 'Opera-udvidelse' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: # windows: 'on the Microsoft Store' bookmarklet: description: 'Træk dette link til din bogmærkeliste:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: # page_title: 'Quickstart' @@ -329,6 +381,9 @@ tag: list: # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: # page_title: 'Import' @@ -362,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." # firefox: # page_title: 'Import > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: # page_title: 'Import > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: # page_title: 'Developer' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'Emailadresse' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -465,8 +524,10 @@ flashes: rss_updated: 'RSS-oplysninger opdateret' # tagging_rules_updated: 'Tagging rules updated' # tagging_rules_deleted: 'Tagging rule deleted' - # user_added: 'User "%username%" added' # rss_token_updated: 'RSS token updated' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: # entry_already_saved: 'Entry already saved on %date%' @@ -496,3 +557,8 @@ flashes: notice: # client_created: 'New client created.' # client_deleted: 'Client deleted' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml index c9625d064..eb3644f6c 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml @@ -70,7 +70,12 @@ config: 200_word: 'Ich lese ~200 Wörter pro Minute' 300_word: 'Ich lese ~300 Wörter pro Minute' 400_word: 'Ich lese ~400 Wörter pro Minute' + action_mark_as_read: + label: 'Wohin soll nach dem Gelesenmarkieren eines Artikels weitergeleitet werden?' + redirect_homepage: 'Zur Homepage' + redirect_current_page: 'Zur aktuellen Seite' pocket_consumer_key_label: Consumer-Key für Pocket, um Inhalte zu importieren + android_configuration: Konfiguriere deine Android Application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'E-Mail-Adresse' twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + title: Lösche mein Konto (a.k.a Gefahrenzone) + description: Wenn du dein Konto löschst, werden ALL deine Artikel, ALL deine Tags, ALL deine Anmerkungen und dein Konto dauerhaft gelöscht (kann NICHT RÜCKGÄNGIG gemacht werden). Du wirst anschließend ausgeloggt. + confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN) + button: Lösche mein Konto + reset: + title: Zurücksetzen (a.k.a Gefahrenzone) + description: Beim Nutzen der folgenden Schaltflächenhast du die Möglichkeit, einige Informationen von deinem Konto zu entfernen. Sei dir bewusst, dass dies NICHT RÜCKGÄNGIG zu machen ist. + annotations: Entferne ALLE Annotationen + tags: Entferne ALLE Tags + entries: Entferne ALLE Einträge + confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Altes Kennwort' @@ -145,15 +162,16 @@ entry: archived: 'Archivierte Einträge' filtered: 'Gefilterte Einträge' filtered_tags: 'Gefiltert nach Tags:' + # filtered_search: 'Filtered by search:' untagged: 'Nicht getaggte Einträge' list: number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' reading_time: 'geschätzte Lesezeit' reading_time_minutes: 'geschätzte Lesezeit: %readingTime% min' - reading_time_less_one_minute: 'geschätzte Lesezeit: < 1 min' + reading_time_less_one_minute: 'geschätzte Lesezeit: < 1 min' number_of_tags: '{1}und ein anderer Tag|]1,Inf[und %count% andere Tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'Original' toogle_as_read: 'Gelesen-Status ändern' toogle_as_star: 'Favoriten-Status ändern' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Vorschaubild vorhanden' preview_picture_help: 'Vorschaubild' language_label: 'Sprache' + # http_status_label: 'HTTP status' reading_time: label: 'Lesezeit in Minuten' from: 'von' @@ -209,6 +228,8 @@ entry: placeholder: 'https://website.de' form_new: url_label: URL + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Eintrag bearbeiten' title_label: 'Titel' @@ -252,6 +273,9 @@ about: howto: page_title: 'How-To' page_description: 'Es gibt mehrere Möglichkeiten, einen Artikel zu speichern:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Browser-Erweiterungen' mobile_apps: 'Apps' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Firefox-Erweiterung' chrome: 'Chrome-Erweiterung' + opera: 'Opera-Erweiterung' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'im Microsoft-Store' bookmarklet: description: 'Ziehe diesen Link in deine Lesezeichenleiste:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Schnelleinstieg' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: '{0} Es gibt keine Tags.|{1} Es gibt einen Tag.|]1,Inf[ Es gibt %count% Tags.' see_untagged_entries: 'Zeige nicht getaggte Einträge' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Importieren' @@ -362,6 +417,7 @@ import: how_to: 'Bitte wähle deinen Readability Export aus und klicke den unteren Button für das Hochladen und Importieren dessen.' worker: enabled: "Der Import erfolgt asynchron. Sobald der Import gestartet ist, wird diese Aufgabe extern abgearbeitet. Der aktuelle Service dafür ist:" + download_images_warning: "Du hast das Herunterladen von Bildern für deine Artikel aktiviert. Verbunden mit dem klassischen Import kann es ewig dauern fortzufahren (oder sogar fehlschlagen). Wir empfehlen den asynchronen Import zu aktivieren, um Fehler zu vermeiden." firefox: page_title: 'Aus Firefox importieren' description: "Dieser Import wird all deine Lesezeichen aus Firefox importieren. Gehe zu deinen Lesezeichen (Strg+Shift+O), dann auf \"Importen und Sichern\", wähle \"Sichern…\". Du erhälst eine .json Datei." @@ -374,6 +430,10 @@ import: page_title: 'Aus Instapaper importieren' description: 'Dieser Import wird all deine Instapaper Artikel importieren. Auf der Einstellungsseite (https://www.instapaper.com/user) klickst du auf "Download .CSV Datei" in dem Abschnitt "Export". Eine CSV Datei wird heruntergeladen (z.B. "instapaper-export.csv").' how_to: "Bitte wähle deine Instapaper Sicherungsdatei aus und klicke den nachfolgenden Button zum Importieren." + pinboard: + page_title: "Aus Pinboard importieren" + description: 'Dieser Import wird all deine Pinboard Artikel importieren. Auf der Seite Backup (https://pinboard.in/settings/backup) klickst du auf "JSON" in dem Abschnitt "Lesezeichen". Eine JSON Datei wird dann heruntergeladen (z.B. "pinboard_export").' + how_to: 'Bitte wähle deinen Pinboard Export aus und klicke den nachfolgenden Button zum Importieren.' developer: page_title: 'Entwickler' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'E-Mail-Adresse' enabled_label: 'Aktiviert' - locked_label: 'Gesperrt' last_login_label: 'Letzter Login' twofactor_label: Zwei-Faktor-Authentifizierung save: Speichern @@ -453,7 +512,7 @@ user: back_to_list: Zurück zur Liste error: - # page_title: An error occurred + page_title: Ein Fehler ist aufgetreten flashes: config: @@ -465,8 +524,10 @@ flashes: rss_updated: 'RSS-Informationen aktualisiert' tagging_rules_updated: 'Tagging-Regeln aktualisiert' tagging_rules_deleted: 'Tagging-Regel gelöscht' - user_added: 'Benutzer "%username%" erstellt' rss_token_updated: 'RSS-Token aktualisiert' + annotations_reset: Anmerkungen zurücksetzen + tags_reset: Tags zurücksetzen + entries_reset: Einträge zurücksetzen entry: notice: entry_already_saved: 'Eintrag bereits am %date% gespeichert' @@ -496,3 +557,8 @@ flashes: notice: client_created: 'Neuer Client erstellt.' client_deleted: 'Client gelöscht' + user: + notice: + added: 'Benutzer "%username%" hinzugefügt' + updated: 'Benutzer "%username%" aktualisiert' + deleted: 'Benutzer "%username%" gelöscht' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index 139cdc246..2626523a6 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml @@ -70,7 +70,12 @@ config: 200_word: 'I read ~200 words per minute' 300_word: 'I read ~300 words per minute' 400_word: 'I read ~400 words per minute' + action_mark_as_read: + label: 'Where do you want to be redirected after mark an article as read?' + redirect_homepage: 'To the homepage' + redirect_current_page: 'To the current page' pocket_consumer_key_label: Consumer key for Pocket to import contents + android_configuration: Configure your Android application help_theme: "wallabag is customizable. You can choose your prefered theme here." help_items_per_page: "You can change the number of articles displayed on each page." help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'Email' twoFactorAuthentication_label: 'Two factor authentication' help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + title: Delete my account (a.k.a danger zone) + description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + confirm: Are you really sure? (THIS CAN'T BE UNDONE) + button: Delete my account + reset: + title: Reset area (a.k.a danger zone) + description: By hitting buttons below you'll have ability to remove some information from your account. Be aware that these actions are IRREVERSIBLE. + annotations: Remove ALL annotations + tags: Remove ALL tags + entries: Remove ALL entries + confirm: Are you really sure? (THIS CAN'T BE UNDONE) form_password: description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Current password' @@ -145,15 +162,16 @@ entry: archived: 'Archived entries' filtered: 'Filtered entries' filtered_tags: 'Filtered by tags:' + filtered_search: 'Filtered by search:' untagged: 'Untagged entries' 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' reading_time_minutes: 'estimated reading time: %readingTime% min' - reading_time_less_one_minute: 'estimated reading time: < 1 min' + reading_time_less_one_minute: 'estimated reading time: < 1 min' number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Toggle mark as read' toogle_as_star: 'Toggle starred' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Has a preview picture' preview_picture_help: 'Preview picture' language_label: 'Language' + http_status_label: 'HTTP status' reading_time: label: 'Reading time in minutes' from: 'from' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + placeholder: 'What are you looking for?' edit: page_title: 'Edit an entry' title_label: 'Title' @@ -251,6 +272,9 @@ about: howto: page_title: 'How to' + tab_menu: + add_link: "Add a link" + shortcuts: "Use shortcuts" page_description: 'There are several ways to save an article:' top_menu: browser_addons: 'Browser addons' @@ -259,8 +283,9 @@ howto: form: description: 'Thanks to this form' browser_addons: - firefox: 'Standard Firefox Add-On' - chrome: 'Chrome Extension' + firefox: 'Firefox addon' + chrome: 'Chrome addon' + opera: 'Opera addon' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'on the Microsoft Store' bookmarklet: description: 'Drag & drop this link to your bookmarks bar:' + shortcuts: + page_description: Here are the shortcuts available in wallabag. + shortcut: Shortcut + action: Action + all_pages_title: Shortcuts available in all pages + go_unread: Go to unread + go_starred: Go to starred + go_archive: Go to archive + go_all: Go to all entries + go_tags: Go to tags + go_config: Go to config + go_import: Go to import + go_developers: Go to developers + go_howto: Go to howto (this page!) + go_logout: Logout + list_title: Shortcuts available in listing pages + search: Display the search form + article_title: Shortcuts available in entry view + open_original: Open original URL of the entry + toggle_favorite: Toggle star status for the entry + toggle_archive: Toggle read status for the entry + delete: Delete the entry + material_title: Shortcuts available with Material theme only + add_link: Add a new link + hide_form: Hide the current form (search or new link) + arrows_navigation: Navigate through articles + open_article: Display the selected entry quickstart: page_title: 'Quickstart' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.' see_untagged_entries: 'See untagged entries' + new: + add: 'Add' + placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Import' @@ -362,6 +417,7 @@ import: how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'Import > Firefox' description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: page_title: 'Import > Instapaper' description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + page_title: "Import > Pinboard" + description: 'This importer will import all your Pinboard articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: page_title: 'Developer' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'Email' enabled_label: 'Enabled' - locked_label: 'Locked' last_login_label: 'Last login' twofactor_label: Two factor authentication save: Save @@ -466,6 +525,9 @@ flashes: tagging_rules_updated: 'Tagging rules updated' tagging_rules_deleted: 'Tagging rule deleted' rss_token_updated: 'RSS token updated' + annotations_reset: Annotations reset + tags_reset: Tags reset + entries_reset: Entries reset entry: notice: entry_already_saved: 'Entry already saved on %date%' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml index 70e64bec0..d45f8bf5f 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml @@ -70,7 +70,12 @@ config: 200_word: 'Leo ~200 palabras por minuto' 300_word: 'Leo ~300 palabras por minuto' 400_word: 'Leo ~400 palabras por minuto' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' # pocket_consumer_key_label: Consumer key for Pocket to import contents + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'Direccion e-mail' twoFactorAuthentication_label: 'Autentificación de dos factores' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Contraseña actual' @@ -145,15 +162,16 @@ entry: archived: 'Artículos archivados' filtered: 'Artículos filtrados' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' reading_time: 'tiempo estimado de lectura' reading_time_minutes: 'tiempo estimado de lectura: %readingTime% min' - reading_time_less_one_minute: 'tiempo estimado de lectura: < 1 min' + reading_time_less_one_minute: 'tiempo estimado de lectura: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Marcar como leído/ no leído' toogle_as_star: 'Marcar como favorito/ no favorito' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Hay una foto' preview_picture_help: 'Foto de preview' language_label: 'Idioma' + # http_status_label: 'HTTP status' reading_time: label: 'Duración de lectura en minutos' from: 'de' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Editar un artículo' title_label: 'Título' @@ -252,6 +273,9 @@ about: howto: page_title: 'Ayuda' page_description: 'Hay muchas maneras para guardar un artículo:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Extensiones de navigador' mobile_apps: 'Aplicaciones para smartphone' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Extensión Firefox' chrome: 'Extensión Chrome' + opera: 'Extensión Opera' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'por la tienda de Microsoft' bookmarklet: description: 'Desplazar y soltar este link en la barra de marcadores :' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Comienzo rápido' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: '{0} No hay ninguna etiqueta.|{1} Hay una etiqueta.|]1,Inf[ Hay %count% etiquetas.' # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Importar' @@ -362,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'Importar > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: page_title: 'Importar > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + page_title: "Importar > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: page_title: 'Promotor' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'Email' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -465,8 +524,10 @@ flashes: rss_updated: 'La configuración de los feeds RSS ha sido actualizada' tagging_rules_updated: 'Regla de etiquetado borrada' tagging_rules_deleted: 'Regla de etiquetado actualizada' - user_added: 'Usuario "%username%" añadido' rss_token_updated: 'RSS token actualizado' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: entry_already_saved: 'Entrada ya guardada por %fecha%' @@ -496,3 +557,8 @@ flashes: notice: client_created: 'Nuevo cliente creado.' client_deleted: 'Cliente suprimido' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml index 753599016..36a7cd809 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml @@ -70,7 +70,12 @@ config: 200_word: 'من تقریباً ۲۰۰ واژه را در دقیقه میخوانم' 300_word: 'من تقریباً ۳۰۰ واژه را در دقیقه میخوانم' 400_word: 'من تقریباً ۴۰۰ واژه را در دقیقه میخوانم' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: کلید کاربری Pocket برای درونریزی مطالب + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'نشانی ایمیل' twoFactorAuthentication_label: 'تأیید ۲مرحلهای' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'رمز قدیمی' @@ -145,15 +162,16 @@ entry: archived: 'مقالههای بایگانیشده' filtered: 'مقالههای فیلترشده' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: number_on_the_page: '{0} هیج مقالهای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' reading_time: 'زمان تخمینی برای خواندن' reading_time_minutes: 'زمان تخمینی برای خواندن: %readingTime% min' - reading_time_less_one_minute: 'زمان تخمینی برای خواندن: < 1 min' + reading_time_less_one_minute: 'زمان تخمینی برای خواندن: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'خواندهشده/خواندهنشده' toogle_as_star: 'برگزیده/نابرگزیده' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'دارای عکس پیشنمایش' preview_picture_help: 'پیشنمایش عکس' language_label: 'زبان' + # http_status_label: 'HTTP status' reading_time: label: 'زمان خواندن به دقیقه' from: 'از' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: نشانی + search: + # placeholder: 'What are you looking for?' edit: page_title: 'ویرایش مقاله' title_label: 'عنوان' @@ -252,6 +273,9 @@ about: howto: page_title: 'خودآموز' page_description: 'راههای زیادی برای ذخیرهٔ مقالهها هست:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'افزونه برای مرورگرها' mobile_apps: 'برنامههای موبایل' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'افزونهٔ فایرفاکس' chrome: 'افزونهٔ کروم' + # opera: 'Opera addon' mobile_apps: android: via_f_droid: 'از راه F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'از راه Microsoft Store' bookmarklet: description: 'این پیوند را به نوار بوکمارک مرورگرتان بکشید:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Quickstart' @@ -279,6 +331,7 @@ quickstart: paragraph_2: 'ادامه دهید!' configure: title: 'برنامه را تنظیم کنید' + # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.' language: 'زبان و نمای برنامه را تغییر دهید' rss: 'خوراک آر-اس-اس را فعال کنید' tagging_rules: 'قانونهای برچسبگذاری خودکار مقالههایتان را تعریف کنید' @@ -328,6 +381,9 @@ tag: list: number_on_the_page: '{0} هیچ برچسبی نیست.|{1} یک برچسب هست.|]1,Inf[ %count% برچسب هست.' # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'درونریزی' @@ -361,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'درونریزی > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -373,6 +430,10 @@ import: page_title: 'درونریزی > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: # page_title: 'Developer' @@ -443,7 +504,6 @@ user: plain_password_label: '????' email_label: 'نشانی ایمیل' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -464,8 +524,10 @@ flashes: rss_updated: 'اطلاعات آر-اس-اس بهروز شد' tagging_rules_updated: 'برچسبگذاری خودکار بهروز شد' tagging_rules_deleted: 'قانون برچسبگذاری پاک شد' - user_added: 'کابر "%username%" افزوده شد' rss_token_updated: 'کد آر-اس-اس بهروز شد' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' @@ -495,3 +557,8 @@ flashes: notice: # client_created: 'New client created.' # client_deleted: 'Client deleted' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index f2c9d8dba..6dd449ba5 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml @@ -46,7 +46,7 @@ footer: social: "Social" powered_by: "propulsé par" about: "À propos" - stats: Depuis le %user_creation% vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour ! + stats: Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour ! config: page_title: "Configuration" @@ -70,7 +70,12 @@ config: 200_word: "Je lis environ 200 mots par minute" 300_word: "Je lis environ 300 mots par minute" 400_word: "Je lis environ 400 mots par minute" + action_mark_as_read: + label: 'Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?' + redirect_homepage: "À la page d'accueil" + redirect_current_page: 'À la page courante' pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données + android_configuration: Configurez votre application Android help_theme: "L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème que vous préférez." help_items_per_page: "Vous pouvez définir le nombre d'articles affichés sur chaque page." help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article." @@ -94,6 +99,18 @@ config: email_label: "Adresse courriel" twoFactorAuthentication_label: "Double authentification" help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email." + delete: + title: Supprimer mon compte (attention danger !) + description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. + confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE) + button: 'Supprimer mon compte' + reset: + title: Réinitialisation (attention danger !) + description: En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES ! + annotations: Supprimer TOUTES les annotations + tags: Supprimer TOUS les tags + entries: Supprimer TOUS les articles + confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE) form_password: description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères." old_password_label: "Mot de passe actuel" @@ -128,7 +145,7 @@ config: domainName: "Le nom de domaine de l’article" operator_description: label: "Opérateur" - less_than: "Moins que…..." + less_than: "Moins que…" strictly_less_than: "Strictement moins que…" greater_than: "Plus que…" strictly_greater_than: "Strictement plus que…" @@ -145,15 +162,16 @@ entry: archived: "Articles lus" filtered: "Articles filtrés" filtered_tags: "Articles filtrés par tags :" + filtered_search: 'Articles filtrés par recherche :' untagged: "Article sans tag" list: - number_on_the_page: "{0} Il n’y a pas d’articles.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." + number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." reading_time: "durée de lecture" reading_time_minutes: "durée de lecture: %readingTime% min" - reading_time_less_one_minute: "durée de lecture: < 1 min" + reading_time_less_one_minute: "durée de lecture: < 1 min" number_of_tags: "{1}et un autre tag|]1,Inf[et %count% autres tags" reading_time_minutes_short: "%readingTime% min" - reading_time_less_one_minute_short: "< 1 min" + reading_time_less_one_minute_short: "< 1 min" original_article: "original" toogle_as_read: "Marquer comme lu/non lu" toogle_as_star: "Marquer comme favori" @@ -168,6 +186,7 @@ entry: preview_picture_label: "A une photo" preview_picture_help: "Photo" language_label: "Langue" + http_status_label: 'Statut HTTP' reading_time: label: "Durée de lecture en minutes" from: "de" @@ -209,6 +228,8 @@ entry: placeholder: "http://website.com" form_new: url_label: "Adresse" + search: + placeholder: "Que recherchez-vous ?" edit: page_title: "Éditer un article" title_label: "Titre" @@ -251,6 +272,9 @@ about: howto: page_title: "Aide" + tab_menu: + add_link: "Ajouter un lien" + shortcuts: "Utiliser les raccourcis" page_description: "Il y a plusieurs façon d’enregistrer un article :" top_menu: browser_addons: "Extensions de navigateur" @@ -261,6 +285,7 @@ howto: browser_addons: firefox: "Extension Firefox" chrome: "Extension Chrome" + opera: "Extension Opera" mobile_apps: android: via_f_droid: "via F-Droid" @@ -269,6 +294,33 @@ howto: windows: "sur Microsoft Store" bookmarklet: description: "Glissez et déposez ce lien dans votre barre de favoris :" + shortcuts: + page_description: Voici les raccourcis disponibles dans wallabag. + shortcut: Raccourci + action: Action + all_pages_title: Raccourcis disponibles dans toutes les pages + go_unread: Afficher les articles non lus + go_starred: Afficher les articles favoris + go_archive: Afficher les articles lus + go_all: Afficher tous les articles + go_tags: Afficher les tags + go_config: Aller à la configuration + go_import: Aller aux imports + go_developers: Aller à la section Développeurs + go_howto: Afficher l'aide (cette page !) + go_logout: Se déconnecter + list_title: Raccourcis disponibles dans les pages de liste + search: Afficher le formulaire de recherche + article_title: Raccourcis disponibles quand on affiche un article + open_original: Ouvrir l'URL originale de l'article + toggle_favorite: Changer le statut Favori de l'article + toggle_archive: Changer le status Lu de l'article + delete: Supprimer l'article + material_title: Raccourcis disponibles avec le thème Material uniquement + add_link: Ajouter un nouvel article + hide_form: Masquer le formulaire courant (recherche ou nouvel article) + arrows_navigation: Naviguer à travers les articles + open_article: Afficher l'article sélectionné quickstart: page_title: "Pour bien débuter" @@ -329,6 +381,9 @@ tag: list: number_on_the_page: "{0} Il n’y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags." see_untagged_entries: "Voir les articles sans tag" + new: + add: 'Ajouter' + placeholder: 'Vous pouvez ajouter plusieurs tags, séparés par une virgule.' import: page_title: "Importer" @@ -362,9 +417,10 @@ import: how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." worker: enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" + download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons vivement d'activer les imports asynchrones." firefox: page_title: "Import > Firefox" - description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. " + description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde… ». Vous allez récupérer un fichier .json. " how_to: "Choisissez le fichier de sauvegarde de vos marques-page et cliquez sur le bouton pour l’importer. Soyez avertis que le processus peut prendre un temps assez long car tous les articles doivent être récupérés en ligne." chrome: page_title: "Import > Chrome" @@ -374,6 +430,10 @@ import: page_title: "Import > Instapaper" description: "Sur la page des paramètres (https://www.instapaper.com/user), cliquez sur « Download .CSV file » dans la section « Export ». Un fichier CSV sera téléchargé (« instapaper-export.csv »)." how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour l’importer." + pinboard: + page_title: "Import > Pinboard" + description: "Sur la page « Backup » (https://pinboard.in/settings/backup), cliquez sur « JSON » dans la section « Bookmarks ». Un fichier json (sans extension) sera téléchargé (« pinboard_export »)." + how_to: "Choisissez le fichier de votre export Pinboard et cliquez sur le bouton ci-dessous pour l’importer." developer: page_title: "Développeur" @@ -444,7 +504,6 @@ user: plain_password_label: "Mot de passe en clair" email_label: "Adresse courriel" enabled_label: "Activé" - locked_label: "Bloqué" last_login_label: "Dernière connexion" twofactor_label: "Double authentification" save: "Sauvegarder" @@ -465,8 +524,10 @@ flashes: rss_updated: "La configuration des flux RSS a bien été mise à jour" tagging_rules_updated: "Règles mises à jour" tagging_rules_deleted: "Règle supprimée" - user_added: "Utilisateur \"%username%\" ajouté" rss_token_updated: "Jeton RSS mis à jour" + annotations_reset: Annotations supprimées + tags_reset: Tags supprimés + entries_reset: Articles supprimés entry: notice: entry_already_saved: "Article déjà sauvegardé le %date%" @@ -496,3 +557,8 @@ flashes: notice: client_created: "Nouveau client %name% créé" client_deleted: "Client %name% supprimé" + user: + notice: + added: 'Utilisateur "%username%" ajouté' + updated: 'Utilisateur "%username%" mis à jour' + deleted: 'Utilisateur "%username%" supprimé' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml index b7d066ab3..4298d1f7d 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml @@ -70,7 +70,12 @@ config: 200_word: 'Leggo ~200 parole al minuto' 300_word: 'Leggo ~300 parole al minuto' 400_word: 'Leggo ~400 parole al minuto' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: Consumer key per Pocket per importare i contenuti + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'E-mail' twoFactorAuthentication_label: 'Two factor authentication' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Password corrente' @@ -145,15 +162,16 @@ entry: archived: 'Contenuti archiviati' filtered: 'Contenuti filtrati' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." reading_time: 'tempo di lettura stimato' reading_time_minutes: 'tempo di lettura stimato: %readingTime% min' - reading_time_less_one_minute: 'tempo di lettura stimato: < 1 min' + reading_time_less_one_minute: 'tempo di lettura stimato: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'originale' toogle_as_read: 'Segna come da leggere' toogle_as_star: 'Segna come non preferito' @@ -168,6 +186,7 @@ entry: preview_picture_label: "Ha un'immagine di anteprima" preview_picture_help: 'Immagine di anteprima' language_label: 'Lingua' + # http_status_label: 'HTTP status' reading_time: label: 'Tempo di lettura in minuti' from: 'da' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Modifica voce' title_label: 'Titolo' @@ -252,6 +273,9 @@ about: howto: page_title: 'How to' page_description: 'Ci sono diversi modi per salvare un contenuto:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'tramite addons del Browser' mobile_apps: 'tramite app Mobile' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Add-On di Firefox' chrome: 'Estensione di Chrome' + opera: 'Estensione di Opera' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'sullo store di Microsoft' bookmarklet: description: 'Trascinando e rilasciando questo link sulla barra dei bookmark del tuo browser:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Introduzione' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag." # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Importa' @@ -362,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'Importa da > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: page_title: 'Importa da > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + page_title: "Importa da > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: page_title: 'Sviluppatori' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'E-mail' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -465,8 +524,10 @@ flashes: rss_updated: 'Informazioni RSS aggiornate' tagging_rules_updated: 'Regole di tagging aggiornate' tagging_rules_deleted: 'Regola di tagging aggiornate' - user_added: 'Utente "%username%" aggiunto' rss_token_updated: 'RSS token aggiornato' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: entry_already_saved: 'Contenuto già salvato in data %date%' @@ -496,3 +557,8 @@ flashes: notice: client_created: 'Nuovo client creato.' client_deleted: 'Client eliminato' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml index 16ef1e5d2..85310cd7b 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml @@ -25,13 +25,13 @@ menu: internal_settings: 'Configuracion interna' import: 'Importar' howto: 'Ajuda' - developer: 'Desvolopador' + developer: 'Desvolopaire' logout: 'Desconnexion' about: 'A prepaus' search: 'Cercar' save_link: 'Enregistrar un novèl article' back_to_unread: 'Tornar als articles pas legits' - # users_management: 'Users management' + users_management: 'Gestion dels utilizaires' top: add_new_entry: 'Enregistrar un novèl article' search: 'Cercar' @@ -46,7 +46,7 @@ footer: social: 'Social' powered_by: 'propulsat per' about: 'A prepaus' - # stats: Since %user_creation% you read %nb_archives% articles. That is about %per_day% a day! + stats: "Dempuèi %user_creation% avètz legit %nb_archives% articles. Es a l'entorn de %per_day% per jorn !" config: page_title: 'Configuracion' @@ -70,7 +70,12 @@ config: 200_word: "Legissi a l'entorn de 200 mots per minuta" 300_word: "Legissi a l'entorn de 300 mots per minuta" 400_word: "Legissi a l'entorn de 400 mots per minuta" + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas + android_configuration: Configuratz vòstra aplicacion Android # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'Adreça de corrièl' twoFactorAuthentication_label: 'Dobla autentificacion' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + title: Suprimir mon compte (Mèfi zòna perilhosa) + description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat. + confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE) + button: Suprimir mon compte + reset: + title: Zòna de reïnicializacion (Mèfi zòna perilhosa) + description: En clicant sul boton çai-jos auretz la possibilitat de levar qualques informacions de vòstre compte. Mèfi que totas aquelas accions son IRREVERSIBLAS. + annotations: Levar TOTAS las anotacions + tags: Levar TOTAS las etiquetas + entries: Levar TOTES los articles + confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Senhal actual' @@ -103,7 +120,7 @@ config: if_label: 'se' then_tag_as_label: 'alara atribuir las etiquetas' delete_rule_label: 'suprimir' - # edit_rule_label: 'edit' + edit_rule_label: 'modificar' rule_label: 'Règla' tags_label: 'Etiquetas' faq: @@ -145,15 +162,16 @@ entry: archived: 'Articles legits' filtered: 'Articles filtrats' filtered_tags: 'Filtats per etiquetas:' + # filtered_search: 'Filtered by search:' untagged: 'Articles sens etiqueta' list: number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." reading_time: 'durada de lectura' reading_time_minutes: 'durada de lectura : %readingTime% min' - reading_time_less_one_minute: 'durada de lectura : < 1 min' + reading_time_less_one_minute: 'durada de lectura : < 1 min' number_of_tags: '{1}e una autra etiqueta|]1,Inf[e %count% autras etiquetas' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Marcar coma legit/pas legit' toogle_as_star: 'Marcar coma favorit' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'A una fotò' preview_picture_help: 'Fotò' language_label: 'Lenga' + # http_status_label: 'HTTP status' reading_time: label: 'Durada de lectura en minutas' from: 'de' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Modificar un article' title_label: 'Títol' @@ -216,7 +237,7 @@ entry: is_public_label: 'Public' save_label: 'Enregistrar' public: - # shared_by_wallabag: "This article has been shared by wallabag" + shared_by_wallabag: "Aqueste article es estat partejat per wallabag" about: page_title: 'A prepaus' @@ -252,6 +273,9 @@ about: howto: page_title: 'Ajuda' page_description: "I a mai d'un biais d'enregistrar un article :" + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Extensions de navigator' mobile_apps: 'Aplicacions mobil' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Extension Firefox' chrome: 'Extension Chrome' + opera: 'Extension Opera' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,17 +294,44 @@ howto: windows: 'sus Microsoft Store' bookmarklet: description: 'Lisatz-depausatz aqueste ligam dins vòstra barra de favorits :' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Per ben començar' - # more: 'More…' + more: 'Mai…' intro: title: 'Benvenguda sus wallabag !' paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas fonccionalitats que vos poirián interessar per vos apropriar aquesta aisina." paragraph_2: 'Seguètz-nos ' configure: - title: "Configuratz l'aplicacio" - # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.' + title: "Configuratz l'aplicacion" + description: "Per fin d'aver una aplicacion que vos va ben, anatz veire la configuracion de wallabag." language: "Cambiatz la lenga e l'estil de l'aplicacion" rss: 'Activatz los fluxes RSS' tagging_rules: 'Escrivètz de règlas per classar automaticament vòstres articles' @@ -293,7 +345,7 @@ quickstart: import: 'Configurar los impòrt' first_steps: title: 'Primièrs passes' - # description: "Now wallabag is well configured, it's time to archive the web. You can click on the top right sign + to add a link." + description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam." new_article: 'Ajustatz vòstre primièr article' unread_articles: 'E racaptatz-lo !' migrate: @@ -305,14 +357,14 @@ quickstart: readability: 'Migrar dempuèi Readability' instapaper: 'Migrar dempuèi Instapaper' developer: - title: 'Pels desvolopadors' - # description: 'We also thought to the developers: Docker, API, translations, etc.' + title: 'Pels desvolopaires' + description: 'Avèm tanben pensat als desvolopaires : Docker, API, traduccions, etc.' create_application: 'Crear vòstra aplicacion tèrça' - # use_docker: 'Use Docker to install wallabag' + use_docker: 'Utilizar Docker per installar wallabag' docs: title: 'Documentacion complèta' - # description: "There are so much features in wallabag. Don't hesitate to read the manual to know them and to learn how to use them." - annotate: 'Anotatar vòstre article' + description: "I a un fum de fonccionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar." + annotate: 'Anotar vòstre article' export: 'Convertissètz vòstres articles en ePub o en PDF' search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa" fetching_errors: "Qué far se mon article es pas recuperat coma cal ?" @@ -329,6 +381,9 @@ tag: list: number_on_the_page: "{0} I a pas cap d'etiquetas.|{1} I a una etiqueta.|]1,Inf[ I a %count% etiquetas." see_untagged_entries: "Afichar las entradas sens pas cap d'etiquetas" + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Importar' @@ -362,6 +417,7 @@ import: how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar." worker: enabled: "L'importacion se fa de manièra asincròna. Un còp l'importacion lançada, una aisina externa s'ocuparà dels messatges un per un. Lo servici actual es : " + download_images_warning: "Avètz activat lo telecargament de los imatges de vòstres articles. Combinat amb l'importacion classica, aquò pòt tardar un long moment (o benlèu fracassar). Recomandem fòrtament l'activacion de l'importacion asincròna per evitar las errors." firefox: page_title: 'Importar > Firefox' description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: page_title: 'Importar > Instapaper' description: "Aquesta aisina importarà totas vòstres articles d'Instapaper. Sus la pagina de paramètres (https://www.instapaper.com/user), clicatz sus \"Download .CSV file\" dins la seccion \"Export\". Un fichièr CSV serà telecargat (aital \"instapaper-export.csv\")." how_to: "Mercés de causir vòstre fichièr Instapaper e de clicar sul boton dejós per lo telecargar e l'importar" + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: page_title: 'Desvolopaire' @@ -397,7 +457,7 @@ developer: warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag." action: 'Suprimir aqueste client' client: - page_title: 'Desvlopador > Novèl client' + page_title: 'Desvolopaire > Novèl client' page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion." form: name_label: "Nom del client" @@ -405,7 +465,7 @@ developer: save_label: 'Crear un novèl client' action_back: 'Retorn' client_parameter: - page_title: 'Desvolopador > Los paramètres de vòstre client' + page_title: 'Desvolopaire > Los paramètres de vòstre client' page_description: 'Vaquí los paramètres de vòstre client' field_name: 'Nom del client' field_id: 'ID Client' @@ -413,7 +473,7 @@ developer: back: 'Retour' read_howto: 'Legir "cossí crear ma primièra aplicacion"' howto: - page_title: 'Desvolopador > Cossí crear ma primièra aplicacion' + page_title: 'Desvolopaire > Cossí crear ma primièra aplicacion' description: paragraph_1: "Las comandas seguentas utilizan la bibliotèca HTTPie. Asseguratz-vos que siasqueòu installadas abans de l'utilizar." paragraph_2: "Vos cal un geton per escambiar entre vòstra aplicacion e l'API de wallabar." @@ -426,34 +486,33 @@ developer: back: 'Retorn' user: - # page_title: Users management - # new_user: Create a new user - # edit_user: Edit an existing user - # description: "Here you can manage all users (create, edit and delete)" - # list: - # actions: Actions - # edit_action: Edit - # yes: Yes - # no: No - # create_new_one: Create a new user + page_title: 'Gestion dels utilizaires' + new_user: 'Crear un novèl utilizaire' + edit_user: 'Modificar un utilizaire existent' + description: "Aquí podètz gerir totes los utilizaires (crear, modificar e suprimir)" + list: + actions: 'Accions' + edit_action: 'Modificar' + yes: 'Òc' + no: 'Non' + create_new_one: 'Crear un novèl utilizaire' form: username_label: "Nom d'utilizaire" - # name_label: 'Name' + name_label: 'Nom' password_label: 'Senhal' repeat_new_password_label: 'Confirmatz vòstre novèl senhal' plain_password_label: 'Senhal en clar' email_label: 'Adreça de corrièl' - # enabled_label: 'Enabled' - # locked_label: 'Locked' - # last_login_label: 'Last login' - # twofactor_label: Two factor authentication - # save: Save - # delete: Delete - # delete_confirm: Are you sure? - # back_to_list: Back to list + enabled_label: 'Actiu' + last_login_label: 'Darrièra connexion' + twofactor_label: 'Autentificacion doble-factor' + save: 'Enregistrar' + delete: 'Suprimir' + delete_confirm: 'Sètz segur ?' + back_to_list: 'Tornar a la lista' error: - # page_title: An error occurred + page_title: Una error s'es produsida flashes: config: @@ -465,8 +524,10 @@ flashes: rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' tagging_rules_updated: 'Règlas misa a jorn' tagging_rules_deleted: 'Règla suprimida' - user_added: 'Utilizaire "%username%" apondut' rss_token_updated: 'Geton RSS mes a jorn' + annotations_reset: Anotacions levadas + tags_reset: Etiquetas levadas + entries_reset: Articles levats entry: notice: entry_already_saved: 'Article ja salvargardat lo %date%' @@ -477,12 +538,12 @@ flashes: entry_reloaded_failed: "L'article es estat cargat de nòu mai la recuperacion del contengut a fracassat" entry_archived: 'Article marcat coma legit' entry_unarchived: 'Article marcat coma pas legit' - entry_starred: 'Article apondut dins los favorits' + entry_starred: 'Article ajustat dins los favorits' entry_unstarred: 'Article quitat dels favorits' entry_deleted: 'Article suprimit' tag: notice: - tag_added: 'Etiqueta aponduda' + tag_added: 'Etiqueta ajustada' import: notice: failed: "L'importacion a fracassat, mercés de tornar ensajar" @@ -496,3 +557,8 @@ flashes: notice: client_created: 'Novèl client creat' client_deleted: 'Client suprimit' + user: + notice: + added: 'Utilizaire "%username%" ajustat' + updated: 'Utilizaire "%username%" mes a jorn' + deleted: 'Utilizaire "%username%" suprimit' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml index 73250cc02..35120edce 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml @@ -61,7 +61,7 @@ config: save: 'Zapisz' form_settings: theme_label: 'Temat' - items_per_page_label: 'Ilość elementóœ na stronie' + items_per_page_label: 'Ilość elementów na stronie' language_label: 'Język' reading_speed: label: 'Prędkość czytania' @@ -70,12 +70,17 @@ config: 200_word: 'Czytam ~200 słów na minutę' 300_word: 'Czytam ~300 słów na minutę' 400_word: 'Czytam ~400 słów na minutę' + action_mark_as_read: + label: 'Gdzie zostaniesz przekierowany po oznaczeniu artukuły jako przeczytanego' + redirect_homepage: 'do strony głównej' + redirect_current_page: 'do bieżącej strony' pocket_consumer_key_label: 'Klucz klienta Pocket do importu zawartości' - # help_theme: "wallabag is customizable. You can choose your prefered theme here." - # help_items_per_page: "You can change the number of articles displayed on each page." - # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." - # help_language: "You can change the language of wallabag interface." - # help_pocket_consumer_key: "Required for Pocket import. You can create it in your Pocket account." + android_configuration: Skonfiguruj swoją androidową aplikację + help_theme: "Dopasuj wallabag do swoich potrzeb. Tutaj możesz wybrać preferowany przez ciebie motyw." + help_items_per_page: "Możesz zmienić ilość artykułów wyświetlanych na każdej stronie." + help_reading_speed: "wallabag oblicza czas czytania każdego artykułu. Dzięki tej liście możesz określić swoje tempo. Wallabag przeliczy ponownie czas potrzebny, na przeczytanie każdego z artykułów." + help_language: "Możesz zmienić język interfejsu wallabag." + help_pocket_consumer_key: "Wymagane dla importu z Pocket. Możesz go stworzyć na swoim koncie Pocket." form_rss: description: 'Kanały RSS prowadzone przez wallabag pozwalają Ci na czytanie twoich zapisanych artykułów w twoium ulubionym czytniku RSS. Musisz najpierw wynegenerować tokena.' token_label: 'Token RSS' @@ -93,9 +98,21 @@ config: name_label: 'Nazwa' email_label: 'Adres email' twoFactorAuthentication_label: 'Autoryzacja dwuetapowa' - # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + help_twoFactorAuthentication: "Jeżeli włączysz autoryzację dwuetapową. Za każdym razem, kiedy będziesz chciał się zalogować, dostaniesz kod na swój e-mail." + delete: + title: Usuń moje konto (niebezpieczna strefa !) + description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany. + confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) + button: Usuń moje konto + reset: + title: Reset (niebezpieczna strefa) + description: Poniższe przyciski pozwalają usunąć pewne informacje z twojego konta. Uważaj te operacje są NIEODWRACALNE. + annotations: Usuń WSZYSTKIE adnotacje + tags: Usuń WSZYSTKIE tagi + entries: usuń WSZYTSTKIE wpisy + confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) form_password: - # description: "You can change your password here. Your new password should by at least 8 characters long." + description: "Tutaj możesz zmienić swoje hasło. Twoje nowe hasło powinno mieć conajmniej 8 znaków." old_password_label: 'Stare hasło' new_password_label: 'Nowe hasło' repeat_new_password_label: 'Powtórz nowe hasło' @@ -145,15 +162,16 @@ entry: archived: 'Zarchiwizowane wpisy' filtered: 'Odfiltrowane wpisy' filtered_tags: 'Filtrowane po tagach:' + filtered_search: 'Filtrowanie po wyszukiwaniu:' untagged: 'Odtaguj wpisy' list: number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' reading_time: 'szacunkowy czas czytania' reading_time_minutes: 'szacunkowy czas czytania: %readingTime% min' - reading_time_less_one_minute: 'szacunkowy czas czytania: < 1 min' + reading_time_less_one_minute: 'szacunkowy czas czytania: < 1 min' number_of_tags: '{1} i inny tag|]1,Inf[i %count% innych tagów' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'oryginał' toogle_as_read: 'Oznacz jako przeczytane' toogle_as_star: 'Oznacz jako ulubione' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Posiada podgląd obrazu' preview_picture_help: 'Podgląd obrazu' language_label: 'Język' + http_status_label: 'Status HTTP' reading_time: label: 'Czas czytania w minutach' from: 'od' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + placeholder: 'Czego szukasz?' edit: page_title: 'Edytuj wpis' title_label: 'Tytuł' @@ -252,6 +273,9 @@ about: howto: page_title: 'Howto' page_description: 'Sposoby zapisania artykułu:' + tab_menu: + add_link: "Dodaj link" + shortcuts: "Użyj skrótów" top_menu: browser_addons: 'Wtyczki dla przeglądarki' mobile_apps: 'Aplikacje mobilne' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Standardowe rozszerzenie dla Firefox' chrome: 'Rozszerzenie dla Chrome' + opera: 'Rozszerzenie dla Opera' mobile_apps: android: via_f_droid: 'w F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'w Microsoft Store' bookmarklet: description: 'Przeciągnij i upuść ten link na swój pasek zakładek' + shortcuts: + page_description: Tutaj znajdują się skróty dostępne w wallabag. + shortcut: Skrót + action: Akcja + all_pages_title: Skróty dostępne na wszystkich stronach + go_unread: Idź do nieprzeczytanych + go_starred: Idź do oznaczonych gwiazdką + go_archive: Idź do archiwum + go_all: Idź do wszystkich wpisów + go_tags: Idź do tagów + go_config: Idź do konfiguracji + go_import: Idź do importu + go_developers: Idź do deweloperów + go_howto: Idź do howto (tej strony!) + go_logout: Wyloguj + list_title: Skróty dostępne w spisie stron + search: Pokaż formularz wyszukiwania + article_title: Skróty dostępne w widoku artykułu + open_original: Otwórz oryginalny adres URL wpisu + toggle_favorite: Oznacz wpis gwiazdką + toggle_archive: Oznacz wpis jako przeczytany + delete: Usuń wpis + material_title: Skróty dostępne wyłącznie w motywie Material + add_link: Dodaj nowy link + hide_form: Ukryj obecny formularz (wyszukiwania lub nowego linku) + arrows_navigation: Nawiguj pomiędzy artykułami + open_article: Wyświetl zaznaczony wpis quickstart: page_title: 'Szybki start' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: '{0} Nie ma tagów.|{1} Jest jeden tag.|]1,Inf[ Są %count% tagi.' see_untagged_entries: 'Zobacz nieotagowane wpisy' + new: + add: 'Dodaj' + placeholder: 'Możesz dodać kilka tagów, oddzielając je przecinkami.' import: page_title: 'Import' @@ -362,6 +417,7 @@ import: how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.' worker: enabled: "Import jest wykonywany asynchronicznie. Od momentu rozpoczęcia importu, zewnętrzna usługa może zajmować się na raz tylko jednym zadaniem. Bieżącą usługą jest:" + download_images_warning: "Włączyłeś pobieranie obrazów dla swoich artykułów. W połączeniu z klasycznym importem, może to zająć dużo czasu (lub zakończyć się niepowodzeniem).Zdecydowanie zalecamy włączenie asynchronicznego importu, w celu uniknięcia błędów." firefox: page_title: 'Import > Firefox' description: "Ten importer zaimportuje wszystkie twoje zakładki z Firefoksa. Idź do twoich zakładek (Ctrl+Shift+O), następnie w \"Import i kopie zapasowe\", wybierz \"Utwórz kopię zapasową...\". Uzyskasz plik .json." @@ -374,6 +430,10 @@ import: page_title: 'Import > Instapaper' description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Instapaper. W ustawieniach (https://www.instapaper.com/user), kliknij na "Download .CSV file" w sekcji "Export". Otrzymasz plik CSV.' how_to: 'Wybierz swój plik eksportu z Instapaper i kliknij poniższy przycisk, aby go załadować.' + pinboard: + page_title: "Import > Pinboard" + description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Pinboard. W ustawieniach kopii zapasowej (https://pinboard.in/settings/backup), kliknij na "JSON" w sekcji "Bookmarks". Otrzymasz plik "pinboard_export".' + how_to: 'Wybierz swój plik eksportu z Pinboard i kliknij poniższy przycisk, aby go załadować.' developer: page_title: 'Deweloper' @@ -444,7 +504,6 @@ user: plain_password_label: 'Jawne hasło' email_label: 'Adres email' enabled_label: 'Włączony' - locked_label: 'Zablokowany' last_login_label: 'Ostatnie logowanie' twofactor_label: Autoryzacja dwuetapowa save: Zapisz @@ -453,7 +512,7 @@ user: back_to_list: Powrót do listy error: - # page_title: An error occurred + page_title: Wystąpił błąd flashes: config: @@ -465,8 +524,10 @@ flashes: rss_updated: 'Informacje RSS zaktualizowane' tagging_rules_updated: 'Reguły tagowania zaktualizowane' tagging_rules_deleted: 'Reguła tagowania usunięta' - user_added: 'Użytkownik "%username%" dodany' rss_token_updated: 'Token kanału RSS zaktualizowany' + annotations_reset: Zresetuj adnotacje + tags_reset: Zresetuj tagi + entries_reset: Zresetuj wpisy entry: notice: entry_already_saved: 'Wpis już został dodany %date%' @@ -496,3 +557,8 @@ flashes: notice: client_created: 'Nowy klient utworzony.' client_deleted: 'Klient usunięty' + user: + notice: + added: 'Użytkownik "%username%" dodany' + updated: 'Użytkownik "%username%" zaktualizowany' + deleted: 'Użytkownik "%username%" usunięty' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml index a375ac7be..c4ace37c8 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml @@ -70,7 +70,12 @@ config: 200_word: 'Posso ler ~200 palavras por minuto' 300_word: 'Posso ler ~300 palavras por minuto' 400_word: 'Posso ler ~400 palavras por minuto' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: 'Chave do consumidor do Pocket para importar conteúdo' + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'E-mail' twoFactorAuthentication_label: 'Autenticação de dois passos' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Senha atual' @@ -145,15 +162,16 @@ entry: archived: 'Entradas arquivadas' filtered: 'Entradas filtradas' filtered_tags: 'Filtrar por tags:' + # filtered_search: 'Filtered by search:' untagged: 'Entradas sem tags' list: number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.' reading_time: 'tempo estimado de leitura' reading_time_minutes: 'tempo estimado de leitura: %readingTime% min' - reading_time_less_one_minute: 'tempo estimado de leitura: < 1 min' + reading_time_less_one_minute: 'tempo estimado de leitura: < 1 min' number_of_tags: '{1}e uma outra tag|]1,Inf[e %count% outras tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Marcar como lido' toogle_as_star: 'Marcar como destacado' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Possui uma imagem de preview' preview_picture_help: 'Imagem de preview' language_label: 'Idioma' + # http_status_label: 'HTTP status' reading_time: label: 'Tempo de leitura em minutos' from: 'de' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Editar uma entrada' title_label: 'Título' @@ -252,6 +273,9 @@ about: howto: page_title: 'How to' page_description: 'Existem diferentes formas de salvar um artigo:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Extensões de navegadores' mobile_apps: "App's móveis" @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Extensão padrão do Firefox' chrome: 'Extensão do Chrome' + opera: 'Extensão do Opera' mobile_apps: android: via_f_droid: 'via F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'na Microsoft Store' bookmarklet: description: 'Arraste e solve este link na sua barra de favoritos:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Começo Rápido' @@ -329,6 +381,9 @@ tag: list: number_on_the_page: '{0} Não existem tags.|{1} Uma tag.|]1,Inf[ Existem %count% tags.' see_untagged_entries: 'Ver entradas sem tags' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'Importar' @@ -362,6 +417,7 @@ import: how_to: 'Por favor, selecione sua exportação do Readability e clique no botão abaixo para importá-la.' worker: enabled: "A importação é feita assíncronamente. Uma vez que a tarefa de importação é iniciada, um trabalho externo pode executar tarefas uma por vez. O serviço atual é:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'Importar > Firefox' description: "Com este importador você importa todos os favoritos de seu Firefox. Somente vá até seus favoritos (Ctrl+Maj+O), e em \"Importar e Backup\" e escolha \"Backup...\". Você terá então um arquivo .json." @@ -374,6 +430,10 @@ import: page_title: 'Importar > Instapaper' description: 'Este importador pode importar todos os artigos do seu Instapaper. Nas página de configurações (https://www.instapaper.com/user), clique em "Download .CSV file" na seção "Export". Um arquivo CSV será baixado (algo como "instapaper-export.csv").' how_to: 'Por favor, selecione sua exportação do seu Instapaper e clique no botão abaixo para importá-la.' + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: page_title: 'Desenvolvedor' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'E-mail' enabled_label: 'Habilitado' - locked_label: 'Travado' last_login_label: 'Último login' twofactor_label: 'Autenticação de dois passos' save: 'Salvar' @@ -452,17 +511,23 @@ user: delete_confirm: 'Tem certeza?' back_to_list: 'Voltar para a lista' +error: + # page_title: An error occurred + flashes: config: notice: config_saved: 'Configiração salva.' password_updated: 'Senha atualizada' password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.' - user_updated: 'Informação atualizada' + # user_updated: 'Information updated' rss_updated: 'Informação de RSS atualizada' tagging_rules_updated: 'Regras de tags atualizadas' tagging_rules_deleted: 'Regra de tag apagada' rss_token_updated: 'Token RSS atualizado' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: entry_already_saved: 'Entrada já foi salva em %date%' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml index 7d8fcea32..928e5c270 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml @@ -70,7 +70,12 @@ config: # 200_word: 'I read ~200 words per minute' # 300_word: 'I read ~300 words per minute' # 400_word: 'I read ~400 words per minute' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' pocket_consumer_key_label: Cheie consumator pentru importarea contentului din Pocket + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'E-mail' # twoFactorAuthentication_label: 'Two factor authentication' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Parola veche' @@ -145,15 +162,16 @@ entry: # archived: 'Archived entries' # filtered: 'Filtered entries' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' reading_time: 'timp estimat de citire' reading_time_minutes: 'timp estimat de citire: %readingTime% min' - reading_time_less_one_minute: 'timp estimat de citire: < 1 min' + reading_time_less_one_minute: 'timp estimat de citire: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'original' toogle_as_read: 'Comută marcat ca citit' toogle_as_star: 'Comută marcat ca favorit' @@ -168,6 +186,7 @@ entry: preview_picture_label: 'Are o imagine de previzualizare' preview_picture_help: 'Previzualizare imagine' language_label: 'Limbă' + # http_status_label: 'HTTP status' reading_time: label: 'Timp de citire în minute' from: 'de la' @@ -209,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: # page_title: 'Edit an entry' # title_label: 'Title' @@ -252,6 +273,9 @@ about: howto: page_title: 'Cum să' # page_description: 'There are several ways to save an article:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Add-On-uri de Browser' mobile_apps: 'Aplicații mobile' @@ -261,6 +285,7 @@ howto: browser_addons: firefox: 'Add-On standard de Firefox' chrome: 'Extensie Chrome' + opera: 'Extensie Opera' mobile_apps: android: via_f_droid: 'prin F-Droid' @@ -269,6 +294,33 @@ howto: windows: 'prin Microsoft Store' bookmarklet: description: 'Drag & drop acest link în bara de bookmark-uri:' + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: # page_title: 'Quickstart' @@ -329,6 +381,9 @@ tag: list: # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: # page_title: 'Import' @@ -362,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." # firefox: # page_title: 'Import > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -374,6 +430,10 @@ import: # page_title: 'Import > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: # page_title: 'Developer' @@ -444,7 +504,6 @@ user: plain_password_label: '????' email_label: 'E-mail' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -465,8 +524,10 @@ flashes: rss_updated: 'Informație RSS actualizată' # tagging_rules_updated: 'Tagging rules updated' # tagging_rules_deleted: 'Tagging rule deleted' - # user_added: 'User "%username%" added' # rss_token_updated: 'RSS token updated' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: # entry_already_saved: 'Entry already saved on %date%' @@ -496,3 +557,8 @@ flashes: notice: # client_created: 'New client created.' # client_deleted: 'Client deleted' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml index 357aa2ae1..d6cea9745 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml @@ -70,7 +70,12 @@ config: # 200_word: 'I read ~200 words per minute' # 300_word: 'I read ~300 words per minute' # 400_word: 'I read ~400 words per minute' + action_mark_as_read: + # label: 'Where do you to be redirected after mark an article as read?' + # redirect_homepage: 'To the homepage' + # redirect_current_page: 'To the current page' # pocket_consumer_key_label: Consumer key for Pocket to import contents + # android_configuration: Configure your Android application # help_theme: "wallabag is customizable. You can choose your prefered theme here." # help_items_per_page: "You can change the number of articles displayed on each page." # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." @@ -94,6 +99,18 @@ config: email_label: 'E-posta' twoFactorAuthentication_label: 'İki adımlı doğrulama' # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." + delete: + # title: Delete my account (a.k.a danger zone) + # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. + # confirm: Are you really sure? (THIS CAN'T BE UNDONE) + # button: Delete my account + reset: + # title: Reset area (a.k.a danger zone) + # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. + # annotations: Remove ALL annotations + # tags: Remove ALL tags + # entries: Remove ALL entries + # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) form_password: # description: "You can change your password here. Your new password should by at least 8 characters long." old_password_label: 'Eski şifre' @@ -103,6 +120,7 @@ config: # if_label: 'if' # then_tag_as_label: 'then tag as' # delete_rule_label: 'delete' + # edit_rule_label: 'edit' rule_label: 'Kural' tags_label: 'Etiketler' faq: @@ -144,15 +162,16 @@ entry: # archived: 'Archived entries' # filtered: 'Filtered entries' # filtered_tags: 'Filtered by tags:' + # filtered_search: 'Filtered by search:' # untagged: 'Untagged entries' list: number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' reading_time: 'tahmini okuma süresi' reading_time_minutes: 'tahmini okuma süresi: %readingTime% min' - reading_time_less_one_minute: 'tahmini okuma süresi: < 1 min' + reading_time_less_one_minute: 'tahmini okuma süresi: < 1 min' # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags' reading_time_minutes_short: '%readingTime% min' - reading_time_less_one_minute_short: '< 1 min' + reading_time_less_one_minute_short: '< 1 min' original_article: 'orijinal' toogle_as_read: 'Okundu/okunmadı olarak işaretle' toogle_as_star: 'Favorilere ekle/çıkar' @@ -167,6 +186,7 @@ entry: preview_picture_label: 'Resim önizlemesi varsa' preview_picture_help: 'Resim önizlemesi' language_label: 'Dil' + # http_status_label: 'HTTP status' reading_time: label: 'Dakika cinsinden okuma süresi' from: 'başlangıç' @@ -208,6 +228,8 @@ entry: placeholder: 'http://website.com' form_new: url_label: Url + search: + # placeholder: 'What are you looking for?' edit: page_title: 'Makaleyi düzenle' title_label: 'Başlık' @@ -251,6 +273,9 @@ about: howto: page_title: 'Yardım' # page_description: 'There are several ways to save an article:' + tab_menu: + # add_link: "Add a link" + # shortcuts: "Use shortcuts" top_menu: browser_addons: 'Tarayıcı eklentileri' mobile_apps: 'Mobil uygulamalar' @@ -260,6 +285,7 @@ howto: browser_addons: firefox: 'Standart Firefox Eklentisi' chrome: 'Chrome Eklentisi' + opera: 'Opera Eklentisi' mobile_apps: android: # via_f_droid: 'via F-Droid' @@ -268,6 +294,33 @@ howto: # windows: 'on the Microsoft Store' bookmarklet: description: "Bu bağlantı ile yer imlerinizi sürükleyip bırakarak wallabag'e ekleyebilirsiniz:" + shortcuts: + # page_description: Here are the shortcuts available in wallabag. + # shortcut: Shortcut + # action: Action + # all_pages_title: Shortcuts available in all pages + # go_unread: Go to unread + # go_starred: Go to starred + # go_archive: Go to archive + # go_all: Go to all entries + # go_tags: Go to tags + # go_config: Go to config + # go_import: Go to import + # go_developers: Go to developers + # go_howto: Go to howto (this page!) + # go_logout: Logout + # list_title: Shortcuts available in listing pages + # search: Display the search form + # article_title: Shortcuts available in entry view + # open_original: Open original URL of the entry + # toggle_favorite: Toggle star status for the entry + # toggle_archive: Toggle read status for the entry + # delete: Delete the entry + # material_title: Shortcuts available with Material theme only + # add_link: Add a new link + # hide_form: Hide the current form (search or new link) + # arrows_navigation: Navigate through articles + # open_article: Display the selected entry quickstart: page_title: 'Hızlı başlangıç' @@ -328,6 +381,9 @@ tag: list: number_on_the_page: '{0} Herhangi bir etiket yok.|{1} Burada bir adet etiket var.|]1,Inf[ Burada %count% adet etiket var.' # see_untagged_entries: 'See untagged entries' + new: + # add: 'Add' + # placeholder: 'You can add several tags, separated by a comma.' import: page_title: 'İçe Aktar' @@ -361,6 +417,7 @@ import: # how_to: 'Please select your Readability export and click on the below button to upload and import it.' worker: # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" + # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We strongly recommend to enable asynchronous import to avoid errors." firefox: page_title: 'İçe Aktar > Firefox' # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." @@ -373,6 +430,10 @@ import: page_title: 'İçe Aktar > Instapaper' # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' + pinboard: + # page_title: "Import > Pinboard" + # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' + # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' developer: # page_title: 'Developer' @@ -443,7 +504,6 @@ user: plain_password_label: '????' email_label: 'E-posta' # enabled_label: 'Enabled' - # locked_label: 'Locked' # last_login_label: 'Last login' # twofactor_label: Two factor authentication # save: Save @@ -464,8 +524,10 @@ flashes: rss_updated: 'RSS bilgiler güncellendi' tagging_rules_updated: 'Tagging rules updated' tagging_rules_deleted: 'Tagging rule deleted' - user_added: 'User "%username%" added' rss_token_updated: 'RSS token updated' + # annotations_reset: Annotations reset + # tags_reset: Tags reset + # entries_reset: Entries reset entry: notice: entry_already_saved: 'Entry already saved on %date%' @@ -495,3 +557,8 @@ flashes: notice: # client_created: 'New client created.' # client_deleted: 'Client deleted' + user: + notice: + # added: 'User "%username%" added' + # updated: 'User "%username%" updated' + # deleted: 'User "%username%" deleted' diff --git a/src/Wallabag/CoreBundle/Resources/views/base.html.twig b/src/Wallabag/CoreBundle/Resources/views/base.html.twig index a1a9a1368..289458d4f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/base.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/base.html.twig @@ -41,6 +41,8 @@ {% block css %} {% endblock %} {% block scripts %} + + {% endblock %}