aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/CoreBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/CoreBundle')
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php37
-rw-r--r--src/Wallabag/CoreBundle/Controller/ConfigController.php112
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php14
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php10
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php7
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php6
-rw-r--r--src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php26
-rw-r--r--src/Wallabag/CoreBundle/Event/EntrySavedEvent.php26
-rw-r--r--src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php (renamed from src/Wallabag/CoreBundle/EventListener/LocaleListener.php)2
-rw-r--r--src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php (renamed from src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php)2
-rw-r--r--src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php121
-rw-r--r--src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php70
-rw-r--r--src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php (renamed from src/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriber.php)2
-rw-r--r--src/Wallabag/CoreBundle/Helper/ContentProxy.php5
-rw-r--r--src/Wallabag/CoreBundle/Helper/DownloadImages.php233
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php14
-rw-r--r--src/Wallabag/CoreBundle/Repository/TagRepository.php18
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml30
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml17
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml99
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml25
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml23
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig41
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig40
32 files changed, 1066 insertions, 78 deletions
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index 857a8b4c..9fe90357 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -40,7 +40,7 @@ class InstallCommand extends ContainerAwareCommand
40 { 40 {
41 $this 41 $this
42 ->setName('wallabag:install') 42 ->setName('wallabag:install')
43 ->setDescription('Wallabag installer.') 43 ->setDescription('wallabag installer.')
44 ->addOption( 44 ->addOption(
45 'reset', 45 'reset',
46 null, 46 null,
@@ -55,7 +55,7 @@ class InstallCommand extends ContainerAwareCommand
55 $this->defaultInput = $input; 55 $this->defaultInput = $input;
56 $this->defaultOutput = $output; 56 $this->defaultOutput = $output;
57 57
58 $output->writeln('<info>Installing Wallabag...</info>'); 58 $output->writeln('<info>Installing wallabag...</info>');
59 $output->writeln(''); 59 $output->writeln('');
60 60
61 $this 61 $this
@@ -65,7 +65,7 @@ class InstallCommand extends ContainerAwareCommand
65 ->setupConfig() 65 ->setupConfig()
66 ; 66 ;
67 67
68 $output->writeln('<info>Wallabag has been successfully installed.</info>'); 68 $output->writeln('<info>wallabag has been successfully installed.</info>');
69 $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); 69 $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>');
70 } 70 }
71 71
@@ -77,7 +77,7 @@ class InstallCommand extends ContainerAwareCommand
77 77
78 // testing if database driver exists 78 // testing if database driver exists
79 $fulfilled = true; 79 $fulfilled = true;
80 $label = '<comment>PDO Driver</comment>'; 80 $label = '<comment>PDO Driver (%s)</comment>';
81 $status = '<info>OK!</info>'; 81 $status = '<info>OK!</info>';
82 $help = ''; 82 $help = '';
83 83
@@ -87,7 +87,7 @@ class InstallCommand extends ContainerAwareCommand
87 $help = 'Database driver "'.$this->getContainer()->getParameter('database_driver').'" is not installed.'; 87 $help = 'Database driver "'.$this->getContainer()->getParameter('database_driver').'" is not installed.';
88 } 88 }
89 89
90 $rows[] = [$label, $status, $help]; 90 $rows[] = [sprintf($label, $this->getContainer()->getParameter('database_driver')), $status, $help];
91 91
92 // testing if connection to the database can be etablished 92 // testing if connection to the database can be etablished
93 $label = '<comment>Database connection</comment>'; 93 $label = '<comment>Database connection</comment>';
@@ -95,7 +95,8 @@ class InstallCommand extends ContainerAwareCommand
95 $help = ''; 95 $help = '';
96 96
97 try { 97 try {
98 $this->getContainer()->get('doctrine')->getManager()->getConnection()->connect(); 98 $conn = $this->getContainer()->get('doctrine')->getManager()->getConnection();
99 $conn->connect();
99 } catch (\Exception $e) { 100 } catch (\Exception $e) {
100 if (false === strpos($e->getMessage(), 'Unknown database') 101 if (false === strpos($e->getMessage(), 'Unknown database')
101 && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) { 102 && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) {
@@ -107,6 +108,21 @@ class InstallCommand extends ContainerAwareCommand
107 108
108 $rows[] = [$label, $status, $help]; 109 $rows[] = [$label, $status, $help];
109 110
111 // now check if MySQL isn't too old to handle utf8mb4
112 if ($conn->isConnected() && $conn->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) {
113 $version = $conn->query('select version()')->fetchColumn();
114 $minimalVersion = '5.5.4';
115
116 if (false === version_compare($version, $minimalVersion, '>')) {
117 $fulfilled = false;
118 $rows[] = [
119 '<comment>Database version</comment>',
120 '<error>ERROR!</error>',
121 'Your MySQL version ('.$version.') is too old, consider upgrading ('.$minimalVersion.'+).',
122 ];
123 }
124 }
125
110 foreach ($this->functionExists as $functionRequired) { 126 foreach ($this->functionExists as $functionRequired) {
111 $label = '<comment>'.$functionRequired.'</comment>'; 127 $label = '<comment>'.$functionRequired.'</comment>';
112 $status = '<info>OK!</info>'; 128 $status = '<info>OK!</info>';
@@ -131,7 +147,7 @@ class InstallCommand extends ContainerAwareCommand
131 throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); 147 throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
132 } 148 }
133 149
134 $this->defaultOutput->writeln('<info>Success! Your system can run Wallabag properly.</info>'); 150 $this->defaultOutput->writeln('<info>Success! Your system can run wallabag properly.</info>');
135 151
136 $this->defaultOutput->writeln(''); 152 $this->defaultOutput->writeln('');
137 153
@@ -354,7 +370,7 @@ class InstallCommand extends ContainerAwareCommand
354 ], 370 ],
355 [ 371 [
356 'name' => 'wallabag_url', 372 'name' => 'wallabag_url',
357 'value' => 'http://v2.wallabag.org', 373 'value' => '',
358 'section' => 'misc', 374 'section' => 'misc',
359 ], 375 ],
360 [ 376 [
@@ -382,6 +398,11 @@ class InstallCommand extends ContainerAwareCommand
382 'value' => 'wallabag', 398 'value' => 'wallabag',
383 'section' => 'misc', 399 'section' => 'misc',
384 ], 400 ],
401 [
402 'name' => 'download_images_enabled',
403 'value' => '0',
404 'section' => 'misc',
405 ],
385 ]; 406 ];
386 407
387 foreach ($settings as $setting) { 408 foreach ($settings as $setting) {
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php
index 91cdcae5..d40efcd7 100644
--- a/src/Wallabag/CoreBundle/Controller/ConfigController.php
+++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php
@@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7use Symfony\Component\HttpFoundation\JsonResponse; 7use Symfony\Component\HttpFoundation\JsonResponse;
8use Symfony\Component\HttpFoundation\RedirectResponse; 8use Symfony\Component\HttpFoundation\RedirectResponse;
9use Symfony\Component\HttpFoundation\Request; 9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
10use Wallabag\CoreBundle\Entity\Config; 11use Wallabag\CoreBundle\Entity\Config;
11use Wallabag\CoreBundle\Entity\TaggingRule; 12use Wallabag\CoreBundle\Entity\TaggingRule;
12use Wallabag\CoreBundle\Form\Type\ConfigType; 13use Wallabag\CoreBundle\Form\Type\ConfigType;
@@ -148,6 +149,10 @@ class ConfigController extends Controller
148 'token' => $config->getRssToken(), 149 'token' => $config->getRssToken(),
149 ], 150 ],
150 'twofactor_auth' => $this->getParameter('twofactor_auth'), 151 'twofactor_auth' => $this->getParameter('twofactor_auth'),
152 'wallabag_url' => $this->get('craue_config')->get('wallabag_url'),
153 'enabled_users' => $this->getDoctrine()
154 ->getRepository('WallabagUserBundle:User')
155 ->getSumEnabledUsers(),
151 ]); 156 ]);
152 } 157 }
153 158
@@ -221,6 +226,80 @@ class ConfigController extends Controller
221 } 226 }
222 227
223 /** 228 /**
229 * Remove all annotations OR tags OR entries for the current user.
230 *
231 * @Route("/reset/{type}", requirements={"id" = "annotations|tags|entries"}, name="config_reset")
232 *
233 * @return RedirectResponse
234 */
235 public function resetAction($type)
236 {
237 $em = $this->getDoctrine()->getManager();
238
239 switch ($type) {
240 case 'annotations':
241 $this->getDoctrine()
242 ->getRepository('WallabagAnnotationBundle:Annotation')
243 ->removeAllByUserId($this->getUser()->getId());
244 break;
245
246 case 'tags':
247 $this->removeAllTagsByUserId($this->getUser()->getId());
248 break;
249
250 case 'entries':
251 // SQLite doesn't care about cascading remove, so we need to manually remove associated stuf
252 // otherwise they won't be removed ...
253 if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
254 $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId());
255 }
256
257 // manually remove tags to avoid orphan tag
258 $this->removeAllTagsByUserId($this->getUser()->getId());
259
260 $this->getDoctrine()
261 ->getRepository('WallabagCoreBundle:Entry')
262 ->removeAllByUserId($this->getUser()->getId());
263 }
264
265 $this->get('session')->getFlashBag()->add(
266 'notice',
267 'flashes.config.notice.'.$type.'_reset'
268 );
269
270 return $this->redirect($this->generateUrl('config').'#set3');
271 }
272
273 /**
274 * Remove all tags for a given user and cleanup orphan tags.
275 *
276 * @param int $userId
277 */
278 private function removeAllTagsByUserId($userId)
279 {
280 $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
281
282 if (empty($tags)) {
283 return;
284 }
285
286 $this->getDoctrine()
287 ->getRepository('WallabagCoreBundle:Entry')
288 ->removeTags($userId, $tags);
289
290 // cleanup orphan tags
291 $em = $this->getDoctrine()->getManager();
292
293 foreach ($tags as $tag) {
294 if (count($tag->getEntries()) === 0) {
295 $em->remove($tag);
296 }
297 }
298
299 $em->flush();
300 }
301
302 /**
224 * Validate that a rule can be edited/deleted by the current user. 303 * Validate that a rule can be edited/deleted by the current user.
225 * 304 *
226 * @param TaggingRule $rule 305 * @param TaggingRule $rule
@@ -251,4 +330,37 @@ class ConfigController extends Controller
251 330
252 return $config; 331 return $config;
253 } 332 }
333
334 /**
335 * Delete account for current user.
336 *
337 * @Route("/account/delete", name="delete_account")
338 *
339 * @param Request $request
340 *
341 * @throws AccessDeniedHttpException
342 *
343 * @return \Symfony\Component\HttpFoundation\RedirectResponse
344 */
345 public function deleteAccountAction(Request $request)
346 {
347 $enabledUsers = $this->getDoctrine()
348 ->getRepository('WallabagUserBundle:User')
349 ->getSumEnabledUsers();
350
351 if ($enabledUsers <= 1) {
352 throw new AccessDeniedHttpException();
353 }
354
355 $user = $this->getUser();
356
357 // logout current user
358 $this->get('security.token_storage')->setToken(null);
359 $request->getSession()->invalidate();
360
361 $em = $this->get('fos_user.user_manager');
362 $em->deleteUser($user);
363
364 return $this->redirect($this->generateUrl('fos_user_security_login'));
365 }
254} 366}
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 97bb3d12..3f4eb17d 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -13,6 +13,8 @@ use Wallabag\CoreBundle\Form\Type\EntryFilterType;
13use Wallabag\CoreBundle\Form\Type\EditEntryType; 13use Wallabag\CoreBundle\Form\Type\EditEntryType;
14use Wallabag\CoreBundle\Form\Type\NewEntryType; 14use Wallabag\CoreBundle\Form\Type\NewEntryType;
15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; 15use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
16use Wallabag\CoreBundle\Event\EntrySavedEvent;
17use Wallabag\CoreBundle\Event\EntryDeletedEvent;
16 18
17class EntryController extends Controller 19class EntryController extends Controller
18{ 20{
@@ -81,6 +83,9 @@ class EntryController extends Controller
81 $em->persist($entry); 83 $em->persist($entry);
82 $em->flush(); 84 $em->flush();
83 85
86 // entry saved, dispatch event about it!
87 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
88
84 return $this->redirect($this->generateUrl('homepage')); 89 return $this->redirect($this->generateUrl('homepage'));
85 } 90 }
86 91
@@ -107,6 +112,9 @@ class EntryController extends Controller
107 $em = $this->getDoctrine()->getManager(); 112 $em = $this->getDoctrine()->getManager();
108 $em->persist($entry); 113 $em->persist($entry);
109 $em->flush(); 114 $em->flush();
115
116 // entry saved, dispatch event about it!
117 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
110 } 118 }
111 119
112 return $this->redirect($this->generateUrl('homepage')); 120 return $this->redirect($this->generateUrl('homepage'));
@@ -343,6 +351,9 @@ class EntryController extends Controller
343 $em->persist($entry); 351 $em->persist($entry);
344 $em->flush(); 352 $em->flush();
345 353
354 // entry saved, dispatch event about it!
355 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
356
346 return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); 357 return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()]));
347 } 358 }
348 359
@@ -431,6 +442,9 @@ class EntryController extends Controller
431 UrlGeneratorInterface::ABSOLUTE_PATH 442 UrlGeneratorInterface::ABSOLUTE_PATH
432 ); 443 );
433 444
445 // entry deleted, dispatch event about it!
446 $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
447
434 $em = $this->getDoctrine()->getManager(); 448 $em = $this->getDoctrine()->getManager();
435 $em->remove($entry); 449 $em->remove($entry);
436 $em->flush(); 450 $em->flush();
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index 707f3bbe..a3e70fd0 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -90,15 +90,15 @@ class TagController extends Controller
90 90
91 $flatTags = []; 91 $flatTags = [];
92 92
93 foreach ($tags as $key => $tag) { 93 foreach ($tags as $tag) {
94 $nbEntries = $this->getDoctrine() 94 $nbEntries = $this->getDoctrine()
95 ->getRepository('WallabagCoreBundle:Entry') 95 ->getRepository('WallabagCoreBundle:Entry')
96 ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag['id']); 96 ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag->getId());
97 97
98 $flatTags[] = [ 98 $flatTags[] = [
99 'id' => $tag['id'], 99 'id' => $tag->getId(),
100 'label' => $tag['label'], 100 'label' => $tag->getLabel(),
101 'slug' => $tag['slug'], 101 'slug' => $tag->getSlug(),
102 'nbEntries' => $nbEntries, 102 'nbEntries' => $nbEntries,
103 ]; 103 ];
104 } 104 }
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
index a5e1be65..d0085660 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
@@ -140,6 +140,11 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface
140 'value' => 'wallabag', 140 'value' => 'wallabag',
141 'section' => 'misc', 141 'section' => 'misc',
142 ], 142 ],
143 [
144 'name' => 'download_images_enabled',
145 'value' => '0',
146 'section' => 'misc',
147 ],
143 ]; 148 ];
144 149
145 foreach ($settings as $setting) { 150 foreach ($settings as $setting) {
@@ -158,6 +163,6 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface
158 */ 163 */
159 public function getOrder() 164 public function getOrder()
160 { 165 {
161 return 50; 166 return 29;
162 } 167 }
163} 168}
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index f2da3f4d..dd0f7e67 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -19,7 +19,7 @@ use Wallabag\AnnotationBundle\Entity\Annotation;
19 * 19 *
20 * @XmlRoot("entry") 20 * @XmlRoot("entry")
21 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") 21 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository")
22 * @ORM\Table(name="`entry`") 22 * @ORM\Table(name="`entry`", options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"})
23 * @ORM\HasLifecycleCallbacks() 23 * @ORM\HasLifecycleCallbacks()
24 * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") 24 * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())")
25 */ 25 */
@@ -190,10 +190,10 @@ class Entry
190 * @ORM\JoinTable( 190 * @ORM\JoinTable(
191 * name="entry_tag", 191 * name="entry_tag",
192 * joinColumns={ 192 * joinColumns={
193 * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") 193 * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade")
194 * }, 194 * },
195 * inverseJoinColumns={ 195 * inverseJoinColumns={
196 * @ORM\JoinColumn(name="tag_id", referencedColumnName="id") 196 * @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade")
197 * } 197 * }
198 * ) 198 * )
199 */ 199 */
diff --git a/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php
new file mode 100644
index 00000000..e9061d04
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php
@@ -0,0 +1,26 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event;
4
5use Symfony\Component\EventDispatcher\Event;
6use Wallabag\CoreBundle\Entity\Entry;
7
8/**
9 * This event is fired as soon as an entry is deleted.
10 */
11class EntryDeletedEvent extends Event
12{
13 const NAME = 'entry.deleted';
14
15 protected $entry;
16
17 public function __construct(Entry $entry)
18 {
19 $this->entry = $entry;
20 }
21
22 public function getEntry()
23 {
24 return $this->entry;
25 }
26}
diff --git a/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php
new file mode 100644
index 00000000..5fdb5221
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php
@@ -0,0 +1,26 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event;
4
5use Symfony\Component\EventDispatcher\Event;
6use Wallabag\CoreBundle\Entity\Entry;
7
8/**
9 * This event is fired as soon as an entry was saved.
10 */
11class EntrySavedEvent extends Event
12{
13 const NAME = 'entry.saved';
14
15 protected $entry;
16
17 public function __construct(Entry $entry)
18 {
19 $this->entry = $entry;
20 }
21
22 public function getEntry()
23 {
24 return $this->entry;
25 }
26}
diff --git a/src/Wallabag/CoreBundle/EventListener/LocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php
index a1c7e5ab..b435d99e 100644
--- a/src/Wallabag/CoreBundle/EventListener/LocaleListener.php
+++ b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\EventListener; 3namespace Wallabag\CoreBundle\Event\Listener;
4 4
5use Symfony\Component\EventDispatcher\EventSubscriberInterface; 5use Symfony\Component\EventDispatcher\EventSubscriberInterface;
6use Symfony\Component\HttpKernel\Event\GetResponseEvent; 6use Symfony\Component\HttpKernel\Event\GetResponseEvent;
diff --git a/src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php
index 82d1a63a..367cdfb0 100644
--- a/src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php
+++ b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\EventListener; 3namespace Wallabag\CoreBundle\Event\Listener;
4 4
5use Symfony\Component\HttpFoundation\Session\Session; 5use Symfony\Component\HttpFoundation\Session\Session;
6use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; 6use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php
new file mode 100644
index 00000000..4ebe837b
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php
@@ -0,0 +1,121 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event\Subscriber;
4
5use Symfony\Component\EventDispatcher\EventSubscriberInterface;
6use Psr\Log\LoggerInterface;
7use Wallabag\CoreBundle\Helper\DownloadImages;
8use Wallabag\CoreBundle\Entity\Entry;
9use Wallabag\CoreBundle\Event\EntrySavedEvent;
10use Wallabag\CoreBundle\Event\EntryDeletedEvent;
11use Doctrine\ORM\EntityManager;
12
13class DownloadImagesSubscriber implements EventSubscriberInterface
14{
15 private $em;
16 private $downloadImages;
17 private $enabled;
18 private $logger;
19
20 public function __construct(EntityManager $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger)
21 {
22 $this->em = $em;
23 $this->downloadImages = $downloadImages;
24 $this->enabled = $enabled;
25 $this->logger = $logger;
26 }
27
28 public static function getSubscribedEvents()
29 {
30 return [
31 EntrySavedEvent::NAME => 'onEntrySaved',
32 EntryDeletedEvent::NAME => 'onEntryDeleted',
33 ];
34 }
35
36 /**
37 * Download images and updated the data into the entry.
38 *
39 * @param EntrySavedEvent $event
40 */
41 public function onEntrySaved(EntrySavedEvent $event)
42 {
43 if (!$this->enabled) {
44 $this->logger->debug('DownloadImagesSubscriber: disabled.');
45
46 return;
47 }
48
49 $entry = $event->getEntry();
50
51 $html = $this->downloadImages($entry);
52 if (false !== $html) {
53 $this->logger->debug('DownloadImagesSubscriber: updated html.');
54
55 $entry->setContent($html);
56 }
57
58 // update preview picture
59 $previewPicture = $this->downloadPreviewImage($entry);
60 if (false !== $previewPicture) {
61 $this->logger->debug('DownloadImagesSubscriber: update preview picture.');
62
63 $entry->setPreviewPicture($previewPicture);
64 }
65
66 $this->em->persist($entry);
67 $this->em->flush();
68 }
69
70 /**
71 * Remove images related to the entry.
72 *
73 * @param EntryDeletedEvent $event
74 */
75 public function onEntryDeleted(EntryDeletedEvent $event)
76 {
77 if (!$this->enabled) {
78 $this->logger->debug('DownloadImagesSubscriber: disabled.');
79
80 return;
81 }
82
83 $this->downloadImages->removeImages($event->getEntry()->getId());
84 }
85
86 /**
87 * Download all images from the html.
88 *
89 * @todo If we want to add async download, it should be done in that method
90 *
91 * @param Entry $entry
92 *
93 * @return string|false False in case of async
94 */
95 private function downloadImages(Entry $entry)
96 {
97 return $this->downloadImages->processHtml(
98 $entry->getId(),
99 $entry->getContent(),
100 $entry->getUrl()
101 );
102 }
103
104 /**
105 * Download the preview picture.
106 *
107 * @todo If we want to add async download, it should be done in that method
108 *
109 * @param Entry $entry
110 *
111 * @return string|false False in case of async
112 */
113 private function downloadPreviewImage(Entry $entry)
114 {
115 return $this->downloadImages->processSingleImage(
116 $entry->getId(),
117 $entry->getPreviewPicture(),
118 $entry->getUrl()
119 );
120 }
121}
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php
new file mode 100644
index 00000000..3b4c4cf9
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php
@@ -0,0 +1,70 @@
1<?php
2
3namespace Wallabag\CoreBundle\Event\Subscriber;
4
5use Doctrine\Common\EventSubscriber;
6use Doctrine\ORM\Event\LifecycleEventArgs;
7use Wallabag\CoreBundle\Entity\Entry;
8use Doctrine\Bundle\DoctrineBundle\Registry;
9
10/**
11 * SQLite doesn't care about cascading remove, so we need to manually remove associated stuf for an Entry.
12 * Foreign Key Support can be enabled by running `PRAGMA foreign_keys = ON;` at runtime (AT RUNTIME !).
13 * But it needs a compilation flag that not all SQLite instance has ...
14 *
15 * @see https://www.sqlite.org/foreignkeys.html#fk_enable
16 */
17class SQLiteCascadeDeleteSubscriber implements EventSubscriber
18{
19 private $doctrine;
20
21 /**
22 * @param \Doctrine\Bundle\DoctrineBundle\Registry $doctrine
23 */
24 public function __construct(Registry $doctrine)
25 {
26 $this->doctrine = $doctrine;
27 }
28
29 /**
30 * @return array
31 */
32 public function getSubscribedEvents()
33 {
34 return [
35 'preRemove',
36 ];
37 }
38
39 /**
40 * We removed everything related to the upcoming removed entry because SQLite can't handle it on it own.
41 * We do it in the preRemove, because we can't retrieve tags in the postRemove (because the entry id is gone).
42 *
43 * @param LifecycleEventArgs $args
44 */
45 public function preRemove(LifecycleEventArgs $args)
46 {
47 $entity = $args->getEntity();
48
49 if (!$this->doctrine->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver ||
50 !$entity instanceof Entry) {
51 return;
52 }
53
54 $em = $this->doctrine->getManager();
55
56 if (null !== $entity->getTags()) {
57 foreach ($entity->getTags() as $tag) {
58 $entity->removeTag($tag);
59 }
60 }
61
62 if (null !== $entity->getAnnotations()) {
63 foreach ($entity->getAnnotations() as $annotation) {
64 $em->remove($annotation);
65 }
66 }
67
68 $em->flush();
69 }
70}
diff --git a/src/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php
index 0379ad6a..9013328f 100644
--- a/src/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriber.php
+++ b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\Subscriber; 3namespace Wallabag\CoreBundle\Event\Subscriber;
4 4
5use Doctrine\Common\EventSubscriber; 5use Doctrine\Common\EventSubscriber;
6use Doctrine\ORM\Event\LoadClassMetadataEventArgs; 6use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
index 8019df42..1986ab33 100644
--- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php
+++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
@@ -3,7 +3,7 @@
3namespace Wallabag\CoreBundle\Helper; 3namespace Wallabag\CoreBundle\Helper;
4 4
5use Graby\Graby; 5use Graby\Graby;
6use Psr\Log\LoggerInterface as Logger; 6use Psr\Log\LoggerInterface;
7use Wallabag\CoreBundle\Entity\Entry; 7use Wallabag\CoreBundle\Entity\Entry;
8use Wallabag\CoreBundle\Entity\Tag; 8use Wallabag\CoreBundle\Entity\Tag;
9use Wallabag\CoreBundle\Tools\Utils; 9use Wallabag\CoreBundle\Tools\Utils;
@@ -20,7 +20,7 @@ class ContentProxy
20 protected $logger; 20 protected $logger;
21 protected $tagRepository; 21 protected $tagRepository;
22 22
23 public function __construct(Graby $graby, RuleBasedTagger $tagger, TagRepository $tagRepository, Logger $logger) 23 public function __construct(Graby $graby, RuleBasedTagger $tagger, TagRepository $tagRepository, LoggerInterface $logger)
24 { 24 {
25 $this->graby = $graby; 25 $this->graby = $graby;
26 $this->tagger = $tagger; 26 $this->tagger = $tagger;
@@ -66,6 +66,7 @@ class ContentProxy
66 $entry->setUrl($content['url'] ?: $url); 66 $entry->setUrl($content['url'] ?: $url);
67 $entry->setTitle($title); 67 $entry->setTitle($title);
68 $entry->setContent($html); 68 $entry->setContent($html);
69
69 $entry->setLanguage($content['language']); 70 $entry->setLanguage($content['language']);
70 $entry->setMimetype($content['content_type']); 71 $entry->setMimetype($content['content_type']);
71 $entry->setReadingTime(Utils::getReadingTime($html)); 72 $entry->setReadingTime(Utils::getReadingTime($html));
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
new file mode 100644
index 00000000..c5298236
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
@@ -0,0 +1,233 @@
1<?php
2
3namespace Wallabag\CoreBundle\Helper;
4
5use Psr\Log\LoggerInterface;
6use Symfony\Component\DomCrawler\Crawler;
7use GuzzleHttp\Client;
8use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser;
9use Symfony\Component\Finder\Finder;
10
11class DownloadImages
12{
13 const REGENERATE_PICTURES_QUALITY = 80;
14
15 private $client;
16 private $baseFolder;
17 private $logger;
18 private $mimeGuesser;
19 private $wallabagUrl;
20
21 public function __construct(Client $client, $baseFolder, $wallabagUrl, LoggerInterface $logger)
22 {
23 $this->client = $client;
24 $this->baseFolder = $baseFolder;
25 $this->wallabagUrl = rtrim($wallabagUrl, '/');
26 $this->logger = $logger;
27 $this->mimeGuesser = new MimeTypeExtensionGuesser();
28
29 $this->setFolder();
30 }
31
32 /**
33 * Setup base folder where all images are going to be saved.
34 */
35 private function setFolder()
36 {
37 // if folder doesn't exist, attempt to create one and store the folder name in property $folder
38 if (!file_exists($this->baseFolder)) {
39 mkdir($this->baseFolder, 0777, true);
40 }
41 }
42
43 /**
44 * Process the html and extract image from it, save them to local and return the updated html.
45 *
46 * @param int $entryId ID of the entry
47 * @param string $html
48 * @param string $url Used as a base path for relative image and folder
49 *
50 * @return string
51 */
52 public function processHtml($entryId, $html, $url)
53 {
54 $crawler = new Crawler($html);
55 $result = $crawler
56 ->filterXpath('//img')
57 ->extract(array('src'));
58
59 $relativePath = $this->getRelativePath($entryId);
60
61 // download and save the image to the folder
62 foreach ($result as $image) {
63 $imagePath = $this->processSingleImage($entryId, $image, $url, $relativePath);
64
65 if (false === $imagePath) {
66 continue;
67 }
68
69 $html = str_replace($image, $imagePath, $html);
70 }
71
72 return $html;
73 }
74
75 /**
76 * Process a single image:
77 * - retrieve it
78 * - re-saved it (for security reason)
79 * - return the new local path.
80 *
81 * @param int $entryId ID of the entry
82 * @param string $imagePath Path to the image to retrieve
83 * @param string $url Url from where the image were found
84 * @param string $relativePath Relative local path to saved the image
85 *
86 * @return string Relative url to access the image from the web
87 */
88 public function processSingleImage($entryId, $imagePath, $url, $relativePath = null)
89 {
90 if (null === $relativePath) {
91 $relativePath = $this->getRelativePath($entryId);
92 }
93
94 $this->logger->debug('DownloadImages: working on image: '.$imagePath);
95
96 $folderPath = $this->baseFolder.'/'.$relativePath;
97
98 // build image path
99 $absolutePath = $this->getAbsoluteLink($url, $imagePath);
100 if (false === $absolutePath) {
101 $this->logger->error('DownloadImages: Can not determine the absolute path for that image, skipping.');
102
103 return false;
104 }
105
106 try {
107 $res = $this->client->get($absolutePath);
108 } catch (\Exception $e) {
109 $this->logger->error('DownloadImages: Can not retrieve image, skipping.', ['exception' => $e]);
110
111 return false;
112 }
113
114 $ext = $this->mimeGuesser->guess($res->getHeader('content-type'));
115 $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]);
116 if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
117 $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping '.$imagePath);
118
119 return false;
120 }
121 $hashImage = hash('crc32', $absolutePath);
122 $localPath = $folderPath.'/'.$hashImage.'.'.$ext;
123
124 try {
125 $im = imagecreatefromstring($res->getBody());
126 } catch (\Exception $e) {
127 $im = false;
128 }
129
130 if (false === $im) {
131 $this->logger->error('DownloadImages: Error while regenerating image', ['path' => $localPath]);
132
133 return false;
134 }
135
136 switch ($ext) {
137 case 'gif':
138 $result = imagegif($im, $localPath);
139 $this->logger->debug('DownloadImages: Re-creating gif');
140 break;
141 case 'jpeg':
142 case 'jpg':
143 $result = imagejpeg($im, $localPath, self::REGENERATE_PICTURES_QUALITY);
144 $this->logger->debug('DownloadImages: Re-creating jpg');
145 break;
146 case 'png':
147 $result = imagepng($im, $localPath, ceil(self::REGENERATE_PICTURES_QUALITY / 100 * 9));
148 $this->logger->debug('DownloadImages: Re-creating png');
149 }
150
151 imagedestroy($im);
152
153 return $this->wallabagUrl.'/assets/images/'.$relativePath.'/'.$hashImage.'.'.$ext;
154 }
155
156 /**
157 * Remove all images for the given entry id.
158 *
159 * @param int $entryId ID of the entry
160 */
161 public function removeImages($entryId)
162 {
163 $relativePath = $this->getRelativePath($entryId);
164 $folderPath = $this->baseFolder.'/'.$relativePath;
165
166 $finder = new Finder();
167 $finder
168 ->files()
169 ->ignoreDotFiles(true)
170 ->in($folderPath);
171
172 foreach ($finder as $file) {
173 @unlink($file->getRealPath());
174 }
175
176 @rmdir($folderPath);
177 }
178
179 /**
180 * Generate the folder where we are going to save images based on the entry url.
181 *
182 * @param int $entryId ID of the entry
183 *
184 * @return string
185 */
186 private function getRelativePath($entryId)
187 {
188 $hashId = hash('crc32', $entryId);
189 $relativePath = $hashId[0].'/'.$hashId[1].'/'.$hashId;
190 $folderPath = $this->baseFolder.'/'.$relativePath;
191
192 if (!file_exists($folderPath)) {
193 mkdir($folderPath, 0777, true);
194 }
195
196 $this->logger->debug('DownloadImages: Folder used for that Entry id', ['folder' => $folderPath, 'entryId' => $entryId]);
197
198 return $relativePath;
199 }
200
201 /**
202 * Make an $url absolute based on the $base.
203 *
204 * @see Graby->makeAbsoluteStr
205 *
206 * @param string $base Base url
207 * @param string $url Url to make it absolute
208 *
209 * @return false|string
210 */
211 private function getAbsoluteLink($base, $url)
212 {
213 if (preg_match('!^https?://!i', $url)) {
214 // already absolute
215 return $url;
216 }
217
218 $base = new \SimplePie_IRI($base);
219
220 // remove '//' in URL path (causes URLs not to resolve properly)
221 if (isset($base->ipath)) {
222 $base->ipath = preg_replace('!//+!', '/', $base->ipath);
223 }
224
225 if ($absolute = \SimplePie_IRI::absolutize($base, $url)) {
226 return $absolute->get_uri();
227 }
228
229 $this->logger->error('DownloadImages: Can not make an absolute link', ['base' => $base, 'url' => $url]);
230
231 return false;
232 }
233}
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index cd2b47b9..14616d88 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -329,4 +329,18 @@ class EntryRepository extends EntityRepository
329 329
330 return $qb->getQuery()->getSingleScalarResult(); 330 return $qb->getQuery()->getSingleScalarResult();
331 } 331 }
332
333 /**
334 * Remove all entries for a user id.
335 * Used when a user want to reset all informations.
336 *
337 * @param int $userId
338 */
339 public function removeAllByUserId($userId)
340 {
341 $this->getEntityManager()
342 ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = :userId')
343 ->setParameter('userId', $userId)
344 ->execute();
345 }
332} 346}
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php
index e76878d4..81445989 100644
--- a/src/Wallabag/CoreBundle/Repository/TagRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php
@@ -34,6 +34,9 @@ class TagRepository extends EntityRepository
34 34
35 /** 35 /**
36 * Find all tags per user. 36 * Find all tags per user.
37 * Instead of just left joined on the Entry table, we select only id and group by id to avoid tag multiplication in results.
38 * Once we have all tags id, we can safely request them one by one.
39 * This'll still be fastest than the previous query.
37 * 40 *
38 * @param int $userId 41 * @param int $userId
39 * 42 *
@@ -41,15 +44,20 @@ class TagRepository extends EntityRepository
41 */ 44 */
42 public function findAllTags($userId) 45 public function findAllTags($userId)
43 { 46 {
44 return $this->createQueryBuilder('t') 47 $ids = $this->createQueryBuilder('t')
45 ->select('t.slug', 't.label', 't.id') 48 ->select('t.id')
46 ->leftJoin('t.entries', 'e') 49 ->leftJoin('t.entries', 'e')
47 ->where('e.user = :userId')->setParameter('userId', $userId) 50 ->where('e.user = :userId')->setParameter('userId', $userId)
48 ->groupBy('t.slug') 51 ->groupBy('t.id')
49 ->addGroupBy('t.label')
50 ->addGroupBy('t.id')
51 ->getQuery() 52 ->getQuery()
52 ->getArrayResult(); 53 ->getArrayResult();
54
55 $tags = [];
56 foreach ($ids as $id) {
57 $tags[] = $this->find($id);
58 }
59
60 return $tags;
53 } 61 }
54 62
55 /** 63 /**
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 90a2419e..9786ac27 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -30,7 +30,7 @@ services:
30 - "@doctrine" 30 - "@doctrine"
31 31
32 wallabag_core.subscriber.table_prefix: 32 wallabag_core.subscriber.table_prefix:
33 class: Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber 33 class: Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber
34 arguments: 34 arguments:
35 - "%database_table_prefix%" 35 - "%database_table_prefix%"
36 tags: 36 tags:
@@ -130,3 +130,31 @@ services:
130 arguments: 130 arguments:
131 - '@twig' 131 - '@twig'
132 - '%kernel.debug%' 132 - '%kernel.debug%'
133
134 wallabag_core.subscriber.sqlite_cascade_delete:
135 class: Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber
136 arguments:
137 - "@doctrine"
138 tags:
139 - { name: doctrine.event_subscriber }
140
141 wallabag_core.subscriber.download_images:
142 class: Wallabag\CoreBundle\Event\Subscriber\DownloadImagesSubscriber
143 arguments:
144 - "@doctrine.orm.default_entity_manager"
145 - "@wallabag_core.entry.download_images"
146 - '@=service(''craue_config'').get(''download_images_enabled'')'
147 - "@logger"
148 tags:
149 - { name: kernel.event_subscriber }
150
151 wallabag_core.entry.download_images:
152 class: Wallabag\CoreBundle\Helper\DownloadImages
153 arguments:
154 - "@wallabag_core.entry.download_images.client"
155 - "%kernel.root_dir%/../web/assets/images"
156 - '@=service(''craue_config'').get(''wallabag_url'')'
157 - "@logger"
158
159 wallabag_core.entry.download_images.client:
160 class: GuzzleHttp\Client
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 6ca7e459..aeae6bcf 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -71,6 +71,7 @@ config:
71 # 300_word: 'I read ~300 words per minute' 71 # 300_word: 'I read ~300 words per minute'
72 # 400_word: 'I read ~400 words per minute' 72 # 400_word: 'I read ~400 words per minute'
73 pocket_consumer_key_label: Brugers nøgle til Pocket for at importere materialer 73 pocket_consumer_key_label: Brugers nøgle til Pocket for at importere materialer
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'RSS-feeds fra wallabag gør det muligt at læse de artikler, der gemmes i wallabag, med din RSS-læser. Det kræver, at du genererer et token først.' 76 description: 'RSS-feeds fra wallabag gør det muligt at læse de artikler, der gemmes i wallabag, med din RSS-læser. Det kræver, at du genererer et token først.'
76 token_label: 'RSS-Token' 77 token_label: 'RSS-Token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Navn' 89 name_label: 'Navn'
89 email_label: 'Emailadresse' 90 email_label: 'Emailadresse'
90 # twoFactorAuthentication_label: 'Two factor authentication' 91 # twoFactorAuthentication_label: 'Two factor authentication'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Gammel adgangskode' 105 old_password_label: 'Gammel adgangskode'
93 new_password_label: 'Ny adgangskode' 106 new_password_label: 'Ny adgangskode'
@@ -355,6 +368,7 @@ import:
355 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
356 worker: 369 worker:
357 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 # firefox: 372 # firefox:
359 # page_title: 'Import > Firefox' 373 # page_title: 'Import > Firefox'
360 # 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 # 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."
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'RSS-oplysninger opdateret' 472 rss_updated: 'RSS-oplysninger opdateret'
459 # tagging_rules_updated: 'Tagging rules updated' 473 # tagging_rules_updated: 'Tagging rules updated'
460 # tagging_rules_deleted: 'Tagging rule deleted' 474 # tagging_rules_deleted: 'Tagging rule deleted'
461 # user_added: 'User "%username%" added'
462 # rss_token_updated: 'RSS token updated' 475 # rss_token_updated: 'RSS token updated'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 # entry_already_saved: 'Entry already saved on %date%' 481 # entry_already_saved: 'Entry already saved on %date%'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 # client_created: 'New client created.' 506 # client_created: 'New client created.'
491 # client_deleted: 'Client deleted' 507 # client_deleted: 'Client deleted'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # 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 8fd1d82a..2105d02d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'Ich lese ~300 Wörter pro Minute' 71 300_word: 'Ich lese ~300 Wörter pro Minute'
72 400_word: 'Ich lese ~400 Wörter pro Minute' 72 400_word: 'Ich lese ~400 Wörter pro Minute'
73 pocket_consumer_key_label: Consumer-Key für Pocket, um Inhalte zu importieren 73 pocket_consumer_key_label: Consumer-Key für Pocket, um Inhalte zu importieren
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'Die RSS-Feeds von wallabag erlauben es dir, deine gespeicherten Artikel mit deinem bevorzugten RSS-Reader zu lesen. Vorher musst du jedoch einen Token erstellen.' 76 description: 'Die RSS-Feeds von wallabag erlauben es dir, deine gespeicherten Artikel mit deinem bevorzugten RSS-Reader zu lesen. Vorher musst du jedoch einen Token erstellen.'
76 token_label: 'RSS-Token' 77 token_label: 'RSS-Token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Name' 89 name_label: 'Name'
89 email_label: 'E-Mail-Adresse' 90 email_label: 'E-Mail-Adresse'
90 twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' 91 twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Altes Kennwort' 105 old_password_label: 'Altes Kennwort'
93 new_password_label: 'Neues Kennwort' 106 new_password_label: 'Neues Kennwort'
@@ -355,6 +368,7 @@ import:
355 how_to: 'Bitte wähle deinen Readability Export aus und klicke den unteren Button für das Hochladen und Importieren dessen.' 368 how_to: 'Bitte wähle deinen Readability Export aus und klicke den unteren Button für das Hochladen und Importieren dessen.'
356 worker: 369 worker:
357 enabled: "Der Import erfolgt asynchron. Sobald der Import gestartet ist, wird diese Aufgabe extern abgearbeitet. Der aktuelle Service dafür ist:" 370 enabled: "Der Import erfolgt asynchron. Sobald der Import gestartet ist, wird diese Aufgabe extern abgearbeitet. Der aktuelle Service dafür ist:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Aus Firefox importieren' 373 page_title: 'Aus Firefox importieren'
360 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 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."
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'RSS-Informationen aktualisiert' 472 rss_updated: 'RSS-Informationen aktualisiert'
459 tagging_rules_updated: 'Tagging-Regeln aktualisiert' 473 tagging_rules_updated: 'Tagging-Regeln aktualisiert'
460 tagging_rules_deleted: 'Tagging-Regel gelöscht' 474 tagging_rules_deleted: 'Tagging-Regel gelöscht'
461 user_added: 'Benutzer "%username%" erstellt'
462 rss_token_updated: 'RSS-Token aktualisiert' 475 rss_token_updated: 'RSS-Token aktualisiert'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: 'Eintrag bereits am %date% gespeichert' 481 entry_already_saved: 'Eintrag bereits am %date% gespeichert'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: 'Neuer Client erstellt.' 506 client_created: 'Neuer Client erstellt.'
491 client_deleted: 'Client gelöscht' 507 client_deleted: 'Client gelöscht'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # deleted: 'User "%username%" deleted'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 02f56535..2bb95728 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'I read ~300 words per minute' 71 300_word: 'I read ~300 words per minute'
72 400_word: 'I read ~400 words per minute' 72 400_word: 'I read ~400 words per minute'
73 pocket_consumer_key_label: Consumer key for Pocket to import contents 73 pocket_consumer_key_label: Consumer key for Pocket to import contents
74 android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader. You need to generate a token first.' 76 description: 'RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader. You need to generate a token first.'
76 token_label: 'RSS token' 77 token_label: 'RSS token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Name' 89 name_label: 'Name'
89 email_label: 'Email' 90 email_label: 'Email'
90 twoFactorAuthentication_label: 'Two factor authentication' 91 twoFactorAuthentication_label: 'Two factor authentication'
92 delete:
93 title: Delete my account (a.k.a danger zone)
94 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.
95 confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 button: Delete my account
97 reset:
98 title: Reset area (a.k.a danger zone)
99 description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 annotations: Remove ALL annotations
101 tags: Remove ALL tags
102 entries: Remove ALL entries
103 confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Current password' 105 old_password_label: 'Current password'
93 new_password_label: 'New password' 106 new_password_label: 'New password'
@@ -355,6 +368,7 @@ import:
355 how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 how_to: 'Please select your Readability export and click on the below button to upload and import it.'
356 worker: 369 worker:
357 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:" 370 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:"
371 download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Import > Firefox' 373 page_title: 'Import > Firefox'
360 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 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."
@@ -459,6 +473,9 @@ flashes:
459 tagging_rules_updated: 'Tagging rules updated' 473 tagging_rules_updated: 'Tagging rules updated'
460 tagging_rules_deleted: 'Tagging rule deleted' 474 tagging_rules_deleted: 'Tagging rule deleted'
461 rss_token_updated: 'RSS token updated' 475 rss_token_updated: 'RSS token updated'
476 annotations_reset: Annotations reset
477 tags_reset: Tags reset
478 entries_reset: Entries reset
462 entry: 479 entry:
463 notice: 480 notice:
464 entry_already_saved: 'Entry already saved on %date%' 481 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 42ec8183..ca3db487 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'Leo ~300 palabras por minuto' 71 300_word: 'Leo ~300 palabras por minuto'
72 400_word: 'Leo ~400 palabras por minuto' 72 400_word: 'Leo ~400 palabras por minuto'
73 # pocket_consumer_key_label: Consumer key for Pocket to import contents 73 # pocket_consumer_key_label: Consumer key for Pocket to import contents
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'Los feeds RSS de wallabag permiten leer los artículos guardados con su lector RSS favorito. Necesita generar un token primero' 76 description: 'Los feeds RSS de wallabag permiten leer los artículos guardados con su lector RSS favorito. Necesita generar un token primero'
76 token_label: 'RSS token' 77 token_label: 'RSS token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Nombre' 89 name_label: 'Nombre'
89 email_label: 'Direccion e-mail' 90 email_label: 'Direccion e-mail'
90 twoFactorAuthentication_label: 'Autentificación de dos factores' 91 twoFactorAuthentication_label: 'Autentificación de dos factores'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Contraseña actual' 105 old_password_label: 'Contraseña actual'
93 new_password_label: 'Nueva contraseña' 106 new_password_label: 'Nueva contraseña'
@@ -355,6 +368,7 @@ import:
355 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
356 worker: 369 worker:
357 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Importar > Firefox' 373 page_title: 'Importar > Firefox'
360 # 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 # 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."
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'La configuración de los feeds RSS ha sido actualizada' 472 rss_updated: 'La configuración de los feeds RSS ha sido actualizada'
459 tagging_rules_updated: 'Regla de etiquetado borrada' 473 tagging_rules_updated: 'Regla de etiquetado borrada'
460 tagging_rules_deleted: 'Regla de etiquetado actualizada' 474 tagging_rules_deleted: 'Regla de etiquetado actualizada'
461 user_added: 'Usuario "%username%" añadido'
462 rss_token_updated: 'RSS token actualizado' 475 rss_token_updated: 'RSS token actualizado'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: 'Entrada ya guardada por %fecha%' 481 entry_already_saved: 'Entrada ya guardada por %fecha%'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: 'Nuevo cliente creado.' 506 client_created: 'Nuevo cliente creado.'
491 client_deleted: 'Cliente suprimido' 507 client_deleted: 'Cliente suprimido'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # 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 f82167df..1914215a 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'من تقریباً ۳۰۰ واژه را در دقیقه می‌خوانم' 71 300_word: 'من تقریباً ۳۰۰ واژه را در دقیقه می‌خوانم'
72 400_word: 'من تقریباً ۴۰۰ واژه را در دقیقه می‌خوانم' 72 400_word: 'من تقریباً ۴۰۰ واژه را در دقیقه می‌خوانم'
73 pocket_consumer_key_label: کلید کاربری Pocket برای درون‌ریزی مطالب 73 pocket_consumer_key_label: کلید کاربری Pocket برای درون‌ریزی مطالب
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'با خوراک آر-اس-اس که wallabag در اختیارتان می‌گذارد، می‌توانید مقاله‌های ذخیره‌شده را در نرم‌افزار آر-اس-اس دلخواه خود بخوانید. برای این کار نخست باید یک کد بسازید.' 76 description: 'با خوراک آر-اس-اس که wallabag در اختیارتان می‌گذارد، می‌توانید مقاله‌های ذخیره‌شده را در نرم‌افزار آر-اس-اس دلخواه خود بخوانید. برای این کار نخست باید یک کد بسازید.'
76 token_label: 'کد آر-اس-اس' 77 token_label: 'کد آر-اس-اس'
@@ -88,6 +89,18 @@ config:
88 name_label: 'نام' 89 name_label: 'نام'
89 email_label: 'نشانی ایمیل' 90 email_label: 'نشانی ایمیل'
90 twoFactorAuthentication_label: 'تأیید ۲مرحله‌ای' 91 twoFactorAuthentication_label: 'تأیید ۲مرحله‌ای'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'رمز قدیمی' 105 old_password_label: 'رمز قدیمی'
93 new_password_label: 'رمز تازه' 106 new_password_label: 'رمز تازه'
@@ -272,6 +285,7 @@ quickstart:
272 paragraph_2: 'ادامه دهید!' 285 paragraph_2: 'ادامه دهید!'
273 configure: 286 configure:
274 title: 'برنامه را تنظیم کنید' 287 title: 'برنامه را تنظیم کنید'
288 # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.'
275 language: 'زبان و نمای برنامه را تغییر دهید' 289 language: 'زبان و نمای برنامه را تغییر دهید'
276 rss: 'خوراک آر-اس-اس را فعال کنید' 290 rss: 'خوراک آر-اس-اس را فعال کنید'
277 tagging_rules: 'قانون‌های برچسب‌گذاری خودکار مقاله‌هایتان را تعریف کنید' 291 tagging_rules: 'قانون‌های برچسب‌گذاری خودکار مقاله‌هایتان را تعریف کنید'
@@ -354,6 +368,7 @@ import:
354 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
355 worker: 369 worker:
356 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
357 firefox: 372 firefox:
358 page_title: 'درون‌ریزی > Firefox' 373 page_title: 'درون‌ریزی > Firefox'
359 # 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 # 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."
@@ -457,8 +472,10 @@ flashes:
457 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد' 472 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد'
458 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد' 473 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد'
459 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد' 474 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد'
460 user_added: 'کابر "%username%" افزوده شد'
461 rss_token_updated: 'کد آر-اس-اس به‌روز شد' 475 rss_token_updated: 'کد آر-اس-اس به‌روز شد'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
462 entry: 479 entry:
463 notice: 480 notice:
464 entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' 481 entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
@@ -488,3 +505,8 @@ flashes:
488 notice: 505 notice:
489 # client_created: 'New client created.' 506 # client_created: 'New client created.'
490 # client_deleted: 'Client deleted' 507 # client_deleted: 'Client deleted'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # 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 421cb8b5..60fa9a39 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -71,6 +71,7 @@ config:
71 300_word: "Je lis environ 300 mots par minute" 71 300_word: "Je lis environ 300 mots par minute"
72 400_word: "Je lis environ 400 mots par minute" 72 400_word: "Je lis environ 400 mots par minute"
73 pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données 73 pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données
74 android_configuration: Configurez votre application Android
74 form_rss: 75 form_rss:
75 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton." 76 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton."
76 token_label: "Jeton RSS" 77 token_label: "Jeton RSS"
@@ -88,6 +89,18 @@ config:
88 name_label: "Nom" 89 name_label: "Nom"
89 email_label: "Adresse courriel" 90 email_label: "Adresse courriel"
90 twoFactorAuthentication_label: "Double authentification" 91 twoFactorAuthentication_label: "Double authentification"
92 delete:
93 title: Supprimer mon compte (attention danger !)
94 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é.
95 confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE)
96 button: 'Supprimer mon compte'
97 reset:
98 title: Réinitialisation (attention danger !)
99 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 !
100 annotations: Supprimer TOUTES les annotations
101 tags: Supprimer TOUS les tags
102 entries: Supprimer TOUS les articles
103 confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE)
91 form_password: 104 form_password:
92 old_password_label: "Mot de passe actuel" 105 old_password_label: "Mot de passe actuel"
93 new_password_label: "Nouveau mot de passe" 106 new_password_label: "Nouveau mot de passe"
@@ -355,6 +368,7 @@ import:
355 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." 368 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer."
356 worker: 369 worker:
357 enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" 370 enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :"
371 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 <strong>vivement</strong> d'activer les imports asynchrones."
358 firefox: 372 firefox:
359 page_title: "Import > Firefox" 373 page_title: "Import > Firefox"
360 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. </p>" 374 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. </p>"
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: "La configuration des flux RSS a bien été mise à jour" 472 rss_updated: "La configuration des flux RSS a bien été mise à jour"
459 tagging_rules_updated: "Règles mises à jour" 473 tagging_rules_updated: "Règles mises à jour"
460 tagging_rules_deleted: "Règle supprimée" 474 tagging_rules_deleted: "Règle supprimée"
461 user_added: "Utilisateur \"%username%\" ajouté"
462 rss_token_updated: "Jeton RSS mis à jour" 475 rss_token_updated: "Jeton RSS mis à jour"
476 annotations_reset: Annotations supprimées
477 tags_reset: Tags supprimés
478 entries_reset: Articles supprimés
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: "Article déjà sauvergardé le %date%" 481 entry_already_saved: "Article déjà sauvergardé le %date%"
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: "Nouveau client %name% créé" 506 client_created: "Nouveau client %name% créé"
491 client_deleted: "Client %name% supprimé" 507 client_deleted: "Client %name% supprimé"
508 user:
509 notice:
510 added: 'Utilisateur "%username%" ajouté'
511 updated: 'Utilisateur "%username%" mis à jour'
512 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 d679ef00..7f401684 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'Leggo ~300 parole al minuto' 71 300_word: 'Leggo ~300 parole al minuto'
72 400_word: 'Leggo ~400 parole al minuto' 72 400_word: 'Leggo ~400 parole al minuto'
73 pocket_consumer_key_label: Consumer key per Pocket per importare i contenuti 73 pocket_consumer_key_label: Consumer key per Pocket per importare i contenuti
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'I feed RSS generati da wallabag ti permettono di leggere i tuoi contenuti salvati con il tuo lettore di RSS preferito. Prima, devi generare un token.' 76 description: 'I feed RSS generati da wallabag ti permettono di leggere i tuoi contenuti salvati con il tuo lettore di RSS preferito. Prima, devi generare un token.'
76 token_label: 'RSS token' 77 token_label: 'RSS token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Nome' 89 name_label: 'Nome'
89 email_label: 'E-mail' 90 email_label: 'E-mail'
90 twoFactorAuthentication_label: 'Two factor authentication' 91 twoFactorAuthentication_label: 'Two factor authentication'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Password corrente' 105 old_password_label: 'Password corrente'
93 new_password_label: 'Nuova password' 106 new_password_label: 'Nuova password'
@@ -355,6 +368,7 @@ import:
355 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
356 worker: 369 worker:
357 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Importa da > Firefox' 373 page_title: 'Importa da > Firefox'
360 # 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 # 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."
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'Informazioni RSS aggiornate' 472 rss_updated: 'Informazioni RSS aggiornate'
459 tagging_rules_updated: 'Regole di tagging aggiornate' 473 tagging_rules_updated: 'Regole di tagging aggiornate'
460 tagging_rules_deleted: 'Regola di tagging aggiornate' 474 tagging_rules_deleted: 'Regola di tagging aggiornate'
461 user_added: 'Utente "%username%" aggiunto'
462 rss_token_updated: 'RSS token aggiornato' 475 rss_token_updated: 'RSS token aggiornato'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: 'Contenuto già salvato in data %date%' 481 entry_already_saved: 'Contenuto già salvato in data %date%'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: 'Nuovo client creato.' 506 client_created: 'Nuovo client creato.'
491 client_deleted: 'Client eliminato' 507 client_deleted: 'Client eliminato'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # 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 af0fba0d..c3282b0e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -25,13 +25,13 @@ menu:
25 internal_settings: 'Configuracion interna' 25 internal_settings: 'Configuracion interna'
26 import: 'Importar' 26 import: 'Importar'
27 howto: 'Ajuda' 27 howto: 'Ajuda'
28 developer: 'Desvolopador' 28 developer: 'Desvolopaire'
29 logout: 'Desconnexion' 29 logout: 'Desconnexion'
30 about: 'A prepaus' 30 about: 'A prepaus'
31 search: 'Cercar' 31 search: 'Cercar'
32 save_link: 'Enregistrar un novèl article' 32 save_link: 'Enregistrar un novèl article'
33 back_to_unread: 'Tornar als articles pas legits' 33 back_to_unread: 'Tornar als articles pas legits'
34 # users_management: 'Users management' 34 users_management: 'Gestion dels utilizaires'
35 top: 35 top:
36 add_new_entry: 'Enregistrar un novèl article' 36 add_new_entry: 'Enregistrar un novèl article'
37 search: 'Cercar' 37 search: 'Cercar'
@@ -46,7 +46,7 @@ footer:
46 social: 'Social' 46 social: 'Social'
47 powered_by: 'propulsat per' 47 powered_by: 'propulsat per'
48 about: 'A prepaus' 48 about: 'A prepaus'
49 # stats: Since %user_creation% you read %nb_archives% articles. That is about %per_day% a day! 49 stats: "Dempuèi %user_creation% avètz legit %nb_archives% articles. Es a l'entorn de %per_day% per jorn !"
50 50
51config: 51config:
52 page_title: 'Configuracion' 52 page_title: 'Configuracion'
@@ -71,6 +71,7 @@ config:
71 300_word: "Legissi a l'entorn de 300 mots per minuta" 71 300_word: "Legissi a l'entorn de 300 mots per minuta"
72 400_word: "Legissi a l'entorn de 400 mots per minuta" 72 400_word: "Legissi a l'entorn de 400 mots per minuta"
73 pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas 73 pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: "Los fluxes RSS fornits per wallabag vos permeton de legir vòstres articles salvagardats dins vòstre lector de fluxes preferit. Per los poder emplegar, vos cal, d'en primièr crear un geton." 76 description: "Los fluxes RSS fornits per wallabag vos permeton de legir vòstres articles salvagardats dins vòstre lector de fluxes preferit. Per los poder emplegar, vos cal, d'en primièr crear un geton."
76 token_label: 'Geton RSS' 77 token_label: 'Geton RSS'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Nom' 89 name_label: 'Nom'
89 email_label: 'Adreça de corrièl' 90 email_label: 'Adreça de corrièl'
90 twoFactorAuthentication_label: 'Dobla autentificacion' 91 twoFactorAuthentication_label: 'Dobla autentificacion'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Senhal actual' 105 old_password_label: 'Senhal actual'
93 new_password_label: 'Senhal novèl' 106 new_password_label: 'Senhal novèl'
@@ -96,7 +109,7 @@ config:
96 if_label: 'se' 109 if_label: 'se'
97 then_tag_as_label: 'alara atribuir las etiquetas' 110 then_tag_as_label: 'alara atribuir las etiquetas'
98 delete_rule_label: 'suprimir' 111 delete_rule_label: 'suprimir'
99 # edit_rule_label: 'edit' 112 edit_rule_label: 'modificar'
100 rule_label: 'Règla' 113 rule_label: 'Règla'
101 tags_label: 'Etiquetas' 114 tags_label: 'Etiquetas'
102 faq: 115 faq:
@@ -209,7 +222,7 @@ entry:
209 is_public_label: 'Public' 222 is_public_label: 'Public'
210 save_label: 'Enregistrar' 223 save_label: 'Enregistrar'
211 public: 224 public:
212 # shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>" 225 shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>"
213 226
214about: 227about:
215 page_title: 'A prepaus' 228 page_title: 'A prepaus'
@@ -265,14 +278,14 @@ howto:
265 278
266quickstart: 279quickstart:
267 page_title: 'Per ben començar' 280 page_title: 'Per ben començar'
268 # more: 'More…' 281 more: 'Mai…'
269 intro: 282 intro:
270 title: 'Benvenguda sus wallabag !' 283 title: 'Benvenguda sus wallabag !'
271 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." 284 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."
272 paragraph_2: 'Seguètz-nos ' 285 paragraph_2: 'Seguètz-nos '
273 configure: 286 configure:
274 title: "Configuratz l'aplicacio" 287 title: "Configuratz l'aplicacion"
275 # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.' 288 description: "Per fin d'aver una aplicacion que vos va ben, anatz veire la configuracion de wallabag."
276 language: "Cambiatz la lenga e l'estil de l'aplicacion" 289 language: "Cambiatz la lenga e l'estil de l'aplicacion"
277 rss: 'Activatz los fluxes RSS' 290 rss: 'Activatz los fluxes RSS'
278 tagging_rules: 'Escrivètz de règlas per classar automaticament vòstres articles' 291 tagging_rules: 'Escrivètz de règlas per classar automaticament vòstres articles'
@@ -286,7 +299,7 @@ quickstart:
286 import: 'Configurar los impòrt' 299 import: 'Configurar los impòrt'
287 first_steps: 300 first_steps:
288 title: 'Primièrs passes' 301 title: 'Primièrs passes'
289 # 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." 302 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."
290 new_article: 'Ajustatz vòstre primièr article' 303 new_article: 'Ajustatz vòstre primièr article'
291 unread_articles: 'E racaptatz-lo !' 304 unread_articles: 'E racaptatz-lo !'
292 migrate: 305 migrate:
@@ -298,14 +311,14 @@ quickstart:
298 readability: 'Migrar dempuèi Readability' 311 readability: 'Migrar dempuèi Readability'
299 instapaper: 'Migrar dempuèi Instapaper' 312 instapaper: 'Migrar dempuèi Instapaper'
300 developer: 313 developer:
301 title: 'Pels desvolopadors' 314 title: 'Pels desvolopaires'
302 # description: 'We also thought to the developers: Docker, API, translations, etc.' 315 description: 'Avèm tanben pensat als desvolopaires : Docker, API, traduccions, etc.'
303 create_application: 'Crear vòstra aplicacion tèrça' 316 create_application: 'Crear vòstra aplicacion tèrça'
304 # use_docker: 'Use Docker to install wallabag' 317 use_docker: 'Utilizar Docker per installar wallabag'
305 docs: 318 docs:
306 title: 'Documentacion complèta' 319 title: 'Documentacion complèta'
307 # 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." 320 description: "I a un fum de fonccionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar."
308 annotate: 'Anotatar vòstre article' 321 annotate: 'Anotar vòstre article'
309 export: 'Convertissètz vòstres articles en ePub o en PDF' 322 export: 'Convertissètz vòstres articles en ePub o en PDF'
310 search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa" 323 search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa"
311 fetching_errors: "Qué far se mon article es pas recuperat coma cal ?" 324 fetching_errors: "Qué far se mon article es pas recuperat coma cal ?"
@@ -355,6 +368,7 @@ import:
355 how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar." 368 how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar."
356 worker: 369 worker:
357 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 : " 370 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 : "
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Importar > Firefox' 373 page_title: 'Importar > Firefox'
360 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 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."
@@ -390,7 +404,7 @@ developer:
390 warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag." 404 warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag."
391 action: 'Suprimir aqueste client' 405 action: 'Suprimir aqueste client'
392 client: 406 client:
393 page_title: 'Desvlopador > Novèl client' 407 page_title: 'Desvolopaire > Novèl client'
394 page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion." 408 page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion."
395 form: 409 form:
396 name_label: "Nom del client" 410 name_label: "Nom del client"
@@ -398,7 +412,7 @@ developer:
398 save_label: 'Crear un novèl client' 412 save_label: 'Crear un novèl client'
399 action_back: 'Retorn' 413 action_back: 'Retorn'
400 client_parameter: 414 client_parameter:
401 page_title: 'Desvolopador > Los paramètres de vòstre client' 415 page_title: 'Desvolopaire > Los paramètres de vòstre client'
402 page_description: 'Vaquí los paramètres de vòstre client' 416 page_description: 'Vaquí los paramètres de vòstre client'
403 field_name: 'Nom del client' 417 field_name: 'Nom del client'
404 field_id: 'ID Client' 418 field_id: 'ID Client'
@@ -406,7 +420,7 @@ developer:
406 back: 'Retour' 420 back: 'Retour'
407 read_howto: 'Legir "cossí crear ma primièra aplicacion"' 421 read_howto: 'Legir "cossí crear ma primièra aplicacion"'
408 howto: 422 howto:
409 page_title: 'Desvolopador > Cossí crear ma primièra aplicacion' 423 page_title: 'Desvolopaire > Cossí crear ma primièra aplicacion'
410 description: 424 description:
411 paragraph_1: "Las comandas seguentas utilizan la <a href=\"https://github.com/jkbrzt/httpie\">bibliotèca HTTPie</a>. Asseguratz-vos que siasqueòu installadas abans de l'utilizar." 425 paragraph_1: "Las comandas seguentas utilizan la <a href=\"https://github.com/jkbrzt/httpie\">bibliotèca HTTPie</a>. Asseguratz-vos que siasqueòu installadas abans de l'utilizar."
412 paragraph_2: "Vos cal un geton per escambiar entre vòstra aplicacion e l'API de wallabar." 426 paragraph_2: "Vos cal un geton per escambiar entre vòstra aplicacion e l'API de wallabar."
@@ -419,31 +433,31 @@ developer:
419 back: 'Retorn' 433 back: 'Retorn'
420 434
421user: 435user:
422 # page_title: Users management 436 page_title: 'Gestion dels utilizaires'
423 # new_user: Create a new user 437 new_user: 'Crear un novèl utilizaire'
424 # edit_user: Edit an existing user 438 edit_user: 'Modificar un utilizaire existent'
425 # description: "Here you can manage all users (create, edit and delete)" 439 description: "Aquí podètz gerir totes los utilizaires (crear, modificar e suprimir)"
426 # list: 440 list:
427 # actions: Actions 441 actions: 'Accions'
428 # edit_action: Edit 442 edit_action: 'Modificar'
429 # yes: Yes 443 yes: 'Òc'
430 # no: No 444 no: 'Non'
431 # create_new_one: Create a new user 445 create_new_one: 'Crear un novèl utilizaire'
432 form: 446 form:
433 username_label: "Nom d'utilizaire" 447 username_label: "Nom d'utilizaire"
434 # name_label: 'Name' 448 name_label: 'Nom'
435 password_label: 'Senhal' 449 password_label: 'Senhal'
436 repeat_new_password_label: 'Confirmatz vòstre novèl senhal' 450 repeat_new_password_label: 'Confirmatz vòstre novèl senhal'
437 plain_password_label: 'Senhal en clar' 451 plain_password_label: 'Senhal en clar'
438 email_label: 'Adreça de corrièl' 452 email_label: 'Adreça de corrièl'
439 # enabled_label: 'Enabled' 453 enabled_label: 'Actiu'
440 # locked_label: 'Locked' 454 locked_label: 'Varrolhat'
441 # last_login_label: 'Last login' 455 last_login_label: 'Darrièra connexion'
442 # twofactor_label: Two factor authentication 456 twofactor_label: 'Autentificacion doble-factor'
443 # save: Save 457 save: 'Enregistrar'
444 # delete: Delete 458 delete: 'Suprimir'
445 # delete_confirm: Are you sure? 459 delete_confirm: 'Sètz segur ?'
446 # back_to_list: Back to list 460 back_to_list: 'Tornar a la lista'
447 461
448error: 462error:
449 # page_title: An error occurred 463 # page_title: An error occurred
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' 472 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn'
459 tagging_rules_updated: 'Règlas misa a jorn' 473 tagging_rules_updated: 'Règlas misa a jorn'
460 tagging_rules_deleted: 'Règla suprimida' 474 tagging_rules_deleted: 'Règla suprimida'
461 user_added: 'Utilizaire "%username%" apondut'
462 rss_token_updated: 'Geton RSS mes a jorn' 475 rss_token_updated: 'Geton RSS mes a jorn'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: 'Article ja salvargardat lo %date%' 481 entry_already_saved: 'Article ja salvargardat lo %date%'
@@ -470,12 +486,12 @@ flashes:
470 entry_reloaded_failed: "L'article es estat cargat de nòu mai la recuperacion del contengut a fracassat" 486 entry_reloaded_failed: "L'article es estat cargat de nòu mai la recuperacion del contengut a fracassat"
471 entry_archived: 'Article marcat coma legit' 487 entry_archived: 'Article marcat coma legit'
472 entry_unarchived: 'Article marcat coma pas legit' 488 entry_unarchived: 'Article marcat coma pas legit'
473 entry_starred: 'Article apondut dins los favorits' 489 entry_starred: 'Article ajustat dins los favorits'
474 entry_unstarred: 'Article quitat dels favorits' 490 entry_unstarred: 'Article quitat dels favorits'
475 entry_deleted: 'Article suprimit' 491 entry_deleted: 'Article suprimit'
476 tag: 492 tag:
477 notice: 493 notice:
478 tag_added: 'Etiqueta aponduda' 494 tag_added: 'Etiqueta ajustada'
479 import: 495 import:
480 notice: 496 notice:
481 failed: "L'importacion a fracassat, mercés de tornar ensajar" 497 failed: "L'importacion a fracassat, mercés de tornar ensajar"
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: 'Novèl client creat' 506 client_created: 'Novèl client creat'
491 client_deleted: 'Client suprimit' 507 client_deleted: 'Client suprimit'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # deleted: 'User "%username%" deleted'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index bf47b58a..87731faf 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -71,6 +71,7 @@ config:
71 300_word: 'Czytam ~300 słów na minutę' 71 300_word: 'Czytam ~300 słów na minutę'
72 400_word: 'Czytam ~400 słów na minutę' 72 400_word: 'Czytam ~400 słów na minutę'
73 pocket_consumer_key_label: 'Klucz klienta Pocket do importu zawartości' 73 pocket_consumer_key_label: 'Klucz klienta Pocket do importu zawartości'
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'Kanały RSS prowadzone przez wallabag pozwalają Ci na czytanie twoich zapisanych artykułów w twoium ulubionym czytniku RSS. Musisz najpierw wynegenerować tokena.‌' 76 description: 'Kanały RSS prowadzone przez wallabag pozwalają Ci na czytanie twoich zapisanych artykułów w twoium ulubionym czytniku RSS. Musisz najpierw wynegenerować tokena.‌'
76 token_label: 'Token RSS' 77 token_label: 'Token RSS'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Nazwa' 89 name_label: 'Nazwa'
89 email_label: 'Adres email' 90 email_label: 'Adres email'
90 twoFactorAuthentication_label: 'Autoryzacja dwuetapowa' 91 twoFactorAuthentication_label: 'Autoryzacja dwuetapowa'
92 delete:
93 title: Usuń moje konto (niebezpieczna strefa !)
94 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.
95 confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć)
96 button: Usuń moje konto
97 reset:
98 title: Reset (niebezpieczna strefa)
99 description: Poniższe przyciski pozwalają usunąć pewne informacje z twojego konta. Uważaj te operacje są NIEODWRACALNE.
100 annotations: Usuń WSZYSTKIE adnotacje
101 tags: Usuń WSZYSTKIE tagi
102 entries: usuń WSZYTSTKIE wpisy
103 confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć)
91 form_password: 104 form_password:
92 old_password_label: 'Stare hasło' 105 old_password_label: 'Stare hasło'
93 new_password_label: 'Nowe hasło' 106 new_password_label: 'Nowe hasło'
@@ -355,6 +368,7 @@ import:
355 how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.' 368 how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.'
356 worker: 369 worker:
357 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:" 370 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 firefox: 372 firefox:
359 page_title: 'Import > Firefox' 373 page_title: 'Import > Firefox'
360 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 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."
@@ -446,7 +460,7 @@ user:
446 back_to_list: Powrót do listy 460 back_to_list: Powrót do listy
447 461
448error: 462error:
449 # page_title: An error occurred 463 page_title: Wystąpił błąd
450 464
451flashes: 465flashes:
452 config: 466 config:
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'Informacje RSS zaktualizowane' 472 rss_updated: 'Informacje RSS zaktualizowane'
459 tagging_rules_updated: 'Reguły tagowania zaktualizowane' 473 tagging_rules_updated: 'Reguły tagowania zaktualizowane'
460 tagging_rules_deleted: 'Reguła tagowania usunięta' 474 tagging_rules_deleted: 'Reguła tagowania usunięta'
461 user_added: 'Użytkownik "%username%" dodany'
462 rss_token_updated: 'Token kanału RSS zaktualizowany' 475 rss_token_updated: 'Token kanału RSS zaktualizowany'
476 annotations_reset: Zresetuj adnotacje
477 tags_reset: Zresetuj tagi
478 entries_reset: Zresetuj wpisy
463 entry: 479 entry:
464 notice: 480 notice:
465 entry_already_saved: 'Wpis już został dodany %date%' 481 entry_already_saved: 'Wpis już został dodany %date%'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 client_created: 'Nowy klient utworzony.' 506 client_created: 'Nowy klient utworzony.'
491 client_deleted: 'Klient usunięty' 507 client_deleted: 'Klient usunięty'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # deleted: 'User "%username%" deleted'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
index f10dc9aa..c1c60430 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -451,7 +451,6 @@ flashes:
451 config_saved: 'Configiração salva. Alguns parâmetros podem ser considerados depois da desconexão.' 451 config_saved: 'Configiração salva. Alguns parâmetros podem ser considerados depois da desconexão.'
452 password_updated: 'Senha atualizada' 452 password_updated: 'Senha atualizada'
453 password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.' 453 password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.'
454 user_updated: 'Informação atualizada'
455 rss_updated: 'Informação de RSS atualizada' 454 rss_updated: 'Informação de RSS atualizada'
456 tagging_rules_updated: 'Regras de tags atualizadas' 455 tagging_rules_updated: 'Regras de tags atualizadas'
457 tagging_rules_deleted: 'Regra de tag apagada' 456 tagging_rules_deleted: 'Regra de tag apagada'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index 875c82e8..50f1b6a2 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -71,6 +71,7 @@ config:
71 # 300_word: 'I read ~300 words per minute' 71 # 300_word: 'I read ~300 words per minute'
72 # 400_word: 'I read ~400 words per minute' 72 # 400_word: 'I read ~400 words per minute'
73 pocket_consumer_key_label: Cheie consumator pentru importarea contentului din Pocket 73 pocket_consumer_key_label: Cheie consumator pentru importarea contentului din Pocket
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'Feed-urile RSS oferite de wallabag îți permit să-ți citești articolele salvate în reader-ul tău preferat RSS.' 76 description: 'Feed-urile RSS oferite de wallabag îți permit să-ți citești articolele salvate în reader-ul tău preferat RSS.'
76 token_label: 'RSS-Token' 77 token_label: 'RSS-Token'
@@ -88,6 +89,18 @@ config:
88 name_label: 'Nume' 89 name_label: 'Nume'
89 email_label: 'E-mail' 90 email_label: 'E-mail'
90 # twoFactorAuthentication_label: 'Two factor authentication' 91 # twoFactorAuthentication_label: 'Two factor authentication'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Parola veche' 105 old_password_label: 'Parola veche'
93 new_password_label: 'Parola nouă' 106 new_password_label: 'Parola nouă'
@@ -355,6 +368,7 @@ import:
355 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
356 worker: 369 worker:
357 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
358 # firefox: 372 # firefox:
359 # page_title: 'Import > Firefox' 373 # page_title: 'Import > Firefox'
360 # 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 # 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."
@@ -458,8 +472,10 @@ flashes:
458 rss_updated: 'Informație RSS actualizată' 472 rss_updated: 'Informație RSS actualizată'
459 # tagging_rules_updated: 'Tagging rules updated' 473 # tagging_rules_updated: 'Tagging rules updated'
460 # tagging_rules_deleted: 'Tagging rule deleted' 474 # tagging_rules_deleted: 'Tagging rule deleted'
461 # user_added: 'User "%username%" added'
462 # rss_token_updated: 'RSS token updated' 475 # rss_token_updated: 'RSS token updated'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
463 entry: 479 entry:
464 notice: 480 notice:
465 # entry_already_saved: 'Entry already saved on %date%' 481 # entry_already_saved: 'Entry already saved on %date%'
@@ -489,3 +505,8 @@ flashes:
489 notice: 505 notice:
490 # client_created: 'New client created.' 506 # client_created: 'New client created.'
491 # client_deleted: 'Client deleted' 507 # client_deleted: 'Client deleted'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # 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 f50f629a..07939ebc 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -71,6 +71,7 @@ config:
71 # 300_word: 'I read ~300 words per minute' 71 # 300_word: 'I read ~300 words per minute'
72 # 400_word: 'I read ~400 words per minute' 72 # 400_word: 'I read ~400 words per minute'
73 # pocket_consumer_key_label: Consumer key for Pocket to import contents 73 # pocket_consumer_key_label: Consumer key for Pocket to import contents
74 # android_configuration: Configure your Android application
74 form_rss: 75 form_rss:
75 description: 'wallabag RSS akışı kaydetmiş olduğunuz makalelerini favori RSS okuyucunuzda görüntülemenizi sağlar. Bunu yapabilmek için öncelikle belirteç (token) oluşturmalısınız.' 76 description: 'wallabag RSS akışı kaydetmiş olduğunuz makalelerini favori RSS okuyucunuzda görüntülemenizi sağlar. Bunu yapabilmek için öncelikle belirteç (token) oluşturmalısınız.'
76 token_label: 'RSS belirteci (token)' 77 token_label: 'RSS belirteci (token)'
@@ -88,6 +89,18 @@ config:
88 name_label: 'İsim' 89 name_label: 'İsim'
89 email_label: 'E-posta' 90 email_label: 'E-posta'
90 twoFactorAuthentication_label: 'İki adımlı doğrulama' 91 twoFactorAuthentication_label: 'İki adımlı doğrulama'
92 delete:
93 # title: Delete my account (a.k.a danger zone)
94 # 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.
95 # confirm: Are you really sure? (THIS CAN'T BE UNDONE)
96 # button: Delete my account
97 reset:
98 # title: Reset area (a.k.a danger zone)
99 # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE.
100 # annotations: Remove ALL annotations
101 # tags: Remove ALL tags
102 # entries: Remove ALL entries
103 # confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
91 form_password: 104 form_password:
92 old_password_label: 'Eski şifre' 105 old_password_label: 'Eski şifre'
93 new_password_label: 'Yeni şifre' 106 new_password_label: 'Yeni şifre'
@@ -96,6 +109,7 @@ config:
96 # if_label: 'if' 109 # if_label: 'if'
97 # then_tag_as_label: 'then tag as' 110 # then_tag_as_label: 'then tag as'
98 # delete_rule_label: 'delete' 111 # delete_rule_label: 'delete'
112 # edit_rule_label: 'edit'
99 rule_label: 'Kural' 113 rule_label: 'Kural'
100 tags_label: 'Etiketler' 114 tags_label: 'Etiketler'
101 faq: 115 faq:
@@ -354,6 +368,7 @@ import:
354 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 368 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
355 worker: 369 worker:
356 # 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:" 370 # 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:"
371 # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors."
357 firefox: 372 firefox:
358 page_title: 'İçe Aktar > Firefox' 373 page_title: 'İçe Aktar > Firefox'
359 # 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 # 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."
@@ -457,8 +472,10 @@ flashes:
457 rss_updated: 'RSS bilgiler güncellendi' 472 rss_updated: 'RSS bilgiler güncellendi'
458 tagging_rules_updated: 'Tagging rules updated' 473 tagging_rules_updated: 'Tagging rules updated'
459 tagging_rules_deleted: 'Tagging rule deleted' 474 tagging_rules_deleted: 'Tagging rule deleted'
460 user_added: 'User "%username%" added'
461 rss_token_updated: 'RSS token updated' 475 rss_token_updated: 'RSS token updated'
476 # annotations_reset: Annotations reset
477 # tags_reset: Tags reset
478 # entries_reset: Entries reset
462 entry: 479 entry:
463 notice: 480 notice:
464 entry_already_saved: 'Entry already saved on %date%' 481 entry_already_saved: 'Entry already saved on %date%'
@@ -488,3 +505,8 @@ flashes:
488 notice: 505 notice:
489 # client_created: 'New client created.' 506 # client_created: 'New client created.'
490 # client_deleted: 'Client deleted' 507 # client_deleted: 'Client deleted'
508 user:
509 notice:
510 # added: 'User "%username%" added'
511 # updated: 'User "%username%" updated'
512 # deleted: 'User "%username%" deleted'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
index ff7ef73a..ec3b23c8 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
@@ -54,6 +54,16 @@
54 <a href="https://getpocket.com/developer/docs/authentication">https://getpocket.com/developer/docs/authentication</a> 54 <a href="https://getpocket.com/developer/docs/authentication">https://getpocket.com/developer/docs/authentication</a>
55 </p> 55 </p>
56 </div> 56 </div>
57
58 <div class="row">
59 <h3>{{ 'config.form_settings.android_configuration'|trans }}</h3>
60 <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}" >Touch here to prefill your Android application</a>
61 <img id="androidQrcode" />
62 <script>
63 const imgBase64 = jrQrcode.getQrBase64('wallabag://{{ app.user.username }}@{{ wallabag_url }}');
64 document.getElementById('androidQrcode').src = imgBase64;
65 </script>
66 </div>
57 </fieldset> 67 </fieldset>
58 68
59 {{ form_rest(form.config) }} 69 {{ form_rest(form.config) }}
@@ -146,10 +156,41 @@
146 </fieldset> 156 </fieldset>
147 {% endif %} 157 {% endif %}
148 158
159 <h2>{{ 'config.reset.title'|trans }}</h2>
160 <fieldset class="w500p inline">
161 <p>{{ 'config.reset.description'|trans }}</p>
162 <ul>
163 <li>
164 <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
165 {{ 'config.reset.annotations'|trans }}
166 </a>
167 </li>
168 <li>
169 <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
170 {{ 'config.reset.tags'|trans }}
171 </a>
172 </li>
173 <li>
174 <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
175 {{ 'config.reset.entries'|trans }}
176 </a>
177 </li>
178 </ul>
179 </fieldset>
180
149 {{ form_widget(form.user._token) }} 181 {{ form_widget(form.user._token) }}
150 {{ form_widget(form.user.save) }} 182 {{ form_widget(form.user.save) }}
151 </form> 183 </form>
152 184
185 {% if enabled_users > 1 %}
186 <h2>{{ 'config.form_user.delete.title'|trans }}</h2>
187
188 <p>{{ 'config.form_user.delete.description'|trans }}</p>
189 <a href="{{ path('delete_account') }}" onclick="return confirm('{{ 'config.form_user.delete.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red delete-account">
190 {{ 'config.form_user.delete.button'|trans }}
191 </a>
192 {% endif %}
193
153 <h2>{{ 'config.tab_menu.password'|trans }}</h2> 194 <h2>{{ 'config.tab_menu.password'|trans }}</h2>
154 195
155 {{ form_start(form.pwd) }} 196 {{ form_start(form.pwd) }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index 19faddc0..f69d158f 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -71,6 +71,18 @@
71 </div> 71 </div>
72 </div> 72 </div>
73 73
74 <div class="row">
75 <div class="input-field col s12">
76 <h5>{{ 'config.form_settings.android_configuration'|trans }}</h5>
77 <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}" class="waves-effect waves-light btn hide-on-large-only">Touch here to prefill your Android application</a>
78 <img id="androidQrcode" class="hide-on-med-and-down" />
79 </div>
80 <script>
81 const imgBase64 = jrQrcode.getQrBase64('wallabag://{{ app.user.username }}@{{ wallabag_url }}');
82 document.getElementById('androidQrcode').src = imgBase64;
83 </script>
84 </div>
85
74 {{ form_widget(form.config.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} 86 {{ form_widget(form.config.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
75 {{ form_rest(form.config) }} 87 {{ form_rest(form.config) }}
76 </form> 88 </form>
@@ -167,6 +179,34 @@
167 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} 179 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
168 {{ form_widget(form.user._token) }} 180 {{ form_widget(form.user._token) }}
169 </form> 181 </form>
182
183 <br /><hr /><br />
184
185 <div class="row">
186 <h5>{{ 'config.reset.title'|trans }}</h5>
187 <p>{{ 'config.reset.description'|trans }}</p>
188 <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
189 {{ 'config.reset.annotations'|trans }}
190 </a>
191 <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
192 {{ 'config.reset.tags'|trans }}
193 </a>
194 <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
195 {{ 'config.reset.entries'|trans }}
196 </a>
197 </div>
198
199 {% if enabled_users > 1 %}
200 <br /><hr /><br />
201
202 <div class="row">
203 <h5>{{ 'config.form_user.delete.title'|trans }}</h5>
204 <p>{{ 'config.form_user.delete.description'|trans }}</p>
205 <a href="{{ path('delete_account') }}" onclick="return confirm('{{ 'config.form_user.delete.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red delete-account">
206 {{ 'config.form_user.delete.button'|trans }}
207 </a>
208 </div>
209 {% endif %}
170 </div> 210 </div>
171 211
172 <div id="set4" class="col s12"> 212 <div id="set4" class="col s12">