# Build
/app/build
/build
+/coverage
# Composer PHAR
/composer.phar
--- /dev/null
+<?php
+
+namespace Wallabag\ApiBundle\Controller;
+
+use JMS\Serializer\SerializationContext;
+use JMS\Serializer\SerializerBuilder;
+use Nelmio\ApiDocBundle\Annotation\ApiDoc;
+use Symfony\Component\HttpFoundation\Response;
+
+class TaggingRuleRestController extends WallabagRestController
+{
+ /**
+ * Export all tagging rules as a json file.
+ *
+ * @ApiDoc()
+ *
+ * @return Response
+ */
+ public function getTaggingruleExportAction()
+ {
+ $this->validateAuthentication();
+
+ $data = SerializerBuilder::create()->build()->serialize(
+ $this->getUser()->getConfig()->getTaggingRules(),
+ 'json',
+ SerializationContext::create()->setGroups(['export_tagging_rule'])
+ );
+
+ return Response::create(
+ $data,
+ 200,
+ [
+ 'Content-type' => 'application/json',
+ 'Content-Disposition' => 'attachment; filename="tagging_rules_' . $this->getUser()->getUsername() . '.json"',
+ 'Content-Transfer-Encoding' => 'UTF-8',
+ ]
+ );
+ }
+}
resource: "WallabagApiBundle:TagRest"
name_prefix: api_
+tagging_rule:
+ type: rest
+ resource: "WallabagApiBundle:TaggingRuleRest"
+ name_prefix: api_
+
annotation:
type: rest
resource: "WallabagApiBundle:AnnotationRest"
namespace Wallabag\CoreBundle\Controller;
+use JMS\Serializer\SerializationContext;
+use JMS\Serializer\SerializerBuilder;
use PragmaRX\Recovery\Recovery as BackupCodes;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Constraints\Locale as LocaleConstraint;
use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
use Wallabag\CoreBundle\Form\Type\ConfigType;
use Wallabag\CoreBundle\Form\Type\FeedType;
+use Wallabag\CoreBundle\Form\Type\TaggingRuleImportType;
use Wallabag\CoreBundle\Form\Type\TaggingRuleType;
use Wallabag\CoreBundle\Form\Type\UserInformationType;
use Wallabag\CoreBundle\Tools\Utils;
return $this->redirect($this->generateUrl('config') . '#set5');
}
+ // handle tagging rules import
+ $taggingRulesImportform = $this->createForm(TaggingRuleImportType::class);
+ $taggingRulesImportform->handleRequest($request);
+
+ if ($taggingRulesImportform->isSubmitted() && $taggingRulesImportform->isValid()) {
+ $message = 'flashes.config.notice.tagging_rules_not_imported';
+ $file = $taggingRulesImportform->get('file')->getData();
+
+ if (null !== $file && $file->isValid() && \in_array($file->getClientMimeType(), ['application/json', 'application/octet-stream'], true)) {
+ $content = json_decode(file_get_contents($file->getPathname()), true);
+
+ if (\is_array($content)) {
+ foreach ($content as $rule) {
+ $taggingRule = new TaggingRule();
+ $taggingRule->setRule($rule['rule']);
+ $taggingRule->setTags($rule['tags']);
+ $taggingRule->setConfig($config);
+ $em->persist($taggingRule);
+ }
+
+ $em->flush();
+
+ $message = 'flashes.config.notice.tagging_rules_imported';
+ }
+ }
+
+ $this->addFlash('notice', $message);
+
+ return $this->redirect($this->generateUrl('config') . '#set5');
+ }
+
return $this->render('WallabagCoreBundle:Config:index.html.twig', [
'form' => [
'config' => $configForm->createView(),
'pwd' => $pwdForm->createView(),
'user' => $userForm->createView(),
'new_tagging_rule' => $newTaggingRule->createView(),
+ 'import_tagging_rule' => $taggingRulesImportform->createView(),
],
'feed' => [
'username' => $user->getUsername(),
return $this->redirect($request->headers->get('referer', $this->generateUrl('homepage')));
}
+ /**
+ * Export tagging rules for the logged in user.
+ *
+ * @Route("/tagging-rule/export", name="export_tagging_rule")
+ *
+ * @return Response
+ */
+ public function exportTaggingRulesAction()
+ {
+ $data = SerializerBuilder::create()->build()->serialize(
+ $this->getUser()->getConfig()->getTaggingRules(),
+ 'json',
+ SerializationContext::create()->setGroups(['export_tagging_rule'])
+ );
+
+ return Response::create(
+ $data,
+ 200,
+ [
+ 'Content-type' => 'application/json',
+ 'Content-Disposition' => 'attachment; filename="tagging_rules_' . $this->getUser()->getUsername() . '.json"',
+ 'Content-Transfer-Encoding' => 'UTF-8',
+ ]
+ );
+ }
+
/**
* Remove all tags for given tags and a given user and cleanup orphan tags.
*
namespace Wallabag\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
+use JMS\Serializer\Annotation\Exclude;
+use JMS\Serializer\Annotation\Groups;
+use JMS\Serializer\Annotation\XmlRoot;
use Symfony\Bridge\RulerZ\Validator\Constraints as RulerZAssert;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Tagging rule.
*
+ * @XmlRoot("tagging_rule")
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\TaggingRuleRepository")
* @ORM\Table(name="`tagging_rule`")
* @ORM\Entity
* allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches", "notmatches"}
* )
* @ORM\Column(name="rule", type="string", nullable=false)
+ *
+ * @Groups({"export_tagging_rule"})
*/
private $rule;
*
* @Assert\NotBlank()
* @ORM\Column(name="tags", type="simple_array", nullable=false)
+ *
+ * @Groups({"export_tagging_rule"})
*/
private $tags = [];
/**
+ * @Exclude
+ *
* @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Config", inversedBy="taggingRules")
*/
private $config;
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\FileType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\FormBuilderInterface;
+
+class TaggingRuleImportType extends AbstractType
+{
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $builder
+ ->add('file', FileType::class, [
+ 'label' => 'config.form_rules.file_label',
+ 'required' => true,
+ ])
+ ->add('import', SubmitType::class, [
+ 'label' => 'config.form_rules.import_submit',
+ ])
+ ;
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'upload_tagging_rule_file';
+ }
+}
# edit_rule_label: 'edit'
# rule_label: 'Rule'
# tags_label: 'Tags'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
# faq:
# title: 'FAQ'
# tagging_rules_definition_title: 'What does « tagging rules » mean?'
# tags_reset: Tags reset
# entries_reset: Entries reset
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
edit_rule_label: 'bearbeiten'
rule_label: 'Regel'
tags_label: 'Tags'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'Was bedeuten die "Tagging-Regeln"?'
and: 'Eine Regel UND eine andere'
matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>'
notmatches: 'Testet, ob ein <i>Titel</i> nicht auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title notmatches "Fußball"</code>'
+ otp:
+ # page_title: Two-factor authentication
+ # app:
+ # two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
+ # two_factor_code_description_2: 'You can scan that QR Code with your app:'
+ # two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
+ # two_factor_code_description_4: 'Test an OTP code from your configured app:'
+ # cancel: Cancel
+ # enable: Enable
entry:
default_title: 'Titel des Eintrags'
tags_reset: Tags zurücksetzen
entries_reset: Einträge zurücksetzen
archived_reset: Archiverte Einträge zurücksetzen
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Eintrag bereits am %date% gespeichert'
edit_rule_label: 'edit'
rule_label: 'Rule'
tags_label: 'Tags'
+ card:
+ new_tagging_rule: Create a tagging rule
+ import_tagging_rules: Import tagging rules
+ import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ export_tagging_rules: Export tagging rules
+ export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ file_label: JSON file
+ import_submit: Import
+ export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'What does « tagging rules » mean?'
entries_reset: Entries reset
archived_reset: Archived entries deleted
otp_enabled: Two-factor authentication enabled
+ tagging_rules_imported: Tagging rules imported
+ tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
edit_rule_label: 'editar'
rule_label: 'Regla'
tags_label: 'Etiquetas'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'Preguntas frecuentes'
tagging_rules_definition_title: '¿Qué significa « reglas de etiquetado automático »?'
tags_reset: Etiquetas reiniciadas
entries_reset: Artículos reiniciados
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Artículo ya guardado el %fecha%'
# edit_rule_label: 'edit'
rule_label: 'قانون'
tags_label: 'برچسبها'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'پرسشهای متداول'
tagging_rules_definition_title: 'برچسبگذاری خودکار یعنی چه؟'
# tags_reset: Tags reset
# entries_reset: Entries reset
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
edit_rule_label: "éditer"
rule_label: "Règle"
tags_label: "Tags"
+ card:
+ new_tagging_rule: Créer une règle
+ import_tagging_rules: Importer des règles
+ import_tagging_rules_detail: Vous devez sélectionné un fichier JSON que vous avez précédemment exporté.
+ export_tagging_rules: Exporter les règles
+ export_tagging_rules_detail: Un fichier JSON sera téléchargé et vous pourrez l'utiliser pour ré-importer les règles ou comme sauvegarde.
+ file_label: Fichier JSON
+ import_submit: Importer
+ export: Export
faq:
title: "FAQ"
tagging_rules_definition_title: "Que signifient les règles de tag automatiques ?"
entries_reset: "Articles supprimés"
archived_reset: "Articles archivés supprimés"
otp_enabled: "Authentification à double-facteur activée"
+ tagging_rules_imported: Règles bien importées
+ tagging_rules_not_imported: Impossible d'importer les règles
entry:
notice:
entry_already_saved: "Article déjà sauvegardé le %date%"
# login_label: 'Login (can not be changed)'
name_label: 'Nome'
email_label: 'E-mail'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
edit_rule_label: 'modifica'
rule_label: 'Regola'
tags_label: 'Etichetta'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'Cosa significa « regole di etichettatura » ?'
tags_reset: Reset etichette
entries_reset: Reset articoli
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Contenuto già salvato in data %date%'
# login_label: 'Login (can not be changed)'
name_label: 'Nom'
email_label: 'Adreça de corrièl'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
edit_rule_label: 'modificar'
rule_label: 'Règla'
tags_label: 'Etiquetas'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: "Qué significa las règlas d'etiquetas automaticas ?"
tags_reset: Etiquetas levadas
entries_reset: Articles levats
archived_reset: Articles archivat suprimits
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Article ja salvagardat lo %date%'
# login_label: 'Login (can not be changed)'
name_label: 'Nazwa'
email_label: 'Adres email'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
edit_rule_label: 'edytuj'
rule_label: 'Reguła'
tags_label: 'Tagi'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'Co oznaczają « reguły tagowania » ?'
tags_reset: Zresetuj tagi
entries_reset: Zresetuj wpisy
archived_reset: Zarchiwizowane wpisy usunięte
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Wpis już został dodany %date%'
# login_label: 'Login (can not be changed)'
name_label: 'Nome'
email_label: 'E-mail'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
edit_rule_label: 'editar'
rule_label: 'Regras'
tags_label: 'Tags'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'O que as « regras de tags » significam?'
# tags_reset: Tags reset
# entries_reset: Entries reset
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Entrada já foi salva em %date%'
# login_label: 'Login (can not be changed)'
name_label: 'Nume'
email_label: 'E-mail'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
# edit_rule_label: 'edit'
# rule_label: 'Rule'
# tags_label: 'Tags'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
# faq:
# title: 'FAQ'
# tagging_rules_definition_title: 'What does « tagging rules » mean?'
rename:
# placeholder: 'You can update tag name.'
-# export:
-# footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
-# unknown: 'Unknown'
+export:
+ # footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
+ # unknown: 'Unknown'
import:
# page_title: 'Import'
# tags_reset: Tags reset
# entries_reset: Entries reset
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
redirect_current_page: 'На текущую страницу'
pocket_consumer_key_label: "Ключ от Pocket для импорта контента"
android_configuration: "Настройте Ваше Android приложение"
+ # android_instruction: "Touch here to prefill your Android application"
help_theme: "wallabag настраиваемый, здесь Вы можете выбрать тему."
help_items_per_page: "Вы можете выбрать количество отображаемых записей на странице."
help_reading_speed: "wallabag посчитает сколько времени занимает чтение каждой записи. Вы можете определить здесь, как быстро вы читаете. wallabag пересчитает время чтения для каждой записи."
unread: 'непрочитанные'
starred: 'помеченные'
archive: 'архивные'
+ # all: 'All'
feed_limit: 'Количество записей в фиде'
form_user:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
# login_label: 'Login (can not be changed)'
name_label: 'Имя'
email_label: 'Email'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
annotations: "Удалить все аннотации"
tags: "Удалить все теги"
entries: "Удалить все записи"
+ # archived: Remove ALL archived entries
confirm: "Вы уверены? (Данные будут БЕЗВОЗВРАТНО удалены, эти действия необратимы)"
form_password:
description: "Здесь Вы можете поменять своя пароль. Ваш пароль должен быть длиннее 8 символов."
edit_rule_label: 'изменить'
rule_label: 'Правило'
tags_label: 'теги'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'Что значит "правило тегирования"?'
or: 'Одно правило ИЛИ другое'
and: 'Одно правило И другое'
matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
+ # notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
filtered_tags: 'Отфильтрованные по тегу:'
filtered_search: 'Отфильтрованные по поиску:'
untagged: 'Записи без тегов'
+ # all: 'All entries'
list:
number_on_the_page: '{0} Записей не обнаружено.|{1} Одна запись.|]1,Inf[ Найдено %count% записей.'
reading_time: 'расчетное время чтения'
unread_label: 'Непрочитанная'
preview_picture_label: 'Есть картинка предварительного просмотра'
preview_picture_help: 'Картинка предварительного просмотра'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Язык'
http_status_label: 'статус HTTP'
reading_time:
original_article: 'оригинал'
annotations_on_the_entry: '{0} Нет аннотации|{1} Одна аннотация|]1,Inf[ %count% аннотаций'
created_at: 'Дата создания'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
# provided_by: 'Provided by'
new:
page_title: 'Сохранить новую запись'
title_label: 'Название'
url_label: 'Ссылка'
# origin_url_label: 'Origin url (from where you found that entry)'
- is_public_label: 'Публичная'
save_label: 'Сохранить'
public:
shared_by_wallabag: "Запись была опубликована <a href='%wallabag_instance%'>wallabag</a>"
+ confirm:
+ # delete: "Are you sure you want to remove that article?"
+ # delete_tag: "Are you sure you want to remove that tag from that article?"
metadata:
# reading_time: "Estimated reading time"
# reading_time_minutes_short: "%readingTime% min"
rename:
# placeholder: 'You can update tag name.'
-# export:
-# footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
-# unknown: 'Unknown'
+export:
+ # footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
+ # unknown: 'Unknown'
import:
page_title: 'Импорт'
delete: "Удалить"
delete_confirm: "Вы уверены?"
back_to_list: "Назад к списку"
+ search:
+ # placeholder: Filter by login or email
+
+site_credential:
+ # page_title: Site credentials management
+ # new_site_credential: Create a credential
+ # edit_site_credential: Edit an existing credential
+ # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc."
+ # list:
+ # actions: Actions
+ # edit_action: Edit
+ # yes: Yes
+ # no: No
+ # create_new_one: Create a new credential
+ # form:
+ # username_label: 'Login'
+ # host_label: 'Host (subdomain.example.org, .example.org, etc.)'
+ # password_label: 'Password'
+ # save: Save
+ # delete: Delete
+ # delete_confirm: Are you sure?
+ # back_to_list: Back to list
error:
page_title: "Произошла ошибка"
annotations_reset: "Аннотации сброшены"
tags_reset: "Теги сброшены"
entries_reset: "Записи сброшены"
+ # archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Запись была сохранена ранее %date%'
added: 'Пользователь "%username%" добавлен'
updated: 'Пользователь "%username%" обновлен'
deleted: 'Пользователь "%username%" удален'
+ site_credential:
+ notice:
+ # added: 'Site credential for "%host%" added'
+ # updated: 'Site credential for "%host%" updated'
+ # deleted: 'Site credential for "%host%" deleted'
# login_label: 'Login (can not be changed)'
name_label: 'ชื่อ'
email_label: 'อีเมล'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
edit_rule_label: 'ปรับแก้'
rule_label: 'ข้อบังคับ'
tags_label: 'แท็ก'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'FAQ'
tagging_rules_definition_title: 'ข้อบังคับการแท็กคืออะไร?'
created_at: 'วันที่สร้าง'
published_at: 'วันที่ประกาศ'
published_by: 'ประกาศโดย'
+ # provided_by: 'Provided by'
new:
page_title: 'บันทึกรายการใหม่'
placeholder: 'http://website.com'
page_title: 'แก้ไขรายการ'
title_label: 'หัวข้อ'
url_label: 'Url'
+ # origin_url_label: 'Origin url (from where you found that entry)'
save_label: 'บันทึก'
public:
shared_by_wallabag: "บทความนี้จะมีการแชร์โดย %username% กับ <a href='%wallabag_instance%'>wallabag</a>"
tags_reset: รีเซ็ตแท็ก
entries_reset: รีเซ็ตรายการ
archived_reset: การลบเอกสารของรายการ
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'รายการพร้อมบันทึกที่ %date%'
# login_label: 'Login (can not be changed)'
name_label: 'İsim'
email_label: 'E-posta'
+ two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# table_method: Method
# edit_rule_label: 'edit'
rule_label: 'Kural'
tags_label: 'Etiketler'
+ # card:
+ # new_tagging_rule: Create a tagging rule
+ # import_tagging_rules: Import tagging rules
+ # import_tagging_rules_detail: You have to select the JSON file you previously exported.
+ # export_tagging_rules: Export tagging rules
+ # export_tagging_rules_detail: This will download a JSON file that you can use to import tagging rules elsewhere or to backup them.
+ # file_label: JSON file
+ # import_submit: Import
+ # export: Export
faq:
title: 'S.S.S.'
tagging_rules_definition_title: '« etiketleme kuralları » ne anlama geliyor?'
unread_label: 'Okunmayan'
preview_picture_label: 'Resim önizlemesi varsa'
preview_picture_help: 'Resim önizlemesi'
+ # is_public_label: 'Has a public link'
+ # is_public_help: 'Public link'
language_label: 'Dil'
# http_status_label: 'HTTP status'
reading_time:
rename:
# placeholder: 'You can update tag name.'
-# export:
-# footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
-# unknown: 'Unknown'
+export:
+ # footer_template: '<div style="text-align:center;"><p>Produced by wallabag with %method%</p><p>Please open <a href="https://github.com/wallabag/wallabag/issues">an issue</a> if you have trouble with the display of this E-Book on your device.</p></div>'
+ # unknown: 'Unknown'
import:
page_title: 'İçe Aktar'
search:
# placeholder: Filter by username or email
+site_credential:
+ # page_title: Site credentials management
+ # new_site_credential: Create a credential
+ # edit_site_credential: Edit an existing credential
+ # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc."
+ # list:
+ # actions: Actions
+ # edit_action: Edit
+ # yes: Yes
+ # no: No
+ # create_new_one: Create a new credential
+ # form:
+ # username_label: 'Login'
+ # host_label: 'Host (subdomain.example.org, .example.org, etc.)'
+ # password_label: 'Password'
+ # save: Save
+ # delete: Delete
+ # delete_confirm: Are you sure?
+ # back_to_list: Back to list
+
error:
# page_title: An error occurred
password_not_updated_demo: "In demonstration mode, you can't change password for this user."
user_updated: 'Bilgiler güncellendi'
feed_updated: 'RSS bilgiler güncellendi'
- tagging_rules_updated: 'Tagging rules updated'
- tagging_rules_deleted: 'Tagging rule deleted'
- feed_token_updated: 'RSS token updated'
+ # tagging_rules_updated: 'Tagging rules updated'
+ # tagging_rules_deleted: 'Tagging rule deleted'
+ # feed_token_updated: 'RSS token updated'
+ # feed_token_revoked: 'RSS token revoked'
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
# archived_reset: Archived entries deleted
+ # otp_enabled: Two-factor authentication enabled
+ # tagging_rules_imported: Tagging rules imported
+ # tagging_rules_not_imported: Error while importing tagging rules
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
{{ form_rest(form.new_tagging_rule) }}
</form>
+
+ <div class="row">
+ <h3>{{ 'config.form_rules.card.import_tagging_rules'|trans }}</h3>
+ <p>{{ 'config.form_rules.card.import_tagging_rules_detail'|trans }}</p>
+ </div>
+
+ {{ form_start(form.import_tagging_rule) }}
+ {{ form_errors(form.import_tagging_rule) }}
+
+ <fieldset class="w500p inline">
+ <div class="row">
+ {{ form_label(form.import_tagging_rule.file) }}
+ {{ form_errors(form.import_tagging_rule.file) }}
+ {{ form_widget(form.import_tagging_rule.file) }}
+ </div>
+ </fieldset>
+
+ {{ form_rest(form.import_tagging_rule) }}
+ </form>
+
+ {% if app.user.config.taggingRules is not empty %}
+ <div class="row">
+ <h3>{{ 'config.form_rules.card.export_tagging_rules'|trans }}</h3>
+ <p>{{ 'config.form_rules.card.export_tagging_rules_detail'|trans }}</p>
+ <p><a href="{{ path('export_tagging_rule') }}" class="waves-effect waves-light btn">{{ 'config.form_rules.export'|trans }}</a></p>
+ </div>
+ {% endif %}
+
<div class="row">
<div class="input-field col s12">
<h3>{{ 'config.form_rules.faq.title'|trans }}</h3>
</div>
{% endif %}
- {{ form_start(form.new_tagging_rule) }}
- {{ form_errors(form.new_tagging_rule) }}
-
- <div class="row">
- <div class="input-field col s12">
- {{ form_label(form.new_tagging_rule.rule) }}
- {{ form_errors(form.new_tagging_rule.rule) }}
- {{ form_widget(form.new_tagging_rule.rule) }}
+ <ul class="row">
+ <li class="col l6 m6 s12">
+ <div class="card">
+ <div class="card-content">
+ <span class="card-title">{{ 'config.form_rules.card.new_tagging_rule'|trans }}</span>
+
+ {{ form_start(form.new_tagging_rule) }}
+ {{ form_errors(form.new_tagging_rule) }}
+
+ <div class="row">
+ <div class="input-field col s12">
+ {{ form_label(form.new_tagging_rule.rule) }}
+ {{ form_errors(form.new_tagging_rule.rule) }}
+ {{ form_widget(form.new_tagging_rule.rule) }}
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="input-field col s12">
+ {{ form_label(form.new_tagging_rule.tags) }}
+ {{ form_errors(form.new_tagging_rule.tags) }}
+ {{ form_widget(form.new_tagging_rule.tags) }}
+ </div>
+ </div>
+
+ {{ form_widget(form.new_tagging_rule.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+ {{ form_rest(form.new_tagging_rule) }}
+ </form>
+ </div>
</div>
- </div>
-
- <div class="row">
- <div class="input-field col s12">
- {{ form_label(form.new_tagging_rule.tags) }}
- {{ form_errors(form.new_tagging_rule.tags) }}
- {{ form_widget(form.new_tagging_rule.tags) }}
+ </li>
+ <li class="col l6 m6 s12">
+ <div class="card z-depth-1">
+ <div class="card-content">
+ <span class="card-title">{{ 'config.form_rules.card.import_tagging_rules'|trans }}</span>
+ <p>{{ 'config.form_rules.card.import_tagging_rules_detail'|trans }}</p>
+ {{ form_start(form.import_tagging_rule) }}
+ {{ form_errors(form.import_tagging_rule) }}
+ <div class="row">
+ <div class="file-field input-field col s12">
+ {{ form_errors(form.import_tagging_rule.file) }}
+ <div class="btn">
+ <span>{{ form.import_tagging_rule.file.vars.label|trans }}</span>
+ {{ form_widget(form.import_tagging_rule.file) }}
+ </div>
+ <div class="file-path-wrapper">
+ <input class="file-path validate" type="text">
+ </div>
+ </div>
+ </div>
+
+ {{ form_widget(form.import_tagging_rule.import, { 'attr': {'class': 'btn waves-effect waves-light'} }) }}
+
+ {{ form_rest(form.import_tagging_rule) }}
+ </form>
+ </div>
</div>
- </div>
-
- {{ form_widget(form.new_tagging_rule.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
- {{ form_rest(form.new_tagging_rule) }}
- </form>
+ </li>
+ {% if app.user.config.taggingRules is not empty %}
+ <li class="col l6 m6 s12">
+ <div class="card z-depth-1">
+ <div class="card-content">
+ <span class="card-title">{{ 'config.form_rules.card.export_tagging_rules'|trans }}</span>
+ <p>{{ 'config.form_rules.card.export_tagging_rules_detail'|trans }}</p>
+ <br/>
+ <p><a href="{{ path('export_tagging_rule') }}" class="waves-effect waves-light btn">{{ 'config.form_rules.export'|trans }}</a></p>
+ </div>
+ </div>
+ </li>
+ {% endif %}
+ </ul>
<div class="row">
<div class="input-field col s12">
--- /dev/null
+<?php
+
+namespace Tests\Wallabag\ApiBundle\Controller;
+
+use Tests\Wallabag\ApiBundle\WallabagApiTestCase;
+
+class TaggingRuleRestControllerTest extends WallabagApiTestCase
+{
+ public function testExportEntry()
+ {
+ $this->client->request('GET', '/api/taggingrule/export');
+ $this->assertSame(200, $this->client->getResponse()->getStatusCode());
+ $this->assertSame('application/json', $this->client->getResponse()->headers->get('Content-Type'));
+ }
+}
namespace Tests\Wallabag\CoreBundle\Controller;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\AnnotationBundle\Entity\Annotation;
use Wallabag\CoreBundle\Entity\Config;
$this->assertFalse($user->isGoogleTwoFactor());
$this->assertEmpty($user->getBackupCodes());
}
+
+ public function testExportTaggingRule()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ ob_start();
+ $crawler = $client->request('GET', '/tagging-rule/export');
+ ob_end_clean();
+
+ $this->assertSame(200, $client->getResponse()->getStatusCode());
+
+ $headers = $client->getResponse()->headers;
+ $this->assertSame('application/json', $headers->get('content-type'));
+ $this->assertSame('attachment; filename="tagging_rules_admin.json"', $headers->get('content-disposition'));
+ $this->assertSame('UTF-8', $headers->get('content-transfer-encoding'));
+
+ $content = json_decode($client->getResponse()->getContent(), true);
+
+ $this->assertCount(4, $content);
+ $this->assertSame('content matches "spurs"', $content[0]['rule']);
+ $this->assertSame('sport', $content[0]['tags'][0]);
+ }
+
+ public function testImportTagginfRuleBadFile()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/config');
+ $form = $crawler->filter('form[name=upload_tagging_rule_file] > button[type=submit]')->form();
+
+ $data = [
+ 'upload_tagging_rule_file[file]' => '',
+ ];
+
+ $client->submit($form, $data);
+
+ $this->assertSame(302, $client->getResponse()->getStatusCode());
+ }
+
+ public function testImportTagginfRuleFile()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/config');
+ $form = $crawler->filter('form[name=upload_tagging_rule_file] > button[type=submit]')->form();
+
+ $file = new UploadedFile(__DIR__ . '/../fixtures/tagging_rules_admin.json', 'tagging_rules_admin.json');
+
+ $data = [
+ 'upload_tagging_rule_file[file]' => $file,
+ ];
+
+ $client->submit($form, $data);
+ $this->assertSame(302, $client->getResponse()->getStatusCode());
+
+ $user = $client->getContainer()->get('fos_user.user_manager.test')->findUserBy(['username' => 'admin']);
+ $taggingRules = $user->getConfig()->getTaggingRules()->toArray();
+ $this->assertCount(5, $taggingRules);
+ $this->assertSame('title matches "football"', $taggingRules[4]->getRule());
+ }
}
--- /dev/null
+[{
+ "rule": "title matches \"football\"",
+ "tags": ["football"]
+}]