diff options
Diffstat (limited to 'src')
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 | |||
3 | namespace Wallabag\CoreBundle\Command; | ||
4 | |||
5 | use Doctrine\ORM\NoResultException; | ||
6 | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; | ||
7 | use Symfony\Component\Console\Input\InputArgument; | ||
8 | use Symfony\Component\Console\Input\InputInterface; | ||
9 | use Symfony\Component\Console\Output\OutputInterface; | ||
10 | use Wallabag\UserBundle\Entity\User; | ||
11 | |||
12 | class 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; | |||
6 | use Doctrine\Common\DataFixtures\OrderedFixtureInterface; | 6 | use Doctrine\Common\DataFixtures\OrderedFixtureInterface; |
7 | use Doctrine\Common\Persistence\ObjectManager; | 7 | use Doctrine\Common\Persistence\ObjectManager; |
8 | use Craue\ConfigBundle\Entity\Setting; | 8 | use Craue\ConfigBundle\Entity\Setting; |
9 | use Symfony\Component\DependencyInjection\ContainerAwareInterface; | ||
10 | use Symfony\Component\DependencyInjection\ContainerInterface; | ||
9 | 11 | ||
10 | class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface | 12 | class 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; | |||
5 | use Psr\Log\LoggerInterface; | 5 | use Psr\Log\LoggerInterface; |
6 | use Symfony\Component\DomCrawler\Crawler; | 6 | use Symfony\Component\DomCrawler\Crawler; |
7 | use GuzzleHttp\Client; | 7 | use GuzzleHttp\Client; |
8 | use GuzzleHttp\Message\Response; | ||
8 | use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser; | 9 | use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser; |
9 | use Symfony\Component\Finder\Finder; | 10 | use 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 | ||
51 | config: | 51 | config: |
@@ -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 <= 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 >= 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 <= 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 >= 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 | ||
248 | about: | 248 | about: |
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 | ||
279 | howto: | 279 | howto: |
@@ -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 | ||
385 | tag: | 385 | tag: |
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.' |