aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php150
-rw-r--r--src/Wallabag/ApiBundle/Controller/UserRestController.php23
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php160
-rw-r--r--src/Wallabag/CoreBundle/Command/ShowUserCommand.php77
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php174
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/Configuration.php11
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php1
-rw-r--r--src/Wallabag/CoreBundle/Helper/ContentProxy.php2
-rw-r--r--src/Wallabag/CoreBundle/Helper/DownloadImages.php50
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml76
10 files changed, 278 insertions, 446 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
index 93c8157e..09b73ccb 100644
--- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -299,65 +299,18 @@ class EntryRestController extends WallabagRestController
299 $this->validateAuthentication(); 299 $this->validateAuthentication();
300 300
301 $url = $request->request->get('url'); 301 $url = $request->request->get('url');
302 $title = $request->request->get('title');
303 $tags = $request->request->get('tags', []);
304 $isArchived = $request->request->get('archive');
305 $isStarred = $request->request->get('starred');
306 $content = $request->request->get('content');
307 $language = $request->request->get('language');
308 $picture = $request->request->get('preview_picture');
309 $publishedAt = $request->request->get('published_at');
310 $authors = $request->request->get('authors', '');
311 302
312 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId()); 303 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
304 $url,
305 $this->getUser()->getId()
306 );
313 307
314 if (false === $entry) { 308 if (false === $entry) {
315 $entry = new Entry($this->getUser()); 309 $entry = new Entry($this->getUser());
316 }
317
318 try {
319 $this->get('wallabag_core.content_proxy')->updateEntry(
320 $entry,
321 $url,
322 [
323 'title' => $title,
324 'html' => $content,
325 'url' => $url,
326 'language' => $language,
327 'date' => $publishedAt,
328 // faking the preview picture
329 'open_graph' => [
330 'og_image' => $picture,
331 ],
332 'authors' => explode(',', $authors),
333 ]
334 );
335 } catch (\Exception $e) {
336 $this->get('logger')->error('Error while saving an entry', [
337 'exception' => $e,
338 'entry' => $entry,
339 ]);
340 $entry->setUrl($url); 310 $entry->setUrl($url);
341 } 311 }
342 312
343 if (!empty($tags)) { 313 $this->upsertEntry($entry, $request);
344 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
345 }
346
347 if (!is_null($isStarred)) {
348 $entry->setStarred((bool) $isStarred);
349 }
350
351 if (!is_null($isArchived)) {
352 $entry->setArchived((bool) $isArchived);
353 }
354
355 $em = $this->getDoctrine()->getManager();
356 $em->persist($entry);
357 $em->flush();
358
359 // entry saved, dispatch event about it!
360 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
361 314
362 return $this->sendResponse($entry); 315 return $this->sendResponse($entry);
363 } 316 }
@@ -374,6 +327,11 @@ class EntryRestController extends WallabagRestController
374 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, 327 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
375 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."}, 328 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
376 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."}, 329 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
330 * {"name"="content", "dataType"="string", "required"=false, "description"="Content of the entry"},
331 * {"name"="language", "dataType"="string", "required"=false, "description"="Language of the entry"},
332 * {"name"="preview_picture", "dataType"="string", "required"=false, "description"="Preview picture of the entry"},
333 * {"name"="published_at", "dataType"="datetime|integer", "format"="YYYY-MM-DDTHH:II:SS+TZ or a timestamp", "required"=false, "description"="Published date of the entry"},
334 * {"name"="authors", "dataType"="string", "format"="Name Firstname,author2,author3", "required"=false, "description"="Authors of the entry"},
377 * } 335 * }
378 * ) 336 * )
379 * 337 *
@@ -384,29 +342,7 @@ class EntryRestController extends WallabagRestController
384 $this->validateAuthentication(); 342 $this->validateAuthentication();
385 $this->validateUserAccess($entry->getUser()->getId()); 343 $this->validateUserAccess($entry->getUser()->getId());
386 344
387 $title = $request->request->get('title'); 345 $this->upsertEntry($entry, $request, true);
388 $isArchived = $request->request->get('archive');
389 $isStarred = $request->request->get('starred');
390
391 if (!is_null($title)) {
392 $entry->setTitle($title);
393 }
394
395 if (!is_null($isArchived)) {
396 $entry->setArchived((bool) $isArchived);
397 }
398
399 if (!is_null($isStarred)) {
400 $entry->setStarred((bool) $isStarred);
401 }
402
403 $tags = $request->request->get('tags', '');
404 if (!empty($tags)) {
405 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
406 }
407
408 $em = $this->getDoctrine()->getManager();
409 $em->flush();
410 346
411 return $this->sendResponse($entry); 347 return $this->sendResponse($entry);
412 } 348 }
@@ -673,4 +609,68 @@ class EntryRestController extends WallabagRestController
673 609
674 return (new JsonResponse())->setJson($json); 610 return (new JsonResponse())->setJson($json);
675 } 611 }
612
613 /**
614 * Update or Insert a new entry.
615 *
616 * @param Entry $entry
617 * @param Request $request
618 * @param bool $disableContentUpdate If we don't want the content to be update by fetching the url (used when patching instead of posting)
619 */
620 private function upsertEntry(Entry $entry, Request $request, $disableContentUpdate = false)
621 {
622 $title = $request->request->get('title');
623 $tags = $request->request->get('tags', []);
624 $isArchived = $request->request->get('archive');
625 $isStarred = $request->request->get('starred');
626 $content = $request->request->get('content');
627 $language = $request->request->get('language');
628 $picture = $request->request->get('preview_picture');
629 $publishedAt = $request->request->get('published_at');
630 $authors = $request->request->get('authors', '');
631
632 try {
633 $this->get('wallabag_core.content_proxy')->updateEntry(
634 $entry,
635 $entry->getUrl(),
636 [
637 'title' => !empty($title) ? $title : $entry->getTitle(),
638 'html' => !empty($content) ? $content : $entry->getContent(),
639 'url' => $entry->getUrl(),
640 'language' => !empty($language) ? $language : $entry->getLanguage(),
641 'date' => !empty($publishedAt) ? $publishedAt : $entry->getPublishedAt(),
642 // faking the open graph preview picture
643 'open_graph' => [
644 'og_image' => !empty($picture) ? $picture : $entry->getPreviewPicture(),
645 ],
646 'authors' => is_string($authors) ? explode(',', $authors) : $entry->getPublishedBy(),
647 ],
648 $disableContentUpdate
649 );
650 } catch (\Exception $e) {
651 $this->get('logger')->error('Error while saving an entry', [
652 'exception' => $e,
653 'entry' => $entry,
654 ]);
655 }
656
657 if (!is_null($isArchived)) {
658 $entry->setArchived((bool) $isArchived);
659 }
660
661 if (!is_null($isStarred)) {
662 $entry->setStarred((bool) $isStarred);
663 }
664
665 if (!empty($tags)) {
666 $this->get('wallabag_core.tags_assigner')->assignTagsToEntry($entry, $tags);
667 }
668
669 $em = $this->getDoctrine()->getManager();
670 $em->persist($entry);
671 $em->flush();
672
673 // entry saved, dispatch event about it!
674 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
675 }
676} 676}
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php
index a1b78e3f..8f675b8d 100644
--- a/src/Wallabag/ApiBundle/Controller/UserRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php
@@ -43,16 +43,18 @@ class UserRestController extends WallabagRestController
43 */ 43 */
44 public function putUserAction(Request $request) 44 public function putUserAction(Request $request)
45 { 45 {
46 if (!$this->container->getParameter('fosuser_registration')) { 46 if (!$this->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) {
47 $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); 47 $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json');
48 48
49 return (new JsonResponse())->setJson($json)->setStatusCode(403); 49 return (new JsonResponse())
50 ->setJson($json)
51 ->setStatusCode(JsonResponse::HTTP_FORBIDDEN);
50 } 52 }
51 53
52 $userManager = $this->get('fos_user.user_manager'); 54 $userManager = $this->get('fos_user.user_manager');
53 $user = $userManager->createUser(); 55 $user = $userManager->createUser();
54 // enable created user by default 56 // user will be disabled BY DEFAULT to avoid spamming account to be enabled
55 $user->setEnabled(true); 57 $user->setEnabled(false);
56 58
57 $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ 59 $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [
58 'csrf_protection' => false, 60 'csrf_protection' => false,
@@ -90,7 +92,9 @@ class UserRestController extends WallabagRestController
90 92
91 $json = $this->get('serializer')->serialize(['error' => $errors], 'json'); 93 $json = $this->get('serializer')->serialize(['error' => $errors], 'json');
92 94
93 return (new JsonResponse())->setJson($json)->setStatusCode(400); 95 return (new JsonResponse())
96 ->setJson($json)
97 ->setStatusCode(JsonResponse::HTTP_BAD_REQUEST);
94 } 98 }
95 99
96 $userManager->updateUser($user); 100 $userManager->updateUser($user);
@@ -99,17 +103,18 @@ class UserRestController extends WallabagRestController
99 $event = new UserEvent($user, $request); 103 $event = new UserEvent($user, $request);
100 $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); 104 $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
101 105
102 return $this->sendUser($user); 106 return $this->sendUser($user, JsonResponse::HTTP_CREATED);
103 } 107 }
104 108
105 /** 109 /**
106 * Send user response. 110 * Send user response.
107 * 111 *
108 * @param User $user 112 * @param User $user
113 * @param int $status HTTP Status code to send
109 * 114 *
110 * @return JsonResponse 115 * @return JsonResponse
111 */ 116 */
112 private function sendUser(User $user) 117 private function sendUser(User $user, $status = JsonResponse::HTTP_OK)
113 { 118 {
114 $json = $this->get('serializer')->serialize( 119 $json = $this->get('serializer')->serialize(
115 $user, 120 $user,
@@ -117,7 +122,9 @@ class UserRestController extends WallabagRestController
117 SerializationContext::create()->setGroups(['user_api']) 122 SerializationContext::create()->setGroups(['user_api'])
118 ); 123 );
119 124
120 return (new JsonResponse())->setJson($json); 125 return (new JsonResponse())
126 ->setJson($json)
127 ->setStatusCode($status);
121 } 128 }
122 129
123 /** 130 /**
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index d9608246..0f119377 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -292,165 +292,7 @@ class InstallCommand extends ContainerAwareCommand
292 // cleanup before insert new stuff 292 // cleanup before insert new stuff
293 $em->createQuery('DELETE FROM CraueConfigBundle:Setting')->execute(); 293 $em->createQuery('DELETE FROM CraueConfigBundle:Setting')->execute();
294 294
295 $settings = [ 295 foreach ($this->getContainer()->getParameter('wallabag_core.default_internal_settings') as $setting) {
296 [
297 'name' => 'share_public',
298 'value' => '1',
299 'section' => 'entry',
300 ],
301 [
302 'name' => 'carrot',
303 'value' => '1',
304 'section' => 'entry',
305 ],
306 [
307 'name' => 'share_diaspora',
308 'value' => '1',
309 'section' => 'entry',
310 ],
311 [
312 'name' => 'diaspora_url',
313 'value' => 'http://diasporapod.com',
314 'section' => 'entry',
315 ],
316 [
317 'name' => 'share_unmark',
318 'value' => '1',
319 'section' => 'entry',
320 ],
321 [
322 'name' => 'unmark_url',
323 'value' => 'https://unmark.it',
324 'section' => 'entry',
325 ],
326 [
327 'name' => 'share_shaarli',
328 'value' => '1',
329 'section' => 'entry',
330 ],
331 [
332 'name' => 'shaarli_url',
333 'value' => 'http://myshaarli.com',
334 'section' => 'entry',
335 ],
336 [
337 'name' => 'share_scuttle',
338 'value' => '1',
339 'section' => 'entry',
340 ],
341 [
342 'name' => 'scuttle_url',
343 'value' => 'http://scuttle.org',
344 'section' => 'entry',
345 ],
346 [
347 'name' => 'share_mail',
348 'value' => '1',
349 'section' => 'entry',
350 ],
351 [
352 'name' => 'share_twitter',
353 'value' => '1',
354 'section' => 'entry',
355 ],
356 [
357 'name' => 'export_epub',
358 'value' => '1',
359 'section' => 'export',
360 ],
361 [
362 'name' => 'export_mobi',
363 'value' => '1',
364 'section' => 'export',
365 ],
366 [
367 'name' => 'export_pdf',
368 'value' => '1',
369 'section' => 'export',
370 ],
371 [
372 'name' => 'export_csv',
373 'value' => '1',
374 'section' => 'export',
375 ],
376 [
377 'name' => 'export_json',
378 'value' => '1',
379 'section' => 'export',
380 ],
381 [
382 'name' => 'export_txt',
383 'value' => '1',
384 'section' => 'export',
385 ],
386 [
387 'name' => 'export_xml',
388 'value' => '1',
389 'section' => 'export',
390 ],
391 [
392 'name' => 'import_with_redis',
393 'value' => '0',
394 'section' => 'import',
395 ],
396 [
397 'name' => 'import_with_rabbitmq',
398 'value' => '0',
399 'section' => 'import',
400 ],
401 [
402 'name' => 'show_printlink',
403 'value' => '1',
404 'section' => 'entry',
405 ],
406 [
407 'name' => 'wallabag_support_url',
408 'value' => 'https://www.wallabag.org/pages/support.html',
409 'section' => 'misc',
410 ],
411 [
412 'name' => 'wallabag_url',
413 'value' => '',
414 'section' => 'misc',
415 ],
416 [
417 'name' => 'piwik_enabled',
418 'value' => '0',
419 'section' => 'analytics',
420 ],
421 [
422 'name' => 'piwik_host',
423 'value' => 'v2.wallabag.org',
424 'section' => 'analytics',
425 ],
426 [
427 'name' => 'piwik_site_id',
428 'value' => '1',
429 'section' => 'analytics',
430 ],
431 [
432 'name' => 'demo_mode_enabled',
433 'value' => '0',
434 'section' => 'misc',
435 ],
436 [
437 'name' => 'demo_mode_username',
438 'value' => 'wallabag',
439 'section' => 'misc',
440 ],
441 [
442 'name' => 'download_images_enabled',
443 'value' => '0',
444 'section' => 'misc',
445 ],
446 [
447 'name' => 'restricted_access',
448 'value' => '0',
449 'section' => 'entry',
450 ],
451 ];
452
453 foreach ($settings as $setting) {
454 $newSetting = new Setting(); 296 $newSetting = new Setting();
455 $newSetting->setName($setting['name']); 297 $newSetting->setName($setting['name']);
456 $newSetting->setValue($setting['value']); 298 $newSetting->setValue($setting['value']);
diff --git a/src/Wallabag/CoreBundle/Command/ShowUserCommand.php b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php
new file mode 100644
index 00000000..0eeaabc4
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Command/ShowUserCommand.php
@@ -0,0 +1,77 @@
1<?php
2
3namespace Wallabag\CoreBundle\Command;
4
5use Doctrine\ORM\NoResultException;
6use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
7use Symfony\Component\Console\Input\InputArgument;
8use Symfony\Component\Console\Input\InputInterface;
9use Symfony\Component\Console\Output\OutputInterface;
10use Wallabag\UserBundle\Entity\User;
11
12class ShowUserCommand extends ContainerAwareCommand
13{
14 /** @var OutputInterface */
15 protected $output;
16
17 protected function configure()
18 {
19 $this
20 ->setName('wallabag:user:show')
21 ->setDescription('Show user details')
22 ->setHelp('This command shows the details for an user')
23 ->addArgument(
24 'username',
25 InputArgument::REQUIRED,
26 'User to show details for'
27 );
28 }
29
30 protected function execute(InputInterface $input, OutputInterface $output)
31 {
32 $this->output = $output;
33
34 $username = $input->getArgument('username');
35
36 try {
37 $user = $this->getUser($username);
38 $this->showUser($user);
39 } catch (NoResultException $e) {
40 $output->writeln(sprintf('<error>User "%s" not found.</error>', $username));
41
42 return 1;
43 }
44
45 return 0;
46 }
47
48 /**
49 * @param User $user
50 */
51 private function showUser(User $user)
52 {
53 $this->output->writeln(sprintf('Username : %s', $user->getUsername()));
54 $this->output->writeln(sprintf('Email : %s', $user->getEmail()));
55 $this->output->writeln(sprintf('Display name : %s', $user->getName()));
56 $this->output->writeln(sprintf('Creation date : %s', $user->getCreatedAt()->format('Y-m-d H:i:s')));
57 $this->output->writeln(sprintf('Last login : %s', $user->getLastLogin() !== null ? $user->getLastLogin()->format('Y-m-d H:i:s') : 'never'));
58 $this->output->writeln(sprintf('2FA activated: %s', $user->isTwoFactorAuthentication() ? 'yes' : 'no'));
59 }
60
61 /**
62 * Fetches a user from its username.
63 *
64 * @param string $username
65 *
66 * @return \Wallabag\UserBundle\Entity\User
67 */
68 private function getUser($username)
69 {
70 return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username);
71 }
72
73 private function getDoctrine()
74 {
75 return $this->getContainer()->get('doctrine');
76 }
77}
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
index aaeb9ee9..a52288e6 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
@@ -6,173 +6,27 @@ use Doctrine\Common\DataFixtures\AbstractFixture;
6use Doctrine\Common\DataFixtures\OrderedFixtureInterface; 6use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
7use Doctrine\Common\Persistence\ObjectManager; 7use Doctrine\Common\Persistence\ObjectManager;
8use Craue\ConfigBundle\Entity\Setting; 8use Craue\ConfigBundle\Entity\Setting;
9use Symfony\Component\DependencyInjection\ContainerAwareInterface;
10use Symfony\Component\DependencyInjection\ContainerInterface;
9 11
10class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface 12class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
11{ 13{
12 /** 14 /**
15 * @var ContainerInterface
16 */
17 private $container;
18
19 public function setContainer(ContainerInterface $container = null)
20 {
21 $this->container = $container;
22 }
23
24 /**
13 * {@inheritdoc} 25 * {@inheritdoc}
14 */ 26 */
15 public function load(ObjectManager $manager) 27 public function load(ObjectManager $manager)
16 { 28 {
17 $settings = [ 29 foreach ($this->container->getParameter('wallabag_core.default_internal_settings') as $setting) {
18 [
19 'name' => 'share_public',
20 'value' => '1',
21 'section' => 'entry',
22 ],
23 [
24 'name' => 'carrot',
25 'value' => '1',
26 'section' => 'entry',
27 ],
28 [
29 'name' => 'share_diaspora',
30 'value' => '1',
31 'section' => 'entry',
32 ],
33 [
34 'name' => 'diaspora_url',
35 'value' => 'http://diasporapod.com',
36 'section' => 'entry',
37 ],
38 [
39 'name' => 'share_unmark',
40 'value' => '1',
41 'section' => 'entry',
42 ],
43 [
44 'name' => 'unmark_url',
45 'value' => 'https://unmark.it',
46 'section' => 'entry',
47 ],
48 [
49 'name' => 'share_shaarli',
50 'value' => '1',
51 'section' => 'entry',
52 ],
53 [
54 'name' => 'share_scuttle',
55 'value' => '1',
56 'section' => 'entry',
57 ],
58 [
59 'name' => 'shaarli_url',
60 'value' => 'http://myshaarli.com',
61 'section' => 'entry',
62 ],
63 [
64 'name' => 'scuttle_url',
65 'value' => 'http://scuttle.org',
66 'section' => 'entry',
67 ],
68 [
69 'name' => 'share_mail',
70 'value' => '1',
71 'section' => 'entry',
72 ],
73 [
74 'name' => 'share_twitter',
75 'value' => '1',
76 'section' => 'entry',
77 ],
78 [
79 'name' => 'export_epub',
80 'value' => '1',
81 'section' => 'export',
82 ],
83 [
84 'name' => 'export_mobi',
85 'value' => '1',
86 'section' => 'export',
87 ],
88 [
89 'name' => 'export_pdf',
90 'value' => '1',
91 'section' => 'export',
92 ],
93 [
94 'name' => 'export_csv',
95 'value' => '1',
96 'section' => 'export',
97 ],
98 [
99 'name' => 'export_json',
100 'value' => '1',
101 'section' => 'export',
102 ],
103 [
104 'name' => 'export_txt',
105 'value' => '1',
106 'section' => 'export',
107 ],
108 [
109 'name' => 'export_xml',
110 'value' => '1',
111 'section' => 'export',
112 ],
113 [
114 'name' => 'import_with_redis',
115 'value' => '0',
116 'section' => 'import',
117 ],
118 [
119 'name' => 'import_with_rabbitmq',
120 'value' => '0',
121 'section' => 'import',
122 ],
123 [
124 'name' => 'show_printlink',
125 'value' => '1',
126 'section' => 'entry',
127 ],
128 [
129 'name' => 'wallabag_support_url',
130 'value' => 'https://www.wallabag.org/pages/support.html',
131 'section' => 'misc',
132 ],
133 [
134 'name' => 'wallabag_url',
135 'value' => 'http://v2.wallabag.org',
136 'section' => 'misc',
137 ],
138 [
139 'name' => 'piwik_enabled',
140 'value' => '0',
141 'section' => 'analytics',
142 ],
143 [
144 'name' => 'piwik_host',
145 'value' => 'v2.wallabag.org',
146 'section' => 'analytics',
147 ],
148 [
149 'name' => 'piwik_site_id',
150 'value' => '1',
151 'section' => 'analytics',
152 ],
153 [
154 'name' => 'demo_mode_enabled',
155 'value' => '0',
156 'section' => 'misc',
157 ],
158 [
159 'name' => 'demo_mode_username',
160 'value' => 'wallabag',
161 'section' => 'misc',
162 ],
163 [
164 'name' => 'download_images_enabled',
165 'value' => '0',
166 'section' => 'misc',
167 ],
168 [
169 'name' => 'restricted_access',
170 'value' => '0',
171 'section' => 'entry',
172 ],
173 ];
174
175 foreach ($settings as $setting) {
176 $newSetting = new Setting(); 30 $newSetting = new Setting();
177 $newSetting->setName($setting['name']); 31 $newSetting->setName($setting['name']);
178 $newSetting->setValue($setting['value']); 32 $newSetting->setValue($setting['value']);
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
index 8b5b5744..33df92d3 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
@@ -52,6 +52,17 @@ class Configuration implements ConfigurationInterface
52 ->scalarNode('api_limit_mass_actions') 52 ->scalarNode('api_limit_mass_actions')
53 ->defaultValue(10) 53 ->defaultValue(10)
54 ->end() 54 ->end()
55 ->arrayNode('default_internal_settings')
56 ->prototype('array')
57 ->children()
58 ->scalarNode('name')->end()
59 ->scalarNode('value')->end()
60 ->enumNode('section')
61 ->values(['entry', 'misc', 'api', 'analytics', 'export', 'import'])
62 ->end()
63 ->end()
64 ->end()
65 ->end()
55 ->end() 66 ->end()
56 ; 67 ;
57 68
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
index a2a703cb..b4d8a386 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
@@ -28,6 +28,7 @@ class WallabagCoreExtension extends Extension
28 $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']); 28 $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']);
29 $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']); 29 $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']);
30 $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']); 30 $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
31 $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
31 32
32 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 33 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
33 $loader->load('services.yml'); 34 $loader->load('services.yml');
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
index bfaa1976..d5820e66 100644
--- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php
+++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php
@@ -105,7 +105,7 @@ class ContentProxy
105 } 105 }
106 } 106 }
107 107
108 if (!empty($content['authors'])) { 108 if (!empty($content['authors']) && is_array($content['authors'])) {
109 $entry->setPublishedBy($content['authors']); 109 $entry->setPublishedBy($content['authors']);
110 } 110 }
111 111
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
index 54e23a05..ed888cdb 100644
--- a/src/Wallabag/CoreBundle/Helper/DownloadImages.php
+++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
@@ -5,6 +5,7 @@ namespace Wallabag\CoreBundle\Helper;
5use Psr\Log\LoggerInterface; 5use Psr\Log\LoggerInterface;
6use Symfony\Component\DomCrawler\Crawler; 6use Symfony\Component\DomCrawler\Crawler;
7use GuzzleHttp\Client; 7use GuzzleHttp\Client;
8use GuzzleHttp\Message\Response;
8use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser; 9use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser;
9use Symfony\Component\Finder\Finder; 10use Symfony\Component\Finder\Finder;
10 11
@@ -116,13 +117,11 @@ class DownloadImages
116 return false; 117 return false;
117 } 118 }
118 119
119 $ext = $this->mimeGuesser->guess($res->getHeader('content-type')); 120 $ext = $this->getExtensionFromResponse($res, $imagePath);
120 $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); 121 if (false === $res) {
121 if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
122 $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: '.$imagePath);
123
124 return false; 122 return false;
125 } 123 }
124
126 $hashImage = hash('crc32', $absolutePath); 125 $hashImage = hash('crc32', $absolutePath);
127 $localPath = $folderPath.'/'.$hashImage.'.'.$ext; 126 $localPath = $folderPath.'/'.$hashImage.'.'.$ext;
128 127
@@ -237,4 +236,45 @@ class DownloadImages
237 236
238 return false; 237 return false;
239 } 238 }
239
240 /**
241 * Retrieve and validate the extension from the response of the url of the image.
242 *
243 * @param Response $res Guzzle Response
244 * @param string $imagePath Path from the src image from the content (used for log only)
245 *
246 * @return string|false Extension name or false if validation failed
247 */
248 private function getExtensionFromResponse(Response $res, $imagePath)
249 {
250 $ext = $this->mimeGuesser->guess($res->getHeader('content-type'));
251 $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]);
252
253 // ok header doesn't have the extension, try a different way
254 if (empty($ext)) {
255 $types = [
256 'jpeg' => "\xFF\xD8\xFF",
257 'gif' => 'GIF',
258 'png' => "\x89\x50\x4e\x47\x0d\x0a",
259 ];
260 $bytes = substr((string) $res->getBody(), 0, 8);
261
262 foreach ($types as $type => $header) {
263 if (0 === strpos($bytes, $header)) {
264 $ext = $type;
265 break;
266 }
267 }
268
269 $this->logger->debug('DownloadImages: Checking extension (alternative)', ['ext' => $ext]);
270 }
271
272 if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) {
273 $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping: '.$imagePath);
274
275 return false;
276 }
277
278 return $ext;
279 }
240} 280}
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index 70e9575a..16e8072b 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -24,7 +24,7 @@ menu:
24 tags: 'Tags' 24 tags: 'Tags'
25 internal_settings: 'Strumenti' 25 internal_settings: 'Strumenti'
26 import: 'Importa' 26 import: 'Importa'
27 howto: 'How to' 27 howto: 'Come fare'
28 # developer: 'API clients management' 28 # developer: 'API clients management'
29 logout: 'Logout' 29 logout: 'Logout'
30 about: 'About' 30 about: 'About'
@@ -44,8 +44,8 @@ footer:
44 wallabag: 44 wallabag:
45 elsewhere: 'Porta wallabag con te' 45 elsewhere: 'Porta wallabag con te'
46 social: 'Social' 46 social: 'Social'
47 powered_by: 'powered by' 47 powered_by: 'Offerto da'
48 about: 'About' 48 about: 'A proposito'
49 # stats: Since %user_creation% you read %nb_archives% articles. That is about %per_day% a day! 49 # stats: Since %user_creation% you read %nb_archives% articles. That is about %per_day% a day!
50 50
51config: 51config:
@@ -55,7 +55,7 @@ config:
55 rss: 'RSS' 55 rss: 'RSS'
56 user_info: 'Informazioni utente' 56 user_info: 'Informazioni utente'
57 password: 'Password' 57 password: 'Password'
58 rules: 'Regole di tagging' 58 rules: 'Regole di etichettatura'
59 new_user: 'Aggiungi utente' 59 new_user: 'Aggiungi utente'
60 form: 60 form:
61 save: 'Salva' 61 save: 'Salva'
@@ -83,7 +83,7 @@ config:
83 # help_pocket_consumer_key: "Required for Pocket import. You can create it in your Pocket account." 83 # help_pocket_consumer_key: "Required for Pocket import. You can create it in your Pocket account."
84 form_rss: 84 form_rss:
85 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.' 85 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.'
86 token_label: 'RSS token' 86 token_label: 'Token RSS'
87 no_token: 'Nessun token' 87 no_token: 'Nessun token'
88 token_create: 'Crea il tuo token' 88 token_create: 'Crea il tuo token'
89 token_reset: 'Rigenera il tuo token' 89 token_reset: 'Rigenera il tuo token'
@@ -94,10 +94,10 @@ config:
94 archive: 'archiviati' 94 archive: 'archiviati'
95 rss_limit: 'Numero di elementi nel feed' 95 rss_limit: 'Numero di elementi nel feed'
96 form_user: 96 form_user:
97 two_factor_description: "Abilitando la two factor authentication riceverai una e-mail con un codice per ogni nuova connesione non verificata" 97 two_factor_description: "Abilitando l'\autenticazione a due fattori riceverai una e-mail con un codice per ogni nuova connesione non verificata"
98 name_label: 'Nome' 98 name_label: 'Nome'
99 email_label: 'E-mail' 99 email_label: 'E-mail'
100 twoFactorAuthentication_label: 'Two factor authentication' 100 twoFactorAuthentication_label: 'Autenticazione a due fattori'
101 # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." 101 # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email."
102 delete: 102 delete:
103 # title: Delete my account (a.k.a danger zone) 103 # title: Delete my account (a.k.a danger zone)
@@ -119,19 +119,19 @@ config:
119 repeat_new_password_label: 'Ripeti la nuova password' 119 repeat_new_password_label: 'Ripeti la nuova password'
120 form_rules: 120 form_rules:
121 if_label: 'se' 121 if_label: 'se'
122 then_tag_as_label: 'allora tagga come' 122 then_tag_as_label: 'allora etichetta come'
123 delete_rule_label: 'elimina' 123 delete_rule_label: 'elimina'
124 # edit_rule_label: 'edit' 124 # edit_rule_label: 'edit'
125 rule_label: 'Regola' 125 rule_label: 'Regola'
126 tags_label: 'Tag' 126 tags_label: 'Etichetta'
127 faq: 127 faq:
128 title: 'FAQ' 128 title: 'FAQ'
129 tagging_rules_definition_title: 'Cosa significa « regole di tagging » ?' 129 tagging_rules_definition_title: 'Cosa significa « regole di etichettatura» ?'
130 tagging_rules_definition_description: 'Sono regole utilizzate da wallabag per taggare automaticamente i contenuti.<br />Ogni volta che viene aggiunto un contenuto, tutte le regole di tagging rules vengono utilizzate per aggiungere i tag configurati, risparmiandoti il lavoro di classificare i contenuti manualmente.' 130 tagging_rules_definition_description: 'Sono regole utilizzate da wallabag per etichettare automaticamente i contenuti.<br />Ogni volta che viene aggiunto un contenuto, tutte le regole di etichettatura vengono utilizzate per aggiungere le etichette configurate, risparmiandoti il lavoro di classificare i contenuti manualmente.'
131 how_to_use_them_title: 'Come si usano?' 131 how_to_use_them_title: 'Come si usano?'
132 how_to_use_them_description: 'Diciamo che vuoi taggare un contenuto come « <i>lettura veloce</i> » quando il tempo di lettura è inferiore ai 3 minuti.<br />In questo case, devi mettere « readingTime &lt;= 3 » nel campo <i>Regola</i> e « <i>lettura veloce</i> » nel campo <i>Tag</i>.<br />Molti tag si possono aggiungere contemporanemente separandoli con una virgola: « <i>lettura veloce, da leggere</i> »<br />Regole complesse possono essere scritte utilizzando gli operatori predefiniti: se « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » allora tagga « <i>lettura lunga, github </i> »' 132 how_to_use_them_description: 'Diciamo che vuoi etichettare un contenuto come « <i>lettura veloce</i> » quando il tempo di lettura è inferiore ai 3 minuti.<br />In questo case, devi mettere « readingTime &lt;= 3 » nel campo <i>Regola</i> e « <i>lettura veloce</i> » nel campo <i>Etichette</i>.<br />Molte etichette si possono aggiungere contemporanemente separandole con una virgola: « <i>lettura veloce, da leggere</i> »<br />Regole complesse possono essere scritte utilizzando gli operatori predefiniti: se « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » allora etichetta « <i>lettura lunga, github </i> »'
133 variables_available_title: 'Quali operatori e variabili posso utilizzare per scrivere delle regole?' 133 variables_available_title: 'Quali operatori e variabili posso utilizzare per scrivere delle regole?'
134 variables_available_description: 'I seguenti operatori e variabili posso essere utilizzati per scrivere regole di tagging:' 134 variables_available_description: 'I seguenti operatori e variabili posso essere utilizzati per scrivere regole di etichettatura:'
135 meaning: 'Significato' 135 meaning: 'Significato'
136 variable_description: 136 variable_description:
137 label: 'Variabile' 137 label: 'Variabile'
@@ -211,7 +211,7 @@ entry:
211 view_original_article: 'Contenuto originale' 211 view_original_article: 'Contenuto originale'
212 re_fetch_content: 'Ri-ottieni pagina' 212 re_fetch_content: 'Ri-ottieni pagina'
213 delete: 'Elimina' 213 delete: 'Elimina'
214 add_a_tag: 'Aggiungi un tag' 214 add_a_tag: 'Aggiungi un''etichetta'
215 share_content: 'Condividi' 215 share_content: 'Condividi'
216 share_email_label: 'E-mail' 216 share_email_label: 'E-mail'
217 # public_link: 'public link' 217 # public_link: 'public link'
@@ -222,7 +222,7 @@ entry:
222 label: 'Problemi?' 222 label: 'Problemi?'
223 description: 'Questo contenuto viene visualizzato male?' 223 description: 'Questo contenuto viene visualizzato male?'
224 edit_title: 'Modifica titolo' 224 edit_title: 'Modifica titolo'
225 original_article: 'originale' 225 original_article: 'Originale'
226 annotations_on_the_entry: '{0} Nessuna annotazione|{1} Una annotazione|]1,Inf[ %count% annotazioni' 226 annotations_on_the_entry: '{0} Nessuna annotazione|{1} Una annotazione|]1,Inf[ %count% annotazioni'
227 created_at: 'Data di creazione' 227 created_at: 'Data di creazione'
228 # published_at: 'Publication date' 228 # published_at: 'Publication date'
@@ -242,11 +242,11 @@ entry:
242 public: 242 public:
243 # shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>" 243 # shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
244 confirm: 244 confirm:
245 # delete: "Are you sure you want to remove that article?" 245 delete: "Vuoi veramente rimuovere quell'articolo?"
246 # delete_tag: "Are you sure you want to remove that tag from that article?" 246 delete_tag: "Vuoi veramente rimuovere quell'etichetta da quell'articolo?"
247 247
248about: 248about:
249 page_title: 'About' 249 page_title: 'A proposito'
250 top_menu: 250 top_menu:
251 who_behind_wallabag: "Chi c'è dietro a wallabag" 251 who_behind_wallabag: "Chi c'è dietro a wallabag"
252 getting_help: 'Ottieni aiuto' 252 getting_help: 'Ottieni aiuto'
@@ -265,7 +265,7 @@ about:
265 bug_reports: 'Bug reports' 265 bug_reports: 'Bug reports'
266 support: '<a href="https://github.com/wallabag/wallabag/issues">su GitHub</a>' 266 support: '<a href="https://github.com/wallabag/wallabag/issues">su GitHub</a>'
267 helping: 267 helping:
268 description: 'wallabag è gratuito opensource. Puoi aiutarci:' 268 description: 'wallabag è gratuito ed OpenSource. Puoi aiutarci:'
269 by_contributing: 'per contribuire al progetto:' 269 by_contributing: 'per contribuire al progetto:'
270 by_contributing_2: 'un elenco delle attività richieste' 270 by_contributing_2: 'un elenco delle attività richieste'
271 by_paypal: 'via Paypal' 271 by_paypal: 'via Paypal'
@@ -273,7 +273,7 @@ about:
273 description: 'Un grazie ai collaboratori di wallabag web application' 273 description: 'Un grazie ai collaboratori di wallabag web application'
274 third_party: 274 third_party:
275 description: 'Ecco un elenco delle librerie di terze parti utilizzate in wallabag (con le rispettive licenze):' 275 description: 'Ecco un elenco delle librerie di terze parti utilizzate in wallabag (con le rispettive licenze):'
276 package: 'Package' 276 package: 'Pacchetto'
277 license: 'Licenza' 277 license: 'Licenza'
278 278
279howto: 279howto:
@@ -299,7 +299,7 @@ howto:
299 ios: 'sullo store di iTunes' 299 ios: 'sullo store di iTunes'
300 windows: 'sullo store di Microsoft' 300 windows: 'sullo store di Microsoft'
301 bookmarklet: 301 bookmarklet:
302 description: 'Trascinando e rilasciando questo link sulla barra dei bookmark del tuo browser:' 302 description: 'Trascinando e rilasciando questo link sulla barra dei preferiti del tuo browser:'
303 shortcuts: 303 shortcuts:
304 # page_description: Here are the shortcuts available in wallabag. 304 # page_description: Here are the shortcuts available in wallabag.
305 # shortcut: Shortcut 305 # shortcut: Shortcut
@@ -333,7 +333,7 @@ quickstart:
333 # more: 'More…' 333 # more: 'More…'
334 intro: 334 intro:
335 title: 'Benvenuto su wallabag!' 335 title: 'Benvenuto su wallabag!'
336 paragraph_1: "Un tour in cui ti guideremo per scoprire e che ti mostrerà delle funzionalità che potrebbero interessarti." 336 paragraph_1: "Ti accompagneremo alla scoperta di wallabag e ti mostreremo delle funzionalità che potrebbero interessarti."
337 paragraph_2: 'Seguici!' 337 paragraph_2: 'Seguici!'
338 configure: 338 configure:
339 title: "Configura l'applicazione" 339 title: "Configura l'applicazione"
@@ -383,9 +383,9 @@ quickstart:
383 gitter: 'Su Gitter' 383 gitter: 'Su Gitter'
384 384
385tag: 385tag:
386 page_title: 'Tags' 386 page_title: 'Etichette'
387 list: 387 list:
388 number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag." 388 number_on_the_page: "{0} Non ci sono etichette.|{1} C'è un'etichetta.|]1,Inf[ ci sono %count% etichette."
389 # see_untagged_entries: 'See untagged entries' 389 # see_untagged_entries: 'See untagged entries'
390 new: 390 new:
391 # add: 'Add' 391 # add: 'Add'
@@ -403,20 +403,20 @@ import:
403 save_label: 'Carica file' 403 save_label: 'Carica file'
404 pocket: 404 pocket:
405 page_title: 'Importa da > Pocket' 405 page_title: 'Importa da > Pocket'
406 description: "Questo importatore copierà tutti i tuoi dati da Pocket. Pocket non ci consente di ottenere contenuti dal loro servzio, così il contenuto leggibile di ogni articolo verrà ri-ottenuto da wallabag." 406 description: "Questo importatore copierà tutti i tuoi dati da Pocket. Pocket non ci consente di ottenere contenuti dal loro servizio, così il contenuto leggibile di ogni articolo verrà ri-ottenuto da wallabag."
407 config_missing: 407 config_missing:
408 description: "Importazione da Pocket non configurata." 408 description: "Importazione da Pocket non configurata."
409 admin_message: 'Devi definire %keyurls% una pocket_consumer_key %keyurle%.' 409 admin_message: 'Devi definire %keyurls% una pocket_consumer_key %keyurle%.'
410 user_message: 'Il tuo amministratore di server deve define una API Key per Pocket.' 410 user_message: 'Il tuo amministratore del server deve definire una API Key per Pocket.'
411 authorize_message: 'Puoi importare dati dal tuo account Pocket. Devi solo cliccare sul pulsante sottostante e autorizzare la connessione a getpocket.com.' 411 authorize_message: 'Puoi importare dati dal tuo account Pocket. Devi solo cliccare sul pulsante sottostante e autorizzare la connessione a getpocket.com.'
412 connect_to_pocket: 'Connetti a Pocket and importa i dati' 412 connect_to_pocket: 'Connetti a Pocket and importa i dati'
413 wallabag_v1: 413 wallabag_v1:
414 page_title: 'Importa da > Wallabag v1' 414 page_title: 'Importa da > Wallabag v1'
415 description: 'Questo importatore copierà tutti i tuoi dati da un wallabag v1. Nella tua pagina di configurazione, clicca su "JSON export" nella sezione "Esport i tuoi dati di wallabag". Otterrai un file "wallabag-export-1-xxxx-xx-xx.json".' 415 description: 'Questo importatore copierà tutti i tuoi dati da un wallabag v1. Nella tua pagina di configurazione, clicca su "JSON export" nella sezione "Esporta i tuoi dati di wallabag". Otterrai un file "wallabag-export-1-xxxx-xx-xx.json".'
416 how_to: 'Seleziona la tua esportazione di wallabag e clicca sul pulsante sottostante caricare il file e importare i dati.' 416 how_to: 'Seleziona la tua esportazione di wallabag e clicca sul pulsante sottostante caricare il file e importare i dati.'
417 wallabag_v2: 417 wallabag_v2:
418 page_title: 'Importa da > Wallabag v2' 418 page_title: 'Importa da > Wallabag v2'
419 description: 'Questo importatore copierà tutti i tuoi dati da un wallabag v2. Vai in "Tutti i contenuti", e, nella sidebar di esportazione, clicca su "JSON". Otterrai un file "Tutti i contenuti.json".' 419 description: 'Questo importatore copierà tutti i tuoi dati da un wallabag v2. Vai in "Tutti i contenuti", e, nella barra laterale di esportazione, clicca su "JSON". Otterrai un file "Tutti i contenuti.json'
420 readability: 420 readability:
421 page_title: 'Importa da > Readability' 421 page_title: 'Importa da > Readability'
422 # description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).' 422 # description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
@@ -455,19 +455,19 @@ developer:
455 title: 'Client esistenti' 455 title: 'Client esistenti'
456 field_id: 'Client ID' 456 field_id: 'Client ID'
457 field_secret: 'Client secret' 457 field_secret: 'Client secret'
458 field_uris: 'Redirect URI' 458 field_uris: 'URI di reindirizzamento'
459 field_grant_types: 'Tipi di grant permessi' 459 field_grant_types: 'Tipi di permessi concessi'
460 no_client: 'Ancora nessun client.' 460 no_client: 'Ancora nessun client.'
461 remove: 461 remove:
462 warn_message_1: "Hai la possibilitò di rimuovere questo client.L'operazione è IRREVERSIBILE!" 462 warn_message_1: "Hai la possibilità di rimuovere questo client. L'operazione è IRREVERSIBILE!"
463 warn_message_2: "Se lo rimuovi, ogni app configurata con questo client non sarà più in grado di autenticarsi." 463 warn_message_2: "Se lo rimuovi, ogni app configurata con questo client non sarà più in grado di autenticarsi."
464 action: 'Rimuovi questo client' 464 action: 'Rimuovi questo client'
465 client: 465 client:
466 # page_title: 'API clients management > Nuovo client' 466 # page_title: 'API clients management > Nuovo client'
467 page_description: 'Stai per creare un nuovo client. Compila i campi sottostanti per il redirect URI della tua applicazione.' 467 page_description: 'Stai per creare un nuovo client. Compila i campi sottostanti per lo URI di reindirizzamento della tua applicazione.'
468 form: 468 form:
469 # name_label: 'Name of the client' 469 # name_label: 'Name of the client'
470 redirect_uris_label: 'Redirect URI' 470 redirect_uris_label: 'URI di reindirizzamento'
471 save_label: 'Crea un nuovo client' 471 save_label: 'Crea un nuovo client'
472 action_back: 'Indietro' 472 action_back: 'Indietro'
473 client_parameter: 473 client_parameter:
@@ -477,7 +477,7 @@ developer:
477 field_id: 'Client ID' 477 field_id: 'Client ID'
478 field_secret: 'Client secret' 478 field_secret: 'Client secret'
479 back: 'Indietro' 479 back: 'Indietro'
480 read_howto: 'Leggi howto "Come creare la mia prima applicazione"' 480 read_howto: 'Leggi "Come creare la mia prima applicazione"'
481 howto: 481 howto:
482 # page_title: 'API clients management > Come creare la mia prima applicazione' 482 # page_title: 'API clients management > Come creare la mia prima applicazione'
483 description: 483 description:
@@ -530,9 +530,9 @@ flashes:
530 password_not_updated_demo: "In modalità demo, non puoi cambiare la password dell'utente." 530 password_not_updated_demo: "In modalità demo, non puoi cambiare la password dell'utente."
531 user_updated: 'Informazioni aggiornate' 531 user_updated: 'Informazioni aggiornate'
532 rss_updated: 'Informazioni RSS aggiornate' 532 rss_updated: 'Informazioni RSS aggiornate'
533 tagging_rules_updated: 'Regole di tagging aggiornate' 533 tagging_rules_updated: 'Regole di etichettatura aggiornate'
534 tagging_rules_deleted: 'Regola di tagging aggiornate' 534 tagging_rules_deleted: 'Regole di etichettatura eliminate'
535 rss_token_updated: 'RSS token aggiornato' 535 rss_token_updated: 'Token RSS aggiornato'
536 # annotations_reset: Annotations reset 536 # annotations_reset: Annotations reset
537 # tags_reset: Tags reset 537 # tags_reset: Tags reset
538 # entries_reset: Entries reset 538 # entries_reset: Entries reset
@@ -552,7 +552,7 @@ flashes:
552 entry_deleted: 'Contenuto eliminato' 552 entry_deleted: 'Contenuto eliminato'
553 tag: 553 tag:
554 notice: 554 notice:
555 tag_added: 'Tag aggiunto' 555 tag_added: 'Etichetta aggiunta'
556 import: 556 import:
557 notice: 557 notice:
558 failed: 'Importazione fallita, riprova.' 558 failed: 'Importazione fallita, riprova.'