diff options
Diffstat (limited to 'src/Wallabag')
119 files changed, 3350 insertions, 422 deletions
diff --git a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php index ad083e31..c13a034f 100644 --- a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php +++ b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php | |||
@@ -3,9 +3,8 @@ | |||
3 | namespace Wallabag\AnnotationBundle\Controller; | 3 | namespace Wallabag\AnnotationBundle\Controller; |
4 | 4 | ||
5 | use FOS\RestBundle\Controller\FOSRestController; | 5 | use FOS\RestBundle\Controller\FOSRestController; |
6 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 6 | use Symfony\Component\HttpFoundation\JsonResponse; |
7 | use Symfony\Component\HttpFoundation\Request; | 7 | use Symfony\Component\HttpFoundation\Request; |
8 | use Symfony\Component\HttpFoundation\Response; | ||
9 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | 8 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; |
10 | use Wallabag\AnnotationBundle\Entity\Annotation; | 9 | use Wallabag\AnnotationBundle\Entity\Annotation; |
11 | use Wallabag\CoreBundle\Entity\Entry; | 10 | use Wallabag\CoreBundle\Entity\Entry; |
@@ -15,42 +14,35 @@ class WallabagAnnotationController extends FOSRestController | |||
15 | /** | 14 | /** |
16 | * Retrieve annotations for an entry. | 15 | * Retrieve annotations for an entry. |
17 | * | 16 | * |
18 | * @ApiDoc( | 17 | * @param Entry $entry |
19 | * requirements={ | 18 | * |
20 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | 19 | * @see Wallabag\ApiBundle\Controller\WallabagRestController |
21 | * } | ||
22 | * ) | ||
23 | * | 20 | * |
24 | * @return Response | 21 | * @return JsonResponse |
25 | */ | 22 | */ |
26 | public function getAnnotationsAction(Entry $entry) | 23 | public function getAnnotationsAction(Entry $entry) |
27 | { | 24 | { |
28 | $annotationRows = $this | 25 | $annotationRows = $this |
29 | ->getDoctrine() | 26 | ->getDoctrine() |
30 | ->getRepository('WallabagAnnotationBundle:Annotation') | 27 | ->getRepository('WallabagAnnotationBundle:Annotation') |
31 | ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); | 28 | ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); |
32 | $total = count($annotationRows); | 29 | $total = count($annotationRows); |
33 | $annotations = ['total' => $total, 'rows' => $annotationRows]; | 30 | $annotations = ['total' => $total, 'rows' => $annotationRows]; |
34 | 31 | ||
35 | $json = $this->get('serializer')->serialize($annotations, 'json'); | 32 | $json = $this->get('serializer')->serialize($annotations, 'json'); |
36 | 33 | ||
37 | return $this->renderJsonResponse($json); | 34 | return (new JsonResponse())->setJson($json); |
38 | } | 35 | } |
39 | 36 | ||
40 | /** | 37 | /** |
41 | * Creates a new annotation. | 38 | * Creates a new annotation. |
42 | * | 39 | * |
43 | * @param Entry $entry | 40 | * @param Request $request |
41 | * @param Entry $entry | ||
44 | * | 42 | * |
45 | * @ApiDoc( | 43 | * @return JsonResponse |
46 | * requirements={ | ||
47 | * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, | ||
48 | * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"}, | ||
49 | * {"name"="text", "dataType"="string", "required"=true, "description"=""}, | ||
50 | * } | ||
51 | * ) | ||
52 | * | 44 | * |
53 | * @return Response | 45 | * @see Wallabag\ApiBundle\Controller\WallabagRestController |
54 | */ | 46 | */ |
55 | public function postAnnotationAction(Request $request, Entry $entry) | 47 | public function postAnnotationAction(Request $request, Entry $entry) |
56 | { | 48 | { |
@@ -75,21 +67,20 @@ class WallabagAnnotationController extends FOSRestController | |||
75 | 67 | ||
76 | $json = $this->get('serializer')->serialize($annotation, 'json'); | 68 | $json = $this->get('serializer')->serialize($annotation, 'json'); |
77 | 69 | ||
78 | return $this->renderJsonResponse($json); | 70 | return (new JsonResponse())->setJson($json); |
79 | } | 71 | } |
80 | 72 | ||
81 | /** | 73 | /** |
82 | * Updates an annotation. | 74 | * Updates an annotation. |
83 | * | 75 | * |
84 | * @ApiDoc( | 76 | * @see Wallabag\ApiBundle\Controller\WallabagRestController |
85 | * requirements={ | ||
86 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
87 | * } | ||
88 | * ) | ||
89 | * | 77 | * |
90 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | 78 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") |
91 | * | 79 | * |
92 | * @return Response | 80 | * @param Annotation $annotation |
81 | * @param Request $request | ||
82 | * | ||
83 | * @return JsonResponse | ||
93 | */ | 84 | */ |
94 | public function putAnnotationAction(Annotation $annotation, Request $request) | 85 | public function putAnnotationAction(Annotation $annotation, Request $request) |
95 | { | 86 | { |
@@ -104,21 +95,19 @@ class WallabagAnnotationController extends FOSRestController | |||
104 | 95 | ||
105 | $json = $this->get('serializer')->serialize($annotation, 'json'); | 96 | $json = $this->get('serializer')->serialize($annotation, 'json'); |
106 | 97 | ||
107 | return $this->renderJsonResponse($json); | 98 | return (new JsonResponse())->setJson($json); |
108 | } | 99 | } |
109 | 100 | ||
110 | /** | 101 | /** |
111 | * Removes an annotation. | 102 | * Removes an annotation. |
112 | * | 103 | * |
113 | * @ApiDoc( | 104 | * @see Wallabag\ApiBundle\Controller\WallabagRestController |
114 | * requirements={ | ||
115 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
116 | * } | ||
117 | * ) | ||
118 | * | 105 | * |
119 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | 106 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") |
120 | * | 107 | * |
121 | * @return Response | 108 | * @param Annotation $annotation |
109 | * | ||
110 | * @return JsonResponse | ||
122 | */ | 111 | */ |
123 | public function deleteAnnotationAction(Annotation $annotation) | 112 | public function deleteAnnotationAction(Annotation $annotation) |
124 | { | 113 | { |
@@ -128,19 +117,6 @@ class WallabagAnnotationController extends FOSRestController | |||
128 | 117 | ||
129 | $json = $this->get('serializer')->serialize($annotation, 'json'); | 118 | $json = $this->get('serializer')->serialize($annotation, 'json'); |
130 | 119 | ||
131 | return $this->renderJsonResponse($json); | 120 | return (new JsonResponse())->setJson($json); |
132 | } | ||
133 | |||
134 | /** | ||
135 | * Send a JSON Response. | ||
136 | * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string. | ||
137 | * | ||
138 | * @param string $json | ||
139 | * | ||
140 | * @return Response | ||
141 | */ | ||
142 | private function renderJsonResponse($json, $code = 200) | ||
143 | { | ||
144 | return new Response($json, $code, ['application/json']); | ||
145 | } | 121 | } |
146 | } | 122 | } |
diff --git a/src/Wallabag/AnnotationBundle/Entity/Annotation.php b/src/Wallabag/AnnotationBundle/Entity/Annotation.php index c48d8731..0838f5aa 100644 --- a/src/Wallabag/AnnotationBundle/Entity/Annotation.php +++ b/src/Wallabag/AnnotationBundle/Entity/Annotation.php | |||
@@ -82,7 +82,7 @@ class Annotation | |||
82 | * @Exclude | 82 | * @Exclude |
83 | * | 83 | * |
84 | * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="annotations") | 84 | * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="annotations") |
85 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") | 85 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade") |
86 | */ | 86 | */ |
87 | private $entry; | 87 | private $entry; |
88 | 88 | ||
diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php index 5f7da70e..8d3f07ee 100644 --- a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php +++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php | |||
@@ -50,7 +50,8 @@ class AnnotationRepository extends EntityRepository | |||
50 | { | 50 | { |
51 | return $this->createQueryBuilder('a') | 51 | return $this->createQueryBuilder('a') |
52 | ->andWhere('a.id = :annotationId')->setParameter('annotationId', $annotationId) | 52 | ->andWhere('a.id = :annotationId')->setParameter('annotationId', $annotationId) |
53 | ->getQuery()->getSingleResult() | 53 | ->getQuery() |
54 | ->getSingleResult() | ||
54 | ; | 55 | ; |
55 | } | 56 | } |
56 | 57 | ||
@@ -67,7 +68,8 @@ class AnnotationRepository extends EntityRepository | |||
67 | return $this->createQueryBuilder('a') | 68 | return $this->createQueryBuilder('a') |
68 | ->where('a.entry = :entryId')->setParameter('entryId', $entryId) | 69 | ->where('a.entry = :entryId')->setParameter('entryId', $entryId) |
69 | ->andwhere('a.user = :userId')->setParameter('userId', $userId) | 70 | ->andwhere('a.user = :userId')->setParameter('userId', $userId) |
70 | ->getQuery()->getResult() | 71 | ->getQuery() |
72 | ->getResult() | ||
71 | ; | 73 | ; |
72 | } | 74 | } |
73 | 75 | ||
@@ -106,4 +108,18 @@ class AnnotationRepository extends EntityRepository | |||
106 | ->getQuery() | 108 | ->getQuery() |
107 | ->getSingleResult(); | 109 | ->getSingleResult(); |
108 | } | 110 | } |
111 | |||
112 | /** | ||
113 | * Remove all annotations for a user id. | ||
114 | * Used when a user want to reset all informations. | ||
115 | * | ||
116 | * @param int $userId | ||
117 | */ | ||
118 | public function removeAllByUserId($userId) | ||
119 | { | ||
120 | $this->getEntityManager() | ||
121 | ->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = :userId') | ||
122 | ->setParameter('userId', $userId) | ||
123 | ->execute(); | ||
124 | } | ||
109 | } | 125 | } |
diff --git a/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php new file mode 100644 index 00000000..2dd26c07 --- /dev/null +++ b/src/Wallabag/ApiBundle/Controller/AnnotationRestController.php | |||
@@ -0,0 +1,111 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Controller; | ||
4 | |||
5 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Symfony\Component\HttpFoundation\JsonResponse; | ||
9 | use Wallabag\CoreBundle\Entity\Entry; | ||
10 | use Wallabag\AnnotationBundle\Entity\Annotation; | ||
11 | |||
12 | class AnnotationRestController extends WallabagRestController | ||
13 | { | ||
14 | /** | ||
15 | * Retrieve annotations for an entry. | ||
16 | * | ||
17 | * @ApiDoc( | ||
18 | * requirements={ | ||
19 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | ||
20 | * } | ||
21 | * ) | ||
22 | * | ||
23 | * @param Entry $entry | ||
24 | * | ||
25 | * @return JsonResponse | ||
26 | */ | ||
27 | public function getAnnotationsAction(Entry $entry) | ||
28 | { | ||
29 | $this->validateAuthentication(); | ||
30 | |||
31 | return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:getAnnotations', [ | ||
32 | 'entry' => $entry, | ||
33 | ]); | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Creates a new annotation. | ||
38 | * | ||
39 | * @ApiDoc( | ||
40 | * requirements={ | ||
41 | * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, | ||
42 | * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"}, | ||
43 | * {"name"="text", "dataType"="string", "required"=true, "description"=""}, | ||
44 | * } | ||
45 | * ) | ||
46 | * | ||
47 | * @param Request $request | ||
48 | * @param Entry $entry | ||
49 | * | ||
50 | * @return JsonResponse | ||
51 | */ | ||
52 | public function postAnnotationAction(Request $request, Entry $entry) | ||
53 | { | ||
54 | $this->validateAuthentication(); | ||
55 | |||
56 | return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:postAnnotation', [ | ||
57 | 'request' => $request, | ||
58 | 'entry' => $entry, | ||
59 | ]); | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Updates an annotation. | ||
64 | * | ||
65 | * @ApiDoc( | ||
66 | * requirements={ | ||
67 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
68 | * } | ||
69 | * ) | ||
70 | * | ||
71 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | ||
72 | * | ||
73 | * @param Annotation $annotation | ||
74 | * @param Request $request | ||
75 | * | ||
76 | * @return JsonResponse | ||
77 | */ | ||
78 | public function putAnnotationAction(Annotation $annotation, Request $request) | ||
79 | { | ||
80 | $this->validateAuthentication(); | ||
81 | |||
82 | return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:putAnnotation', [ | ||
83 | 'annotation' => $annotation, | ||
84 | 'request' => $request, | ||
85 | ]); | ||
86 | } | ||
87 | |||
88 | /** | ||
89 | * Removes an annotation. | ||
90 | * | ||
91 | * @ApiDoc( | ||
92 | * requirements={ | ||
93 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
94 | * } | ||
95 | * ) | ||
96 | * | ||
97 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | ||
98 | * | ||
99 | * @param Annotation $annotation | ||
100 | * | ||
101 | * @return JsonResponse | ||
102 | */ | ||
103 | public function deleteAnnotationAction(Annotation $annotation) | ||
104 | { | ||
105 | $this->validateAuthentication(); | ||
106 | |||
107 | return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:deleteAnnotation', [ | ||
108 | 'annotation' => $annotation, | ||
109 | ]); | ||
110 | } | ||
111 | } | ||
diff --git a/src/Wallabag/ApiBundle/Controller/DeveloperController.php b/src/Wallabag/ApiBundle/Controller/DeveloperController.php index 5a36a260..9cb1b626 100644 --- a/src/Wallabag/ApiBundle/Controller/DeveloperController.php +++ b/src/Wallabag/ApiBundle/Controller/DeveloperController.php | |||
@@ -19,7 +19,7 @@ class DeveloperController extends Controller | |||
19 | */ | 19 | */ |
20 | public function indexAction() | 20 | public function indexAction() |
21 | { | 21 | { |
22 | $clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findAll(); | 22 | $clients = $this->getDoctrine()->getRepository('WallabagApiBundle:Client')->findByUser($this->getUser()->getId()); |
23 | 23 | ||
24 | return $this->render('@WallabagCore/themes/common/Developer/index.html.twig', [ | 24 | return $this->render('@WallabagCore/themes/common/Developer/index.html.twig', [ |
25 | 'clients' => $clients, | 25 | 'clients' => $clients, |
@@ -38,11 +38,11 @@ class DeveloperController extends Controller | |||
38 | public function createClientAction(Request $request) | 38 | public function createClientAction(Request $request) |
39 | { | 39 | { |
40 | $em = $this->getDoctrine()->getManager(); | 40 | $em = $this->getDoctrine()->getManager(); |
41 | $client = new Client(); | 41 | $client = new Client($this->getUser()); |
42 | $clientForm = $this->createForm(ClientType::class, $client); | 42 | $clientForm = $this->createForm(ClientType::class, $client); |
43 | $clientForm->handleRequest($request); | 43 | $clientForm->handleRequest($request); |
44 | 44 | ||
45 | if ($clientForm->isValid()) { | 45 | if ($clientForm->isSubmitted() && $clientForm->isValid()) { |
46 | $client->setAllowedGrantTypes(['token', 'authorization_code', 'password', 'refresh_token']); | 46 | $client->setAllowedGrantTypes(['token', 'authorization_code', 'password', 'refresh_token']); |
47 | $em->persist($client); | 47 | $em->persist($client); |
48 | $em->flush(); | 48 | $em->flush(); |
@@ -75,6 +75,10 @@ class DeveloperController extends Controller | |||
75 | */ | 75 | */ |
76 | public function deleteClientAction(Client $client) | 76 | public function deleteClientAction(Client $client) |
77 | { | 77 | { |
78 | if (null === $this->getUser() || $client->getUser()->getId() != $this->getUser()->getId()) { | ||
79 | throw $this->createAccessDeniedException('You can not access this client.'); | ||
80 | } | ||
81 | |||
78 | $em = $this->getDoctrine()->getManager(); | 82 | $em = $this->getDoctrine()->getManager(); |
79 | $em->remove($client); | 83 | $em->remove($client); |
80 | $em->flush(); | 84 | $em->flush(); |
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php index 24fa7b3b..2c2ec0c1 100644 --- a/src/Wallabag/ApiBundle/Controller/EntryRestController.php +++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php | |||
@@ -10,6 +10,8 @@ use Symfony\Component\HttpFoundation\JsonResponse; | |||
10 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | 10 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
11 | use Wallabag\CoreBundle\Entity\Entry; | 11 | use Wallabag\CoreBundle\Entity\Entry; |
12 | use Wallabag\CoreBundle\Entity\Tag; | 12 | use Wallabag\CoreBundle\Entity\Tag; |
13 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
14 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | ||
13 | 15 | ||
14 | class EntryRestController extends WallabagRestController | 16 | class EntryRestController extends WallabagRestController |
15 | { | 17 | { |
@@ -149,6 +151,28 @@ class EntryRestController extends WallabagRestController | |||
149 | } | 151 | } |
150 | 152 | ||
151 | /** | 153 | /** |
154 | * Retrieve a single entry as a predefined format. | ||
155 | * | ||
156 | * @ApiDoc( | ||
157 | * requirements={ | ||
158 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | ||
159 | * } | ||
160 | * ) | ||
161 | * | ||
162 | * @return Response | ||
163 | */ | ||
164 | public function getEntryExportAction(Entry $entry, Request $request) | ||
165 | { | ||
166 | $this->validateAuthentication(); | ||
167 | $this->validateUserAccess($entry->getUser()->getId()); | ||
168 | |||
169 | return $this->get('wallabag_core.helper.entries_export') | ||
170 | ->setEntries($entry) | ||
171 | ->updateTitle('entry') | ||
172 | ->exportAs($request->attributes->get('_format')); | ||
173 | } | ||
174 | |||
175 | /** | ||
152 | * Create an entry. | 176 | * Create an entry. |
153 | * | 177 | * |
154 | * @ApiDoc( | 178 | * @ApiDoc( |
@@ -200,9 +224,11 @@ class EntryRestController extends WallabagRestController | |||
200 | 224 | ||
201 | $em = $this->getDoctrine()->getManager(); | 225 | $em = $this->getDoctrine()->getManager(); |
202 | $em->persist($entry); | 226 | $em->persist($entry); |
203 | |||
204 | $em->flush(); | 227 | $em->flush(); |
205 | 228 | ||
229 | // entry saved, dispatch event about it! | ||
230 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
231 | |||
206 | $json = $this->get('serializer')->serialize($entry, 'json'); | 232 | $json = $this->get('serializer')->serialize($entry, 'json'); |
207 | 233 | ||
208 | return (new JsonResponse())->setJson($json); | 234 | return (new JsonResponse())->setJson($json); |
@@ -260,6 +286,51 @@ class EntryRestController extends WallabagRestController | |||
260 | } | 286 | } |
261 | 287 | ||
262 | /** | 288 | /** |
289 | * Reload an entry. | ||
290 | * An empty response with HTTP Status 304 will be send if we weren't able to update the content (because it hasn't changed or we got an error). | ||
291 | * | ||
292 | * @ApiDoc( | ||
293 | * requirements={ | ||
294 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | ||
295 | * } | ||
296 | * ) | ||
297 | * | ||
298 | * @return JsonResponse | ||
299 | */ | ||
300 | public function patchEntriesReloadAction(Entry $entry) | ||
301 | { | ||
302 | $this->validateAuthentication(); | ||
303 | $this->validateUserAccess($entry->getUser()->getId()); | ||
304 | |||
305 | try { | ||
306 | $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); | ||
307 | } catch (\Exception $e) { | ||
308 | $this->get('logger')->error('Error while saving an entry', [ | ||
309 | 'exception' => $e, | ||
310 | 'entry' => $entry, | ||
311 | ]); | ||
312 | |||
313 | return new JsonResponse([], 304); | ||
314 | } | ||
315 | |||
316 | // if refreshing entry failed, don't save it | ||
317 | if ($this->getParameter('wallabag_core.fetching_error_message') === $entry->getContent()) { | ||
318 | return new JsonResponse([], 304); | ||
319 | } | ||
320 | |||
321 | $em = $this->getDoctrine()->getManager(); | ||
322 | $em->persist($entry); | ||
323 | $em->flush(); | ||
324 | |||
325 | // entry saved, dispatch event about it! | ||
326 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
327 | |||
328 | $json = $this->get('serializer')->serialize($entry, 'json'); | ||
329 | |||
330 | return (new JsonResponse())->setJson($json); | ||
331 | } | ||
332 | |||
333 | /** | ||
263 | * Delete **permanently** an entry. | 334 | * Delete **permanently** an entry. |
264 | * | 335 | * |
265 | * @ApiDoc( | 336 | * @ApiDoc( |
@@ -279,6 +350,9 @@ class EntryRestController extends WallabagRestController | |||
279 | $em->remove($entry); | 350 | $em->remove($entry); |
280 | $em->flush(); | 351 | $em->flush(); |
281 | 352 | ||
353 | // entry deleted, dispatch event about it! | ||
354 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | ||
355 | |||
282 | $json = $this->get('serializer')->serialize($entry, 'json'); | 356 | $json = $this->get('serializer')->serialize($entry, 'json'); |
283 | 357 | ||
284 | return (new JsonResponse())->setJson($json); | 358 | return (new JsonResponse())->setJson($json); |
diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php index 4e7ddc66..bc6d4e64 100644 --- a/src/Wallabag/ApiBundle/Controller/TagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php | |||
@@ -132,22 +132,6 @@ class TagRestController extends WallabagRestController | |||
132 | } | 132 | } |
133 | 133 | ||
134 | /** | 134 | /** |
135 | * Retrieve version number. | ||
136 | * | ||
137 | * @ApiDoc() | ||
138 | * | ||
139 | * @return JsonResponse | ||
140 | */ | ||
141 | public function getVersionAction() | ||
142 | { | ||
143 | $version = $this->container->getParameter('wallabag_core.version'); | ||
144 | |||
145 | $json = $this->get('serializer')->serialize($version, 'json'); | ||
146 | |||
147 | return (new JsonResponse())->setJson($json); | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * Remove orphan tag in case no entries are associated to it. | 135 | * Remove orphan tag in case no entries are associated to it. |
152 | * | 136 | * |
153 | * @param Tag|array $tags | 137 | * @param Tag|array $tags |
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php index e927a890..b1e08ca4 100644 --- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php +++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php | |||
@@ -3,11 +3,27 @@ | |||
3 | namespace Wallabag\ApiBundle\Controller; | 3 | namespace Wallabag\ApiBundle\Controller; |
4 | 4 | ||
5 | use FOS\RestBundle\Controller\FOSRestController; | 5 | use FOS\RestBundle\Controller\FOSRestController; |
6 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
7 | use Symfony\Component\HttpFoundation\JsonResponse; | ||
6 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; | 8 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
7 | use Wallabag\CoreBundle\Entity\Entry; | ||
8 | 9 | ||
9 | class WallabagRestController extends FOSRestController | 10 | class WallabagRestController extends FOSRestController |
10 | { | 11 | { |
12 | /** | ||
13 | * Retrieve version number. | ||
14 | * | ||
15 | * @ApiDoc() | ||
16 | * | ||
17 | * @return JsonResponse | ||
18 | */ | ||
19 | public function getVersionAction() | ||
20 | { | ||
21 | $version = $this->container->getParameter('wallabag_core.version'); | ||
22 | $json = $this->get('serializer')->serialize($version, 'json'); | ||
23 | |||
24 | return (new JsonResponse())->setJson($json); | ||
25 | } | ||
26 | |||
11 | protected function validateAuthentication() | 27 | protected function validateAuthentication() |
12 | { | 28 | { |
13 | if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { | 29 | if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { |
diff --git a/src/Wallabag/ApiBundle/Entity/Client.php b/src/Wallabag/ApiBundle/Entity/Client.php index f7898ac8..9ed9f980 100644 --- a/src/Wallabag/ApiBundle/Entity/Client.php +++ b/src/Wallabag/ApiBundle/Entity/Client.php | |||
@@ -4,6 +4,7 @@ namespace Wallabag\ApiBundle\Entity; | |||
4 | 4 | ||
5 | use Doctrine\ORM\Mapping as ORM; | 5 | use Doctrine\ORM\Mapping as ORM; |
6 | use FOS\OAuthServerBundle\Entity\Client as BaseClient; | 6 | use FOS\OAuthServerBundle\Entity\Client as BaseClient; |
7 | use Wallabag\UserBundle\Entity\User; | ||
7 | 8 | ||
8 | /** | 9 | /** |
9 | * @ORM\Table("oauth2_clients") | 10 | * @ORM\Table("oauth2_clients") |
@@ -21,7 +22,7 @@ class Client extends BaseClient | |||
21 | /** | 22 | /** |
22 | * @var string | 23 | * @var string |
23 | * | 24 | * |
24 | * @ORM\Column(name="name", type="text", nullable=true) | 25 | * @ORM\Column(name="name", type="text", nullable=false) |
25 | */ | 26 | */ |
26 | protected $name; | 27 | protected $name; |
27 | 28 | ||
@@ -35,9 +36,15 @@ class Client extends BaseClient | |||
35 | */ | 36 | */ |
36 | protected $accessTokens; | 37 | protected $accessTokens; |
37 | 38 | ||
38 | public function __construct() | 39 | /** |
40 | * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="clients") | ||
41 | */ | ||
42 | private $user; | ||
43 | |||
44 | public function __construct(User $user) | ||
39 | { | 45 | { |
40 | parent::__construct(); | 46 | parent::__construct(); |
47 | $this->user = $user; | ||
41 | } | 48 | } |
42 | 49 | ||
43 | /** | 50 | /** |
@@ -63,4 +70,12 @@ class Client extends BaseClient | |||
63 | 70 | ||
64 | return $this; | 71 | return $this; |
65 | } | 72 | } |
73 | |||
74 | /** | ||
75 | * @return User | ||
76 | */ | ||
77 | public function getUser() | ||
78 | { | ||
79 | return $this->user; | ||
80 | } | ||
66 | } | 81 | } |
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing.yml b/src/Wallabag/ApiBundle/Resources/config/routing.yml deleted file mode 100644 index e69de29b..00000000 --- a/src/Wallabag/ApiBundle/Resources/config/routing.yml +++ /dev/null | |||
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml index c1af9e02..57d37f4b 100644 --- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml +++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml | |||
@@ -1,9 +1,19 @@ | |||
1 | entries: | 1 | entry: |
2 | type: rest | 2 | type: rest |
3 | resource: "WallabagApiBundle:EntryRest" | 3 | resource: "WallabagApiBundle:EntryRest" |
4 | name_prefix: api_ | 4 | name_prefix: api_ |
5 | 5 | ||
6 | tags: | 6 | tag: |
7 | type: rest | 7 | type: rest |
8 | resource: "WallabagApiBundle:TagRest" | 8 | resource: "WallabagApiBundle:TagRest" |
9 | name_prefix: api_ | ||
10 | |||
11 | annotation: | ||
12 | type: rest | ||
13 | resource: "WallabagApiBundle:AnnotationRest" | ||
14 | name_prefix: api_ | ||
15 | |||
16 | misc: | ||
17 | type: rest | ||
18 | resource: "WallabagApiBundle:WallabagRest" | ||
9 | name_prefix: api_ | 19 | name_prefix: api_ |
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index 2daf2dd8..f0738b91 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php | |||
@@ -40,7 +40,7 @@ class InstallCommand extends ContainerAwareCommand | |||
40 | { | 40 | { |
41 | $this | 41 | $this |
42 | ->setName('wallabag:install') | 42 | ->setName('wallabag:install') |
43 | ->setDescription('Wallabag installer.') | 43 | ->setDescription('wallabag installer.') |
44 | ->addOption( | 44 | ->addOption( |
45 | 'reset', | 45 | 'reset', |
46 | null, | 46 | null, |
@@ -55,7 +55,7 @@ class InstallCommand extends ContainerAwareCommand | |||
55 | $this->defaultInput = $input; | 55 | $this->defaultInput = $input; |
56 | $this->defaultOutput = $output; | 56 | $this->defaultOutput = $output; |
57 | 57 | ||
58 | $output->writeln('<info>Installing Wallabag...</info>'); | 58 | $output->writeln('<info>Installing wallabag...</info>'); |
59 | $output->writeln(''); | 59 | $output->writeln(''); |
60 | 60 | ||
61 | $this | 61 | $this |
@@ -65,7 +65,7 @@ class InstallCommand extends ContainerAwareCommand | |||
65 | ->setupConfig() | 65 | ->setupConfig() |
66 | ; | 66 | ; |
67 | 67 | ||
68 | $output->writeln('<info>Wallabag has been successfully installed.</info>'); | 68 | $output->writeln('<info>wallabag has been successfully installed.</info>'); |
69 | $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); | 69 | $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>'); |
70 | } | 70 | } |
71 | 71 | ||
@@ -78,7 +78,7 @@ class InstallCommand extends ContainerAwareCommand | |||
78 | 78 | ||
79 | // testing if database driver exists | 79 | // testing if database driver exists |
80 | $fulfilled = true; | 80 | $fulfilled = true; |
81 | $label = '<comment>PDO Driver</comment>'; | 81 | $label = '<comment>PDO Driver (%s)</comment>'; |
82 | $status = '<info>OK!</info>'; | 82 | $status = '<info>OK!</info>'; |
83 | $help = ''; | 83 | $help = ''; |
84 | 84 | ||
@@ -88,7 +88,7 @@ class InstallCommand extends ContainerAwareCommand | |||
88 | $help = 'Database driver "'.$this->getContainer()->getParameter('database_driver').'" is not installed.'; | 88 | $help = 'Database driver "'.$this->getContainer()->getParameter('database_driver').'" is not installed.'; |
89 | } | 89 | } |
90 | 90 | ||
91 | $rows[] = [$label, $status, $help]; | 91 | $rows[] = [sprintf($label, $this->getContainer()->getParameter('database_driver')), $status, $help]; |
92 | 92 | ||
93 | // testing if connection to the database can be etablished | 93 | // testing if connection to the database can be etablished |
94 | $label = '<comment>Database connection</comment>'; | 94 | $label = '<comment>Database connection</comment>'; |
@@ -96,7 +96,8 @@ class InstallCommand extends ContainerAwareCommand | |||
96 | $help = ''; | 96 | $help = ''; |
97 | 97 | ||
98 | try { | 98 | try { |
99 | $doctrineManager->getConnection()->connect(); | 99 | $conn = $this->getContainer()->get('doctrine')->getManager()->getConnection(); |
100 | $conn->connect(); | ||
100 | } catch (\Exception $e) { | 101 | } catch (\Exception $e) { |
101 | if (false === strpos($e->getMessage(), 'Unknown database') | 102 | if (false === strpos($e->getMessage(), 'Unknown database') |
102 | && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) { | 103 | && false === strpos($e->getMessage(), 'database "'.$this->getContainer()->getParameter('database_name').'" does not exist')) { |
@@ -108,12 +109,25 @@ class InstallCommand extends ContainerAwareCommand | |||
108 | 109 | ||
109 | $rows[] = [$label, $status, $help]; | 110 | $rows[] = [$label, $status, $help]; |
110 | 111 | ||
111 | // testing if PostgreSQL > 9.1 | 112 | // check MySQL & PostgreSQL version |
112 | $label = '<comment>SGBD version</comment>'; | 113 | $label = '<comment>Database version</comment>'; |
113 | $status = '<info>OK!</info>'; | 114 | $status = '<info>OK!</info>'; |
114 | $help = ''; | 115 | $help = ''; |
115 | 116 | ||
116 | if ('postgresql' === $doctrineManager->getConnection()->getSchemaManager()->getDatabasePlatform()->getName()) { | 117 | // now check if MySQL isn't too old to handle utf8mb4 |
118 | if ($conn->isConnected() && 'mysql' === $conn->getDatabasePlatform()->getName()) { | ||
119 | $version = $conn->query('select version()')->fetchColumn(); | ||
120 | $minimalVersion = '5.5.4'; | ||
121 | |||
122 | if (false === version_compare($version, $minimalVersion, '>')) { | ||
123 | $fulfilled = false; | ||
124 | $status = '<error>ERROR!</error>'; | ||
125 | $help = 'Your MySQL version ('.$version.') is too old, consider upgrading ('.$minimalVersion.'+).'; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | // testing if PostgreSQL > 9.1 | ||
130 | if ($conn->isConnected() && 'postgresql' === $conn->getDatabasePlatform()->getName()) { | ||
117 | // return version should be like "PostgreSQL 9.5.4 on x86_64-apple-darwin15.6.0, compiled by Apple LLVM version 8.0.0 (clang-800.0.38), 64-bit" | 131 | // return version should be like "PostgreSQL 9.5.4 on x86_64-apple-darwin15.6.0, compiled by Apple LLVM version 8.0.0 (clang-800.0.38), 64-bit" |
118 | $version = $doctrineManager->getConnection()->query('SELECT version();')->fetchColumn(); | 132 | $version = $doctrineManager->getConnection()->query('SELECT version();')->fetchColumn(); |
119 | 133 | ||
@@ -152,7 +166,7 @@ class InstallCommand extends ContainerAwareCommand | |||
152 | throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); | 166 | throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); |
153 | } | 167 | } |
154 | 168 | ||
155 | $this->defaultOutput->writeln('<info>Success! Your system can run Wallabag properly.</info>'); | 169 | $this->defaultOutput->writeln('<info>Success! Your system can run wallabag properly.</info>'); |
156 | 170 | ||
157 | $this->defaultOutput->writeln(''); | 171 | $this->defaultOutput->writeln(''); |
158 | 172 | ||
@@ -299,6 +313,16 @@ class InstallCommand extends ContainerAwareCommand | |||
299 | 'section' => 'entry', | 313 | 'section' => 'entry', |
300 | ], | 314 | ], |
301 | [ | 315 | [ |
316 | 'name' => 'share_unmark', | ||
317 | 'value' => '1', | ||
318 | 'section' => 'entry', | ||
319 | ], | ||
320 | [ | ||
321 | 'name' => 'unmark_url', | ||
322 | 'value' => 'https://unmark.it', | ||
323 | 'section' => 'entry', | ||
324 | ], | ||
325 | [ | ||
302 | 'name' => 'share_shaarli', | 326 | 'name' => 'share_shaarli', |
303 | 'value' => '1', | 327 | 'value' => '1', |
304 | 'section' => 'entry', | 328 | 'section' => 'entry', |
@@ -375,7 +399,7 @@ class InstallCommand extends ContainerAwareCommand | |||
375 | ], | 399 | ], |
376 | [ | 400 | [ |
377 | 'name' => 'wallabag_url', | 401 | 'name' => 'wallabag_url', |
378 | 'value' => 'http://v2.wallabag.org', | 402 | 'value' => '', |
379 | 'section' => 'misc', | 403 | 'section' => 'misc', |
380 | ], | 404 | ], |
381 | [ | 405 | [ |
@@ -403,6 +427,16 @@ class InstallCommand extends ContainerAwareCommand | |||
403 | 'value' => 'wallabag', | 427 | 'value' => 'wallabag', |
404 | 'section' => 'misc', | 428 | 'section' => 'misc', |
405 | ], | 429 | ], |
430 | [ | ||
431 | 'name' => 'download_images_enabled', | ||
432 | 'value' => '0', | ||
433 | 'section' => 'misc', | ||
434 | ], | ||
435 | [ | ||
436 | 'name' => 'restricted_access', | ||
437 | 'value' => '0', | ||
438 | 'section' => 'entry', | ||
439 | ], | ||
406 | ]; | 440 | ]; |
407 | 441 | ||
408 | foreach ($settings as $setting) { | 442 | foreach ($settings as $setting) { |
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index 46fb9503..907bf78e 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php | |||
@@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |||
7 | use Symfony\Component\HttpFoundation\JsonResponse; | 7 | use Symfony\Component\HttpFoundation\JsonResponse; |
8 | use Symfony\Component\HttpFoundation\RedirectResponse; | 8 | use Symfony\Component\HttpFoundation\RedirectResponse; |
9 | use Symfony\Component\HttpFoundation\Request; | 9 | use Symfony\Component\HttpFoundation\Request; |
10 | use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | ||
10 | use Wallabag\CoreBundle\Entity\Config; | 11 | use Wallabag\CoreBundle\Entity\Config; |
11 | use Wallabag\CoreBundle\Entity\TaggingRule; | 12 | use Wallabag\CoreBundle\Entity\TaggingRule; |
12 | use Wallabag\CoreBundle\Form\Type\ConfigType; | 13 | use Wallabag\CoreBundle\Form\Type\ConfigType; |
@@ -34,7 +35,7 @@ class ConfigController extends Controller | |||
34 | $configForm = $this->createForm(ConfigType::class, $config, ['action' => $this->generateUrl('config')]); | 35 | $configForm = $this->createForm(ConfigType::class, $config, ['action' => $this->generateUrl('config')]); |
35 | $configForm->handleRequest($request); | 36 | $configForm->handleRequest($request); |
36 | 37 | ||
37 | if ($configForm->isValid()) { | 38 | if ($configForm->isSubmitted() && $configForm->isValid()) { |
38 | $em->persist($config); | 39 | $em->persist($config); |
39 | $em->flush(); | 40 | $em->flush(); |
40 | 41 | ||
@@ -56,7 +57,7 @@ class ConfigController extends Controller | |||
56 | $pwdForm = $this->createForm(ChangePasswordType::class, null, ['action' => $this->generateUrl('config').'#set4']); | 57 | $pwdForm = $this->createForm(ChangePasswordType::class, null, ['action' => $this->generateUrl('config').'#set4']); |
57 | $pwdForm->handleRequest($request); | 58 | $pwdForm->handleRequest($request); |
58 | 59 | ||
59 | if ($pwdForm->isValid()) { | 60 | if ($pwdForm->isSubmitted() && $pwdForm->isValid()) { |
60 | if ($this->get('craue_config')->get('demo_mode_enabled') && $this->get('craue_config')->get('demo_mode_username') === $user->getUsername()) { | 61 | if ($this->get('craue_config')->get('demo_mode_enabled') && $this->get('craue_config')->get('demo_mode_username') === $user->getUsername()) { |
61 | $message = 'flashes.config.notice.password_not_updated_demo'; | 62 | $message = 'flashes.config.notice.password_not_updated_demo'; |
62 | } else { | 63 | } else { |
@@ -78,7 +79,7 @@ class ConfigController extends Controller | |||
78 | ]); | 79 | ]); |
79 | $userForm->handleRequest($request); | 80 | $userForm->handleRequest($request); |
80 | 81 | ||
81 | if ($userForm->isValid()) { | 82 | if ($userForm->isSubmitted() && $userForm->isValid()) { |
82 | $userManager->updateUser($user, true); | 83 | $userManager->updateUser($user, true); |
83 | 84 | ||
84 | $this->get('session')->getFlashBag()->add( | 85 | $this->get('session')->getFlashBag()->add( |
@@ -93,7 +94,7 @@ class ConfigController extends Controller | |||
93 | $rssForm = $this->createForm(RssType::class, $config, ['action' => $this->generateUrl('config').'#set2']); | 94 | $rssForm = $this->createForm(RssType::class, $config, ['action' => $this->generateUrl('config').'#set2']); |
94 | $rssForm->handleRequest($request); | 95 | $rssForm->handleRequest($request); |
95 | 96 | ||
96 | if ($rssForm->isValid()) { | 97 | if ($rssForm->isSubmitted() && $rssForm->isValid()) { |
97 | $em->persist($config); | 98 | $em->persist($config); |
98 | $em->flush(); | 99 | $em->flush(); |
99 | 100 | ||
@@ -124,7 +125,7 @@ class ConfigController extends Controller | |||
124 | $newTaggingRule = $this->createForm(TaggingRuleType::class, $taggingRule, ['action' => $action]); | 125 | $newTaggingRule = $this->createForm(TaggingRuleType::class, $taggingRule, ['action' => $action]); |
125 | $newTaggingRule->handleRequest($request); | 126 | $newTaggingRule->handleRequest($request); |
126 | 127 | ||
127 | if ($newTaggingRule->isValid()) { | 128 | if ($newTaggingRule->isSubmitted() && $newTaggingRule->isValid()) { |
128 | $taggingRule->setConfig($config); | 129 | $taggingRule->setConfig($config); |
129 | $em->persist($taggingRule); | 130 | $em->persist($taggingRule); |
130 | $em->flush(); | 131 | $em->flush(); |
@@ -150,6 +151,10 @@ class ConfigController extends Controller | |||
150 | 'token' => $config->getRssToken(), | 151 | 'token' => $config->getRssToken(), |
151 | ], | 152 | ], |
152 | 'twofactor_auth' => $this->getParameter('twofactor_auth'), | 153 | 'twofactor_auth' => $this->getParameter('twofactor_auth'), |
154 | 'wallabag_url' => $this->get('craue_config')->get('wallabag_url'), | ||
155 | 'enabled_users' => $this->getDoctrine() | ||
156 | ->getRepository('WallabagUserBundle:User') | ||
157 | ->getSumEnabledUsers(), | ||
153 | ]); | 158 | ]); |
154 | } | 159 | } |
155 | 160 | ||
@@ -223,6 +228,78 @@ class ConfigController extends Controller | |||
223 | } | 228 | } |
224 | 229 | ||
225 | /** | 230 | /** |
231 | * Remove all annotations OR tags OR entries for the current user. | ||
232 | * | ||
233 | * @Route("/reset/{type}", requirements={"id" = "annotations|tags|entries"}, name="config_reset") | ||
234 | * | ||
235 | * @return RedirectResponse | ||
236 | */ | ||
237 | public function resetAction($type) | ||
238 | { | ||
239 | switch ($type) { | ||
240 | case 'annotations': | ||
241 | $this->getDoctrine() | ||
242 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
243 | ->removeAllByUserId($this->getUser()->getId()); | ||
244 | break; | ||
245 | |||
246 | case 'tags': | ||
247 | $this->removeAllTagsByUserId($this->getUser()->getId()); | ||
248 | break; | ||
249 | |||
250 | case 'entries': | ||
251 | // SQLite doesn't care about cascading remove, so we need to manually remove associated stuf | ||
252 | // otherwise they won't be removed ... | ||
253 | if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) { | ||
254 | $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId()); | ||
255 | } | ||
256 | |||
257 | // manually remove tags to avoid orphan tag | ||
258 | $this->removeAllTagsByUserId($this->getUser()->getId()); | ||
259 | |||
260 | $this->getDoctrine() | ||
261 | ->getRepository('WallabagCoreBundle:Entry') | ||
262 | ->removeAllByUserId($this->getUser()->getId()); | ||
263 | } | ||
264 | |||
265 | $this->get('session')->getFlashBag()->add( | ||
266 | 'notice', | ||
267 | 'flashes.config.notice.'.$type.'_reset' | ||
268 | ); | ||
269 | |||
270 | return $this->redirect($this->generateUrl('config').'#set3'); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * Remove all tags for a given user and cleanup orphan tags. | ||
275 | * | ||
276 | * @param int $userId | ||
277 | */ | ||
278 | private function removeAllTagsByUserId($userId) | ||
279 | { | ||
280 | $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId); | ||
281 | |||
282 | if (empty($tags)) { | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | $this->getDoctrine() | ||
287 | ->getRepository('WallabagCoreBundle:Entry') | ||
288 | ->removeTags($userId, $tags); | ||
289 | |||
290 | // cleanup orphan tags | ||
291 | $em = $this->getDoctrine()->getManager(); | ||
292 | |||
293 | foreach ($tags as $tag) { | ||
294 | if (count($tag->getEntries()) === 0) { | ||
295 | $em->remove($tag); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | $em->flush(); | ||
300 | } | ||
301 | |||
302 | /** | ||
226 | * Validate that a rule can be edited/deleted by the current user. | 303 | * Validate that a rule can be edited/deleted by the current user. |
227 | * | 304 | * |
228 | * @param TaggingRule $rule | 305 | * @param TaggingRule $rule |
@@ -253,4 +330,58 @@ class ConfigController extends Controller | |||
253 | 330 | ||
254 | return $config; | 331 | return $config; |
255 | } | 332 | } |
333 | |||
334 | /** | ||
335 | * Delete account for current user. | ||
336 | * | ||
337 | * @Route("/account/delete", name="delete_account") | ||
338 | * | ||
339 | * @param Request $request | ||
340 | * | ||
341 | * @throws AccessDeniedHttpException | ||
342 | * | ||
343 | * @return \Symfony\Component\HttpFoundation\RedirectResponse | ||
344 | */ | ||
345 | public function deleteAccountAction(Request $request) | ||
346 | { | ||
347 | $enabledUsers = $this->getDoctrine() | ||
348 | ->getRepository('WallabagUserBundle:User') | ||
349 | ->getSumEnabledUsers(); | ||
350 | |||
351 | if ($enabledUsers <= 1) { | ||
352 | throw new AccessDeniedHttpException(); | ||
353 | } | ||
354 | |||
355 | $user = $this->getUser(); | ||
356 | |||
357 | // logout current user | ||
358 | $this->get('security.token_storage')->setToken(null); | ||
359 | $request->getSession()->invalidate(); | ||
360 | |||
361 | $em = $this->get('fos_user.user_manager'); | ||
362 | $em->deleteUser($user); | ||
363 | |||
364 | return $this->redirect($this->generateUrl('fos_user_security_login')); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Switch view mode for current user. | ||
369 | * | ||
370 | * @Route("/config/view-mode", name="switch_view_mode") | ||
371 | * | ||
372 | * @param Request $request | ||
373 | * | ||
374 | * @return \Symfony\Component\HttpFoundation\RedirectResponse | ||
375 | */ | ||
376 | public function changeViewModeAction(Request $request) | ||
377 | { | ||
378 | $user = $this->getUser(); | ||
379 | $user->getConfig()->setListMode(!$user->getConfig()->getListMode()); | ||
380 | |||
381 | $em = $this->getDoctrine()->getManager(); | ||
382 | $em->persist($user); | ||
383 | $em->flush(); | ||
384 | |||
385 | return $this->redirect($request->headers->get('referer')); | ||
386 | } | ||
256 | } | 387 | } |
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php index 97bb3d12..f7398e69 100644 --- a/src/Wallabag/CoreBundle/Controller/EntryController.php +++ b/src/Wallabag/CoreBundle/Controller/EntryController.php | |||
@@ -13,10 +13,45 @@ use Wallabag\CoreBundle\Form\Type\EntryFilterType; | |||
13 | use Wallabag\CoreBundle\Form\Type\EditEntryType; | 13 | use Wallabag\CoreBundle\Form\Type\EditEntryType; |
14 | use Wallabag\CoreBundle\Form\Type\NewEntryType; | 14 | use Wallabag\CoreBundle\Form\Type\NewEntryType; |
15 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; | 15 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; |
16 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
17 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | ||
18 | use Wallabag\CoreBundle\Form\Type\SearchEntryType; | ||
16 | 19 | ||
17 | class EntryController extends Controller | 20 | class EntryController extends Controller |
18 | { | 21 | { |
19 | /** | 22 | /** |
23 | * @param Request $request | ||
24 | * @param int $page | ||
25 | * | ||
26 | * @Route("/search/{page}", name="search", defaults={"page" = 1}) | ||
27 | * | ||
28 | * Default parameter for page is hardcoded (in duplication of the defaults from the Route) | ||
29 | * because this controller is also called inside the layout template without any page as argument | ||
30 | * | ||
31 | * @return \Symfony\Component\HttpFoundation\Response | ||
32 | */ | ||
33 | public function searchFormAction(Request $request, $page = 1, $currentRoute = null) | ||
34 | { | ||
35 | // fallback to retrieve currentRoute from query parameter instead of injected one (when using inside a template) | ||
36 | if (null === $currentRoute && $request->query->has('currentRoute')) { | ||
37 | $currentRoute = $request->query->get('currentRoute'); | ||
38 | } | ||
39 | |||
40 | $form = $this->createForm(SearchEntryType::class); | ||
41 | |||
42 | $form->handleRequest($request); | ||
43 | |||
44 | if ($form->isSubmitted() && $form->isValid()) { | ||
45 | return $this->showEntries('search', $request, $page); | ||
46 | } | ||
47 | |||
48 | return $this->render('WallabagCoreBundle:Entry:search_form.html.twig', [ | ||
49 | 'form' => $form->createView(), | ||
50 | 'currentRoute' => $currentRoute, | ||
51 | ]); | ||
52 | } | ||
53 | |||
54 | /** | ||
20 | * Fetch content and update entry. | 55 | * Fetch content and update entry. |
21 | * In case it fails, entry will return to avod loosing the data. | 56 | * In case it fails, entry will return to avod loosing the data. |
22 | * | 57 | * |
@@ -63,7 +98,7 @@ class EntryController extends Controller | |||
63 | 98 | ||
64 | $form->handleRequest($request); | 99 | $form->handleRequest($request); |
65 | 100 | ||
66 | if ($form->isValid()) { | 101 | if ($form->isSubmitted() && $form->isValid()) { |
67 | $existingEntry = $this->checkIfEntryAlreadyExists($entry); | 102 | $existingEntry = $this->checkIfEntryAlreadyExists($entry); |
68 | 103 | ||
69 | if (false !== $existingEntry) { | 104 | if (false !== $existingEntry) { |
@@ -81,6 +116,9 @@ class EntryController extends Controller | |||
81 | $em->persist($entry); | 116 | $em->persist($entry); |
82 | $em->flush(); | 117 | $em->flush(); |
83 | 118 | ||
119 | // entry saved, dispatch event about it! | ||
120 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
121 | |||
84 | return $this->redirect($this->generateUrl('homepage')); | 122 | return $this->redirect($this->generateUrl('homepage')); |
85 | } | 123 | } |
86 | 124 | ||
@@ -107,6 +145,9 @@ class EntryController extends Controller | |||
107 | $em = $this->getDoctrine()->getManager(); | 145 | $em = $this->getDoctrine()->getManager(); |
108 | $em->persist($entry); | 146 | $em->persist($entry); |
109 | $em->flush(); | 147 | $em->flush(); |
148 | |||
149 | // entry saved, dispatch event about it! | ||
150 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
110 | } | 151 | } |
111 | 152 | ||
112 | return $this->redirect($this->generateUrl('homepage')); | 153 | return $this->redirect($this->generateUrl('homepage')); |
@@ -140,7 +181,7 @@ class EntryController extends Controller | |||
140 | 181 | ||
141 | $form->handleRequest($request); | 182 | $form->handleRequest($request); |
142 | 183 | ||
143 | if ($form->isValid()) { | 184 | if ($form->isSubmitted() && $form->isValid()) { |
144 | $em = $this->getDoctrine()->getManager(); | 185 | $em = $this->getDoctrine()->getManager(); |
145 | $em->persist($entry); | 186 | $em->persist($entry); |
146 | $em->flush(); | 187 | $em->flush(); |
@@ -236,8 +277,14 @@ class EntryController extends Controller | |||
236 | private function showEntries($type, Request $request, $page) | 277 | private function showEntries($type, Request $request, $page) |
237 | { | 278 | { |
238 | $repository = $this->get('wallabag_core.entry_repository'); | 279 | $repository = $this->get('wallabag_core.entry_repository'); |
280 | $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : ''); | ||
281 | $currentRoute = (!is_null($request->query->get('currentRoute')) ? $request->query->get('currentRoute') : ''); | ||
239 | 282 | ||
240 | switch ($type) { | 283 | switch ($type) { |
284 | case 'search': | ||
285 | $qb = $repository->getBuilderForSearchByUser($this->getUser()->getId(), $searchTerm, $currentRoute); | ||
286 | |||
287 | break; | ||
241 | case 'untagged': | 288 | case 'untagged': |
242 | $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId()); | 289 | $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId()); |
243 | 290 | ||
@@ -272,7 +319,7 @@ class EntryController extends Controller | |||
272 | $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb); | 319 | $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb); |
273 | } | 320 | } |
274 | 321 | ||
275 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery()); | 322 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); |
276 | 323 | ||
277 | $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries') | 324 | $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries') |
278 | ->prepare($pagerAdapter, $page); | 325 | ->prepare($pagerAdapter, $page); |
@@ -286,11 +333,11 @@ class EntryController extends Controller | |||
286 | } | 333 | } |
287 | 334 | ||
288 | return $this->render( | 335 | return $this->render( |
289 | 'WallabagCoreBundle:Entry:entries.html.twig', | 336 | 'WallabagCoreBundle:Entry:entries.html.twig', [ |
290 | [ | ||
291 | 'form' => $form->createView(), | 337 | 'form' => $form->createView(), |
292 | 'entries' => $entries, | 338 | 'entries' => $entries, |
293 | 'currentPage' => $page, | 339 | 'currentPage' => $page, |
340 | 'searchTerm' => $searchTerm, | ||
294 | ] | 341 | ] |
295 | ); | 342 | ); |
296 | } | 343 | } |
@@ -343,6 +390,9 @@ class EntryController extends Controller | |||
343 | $em->persist($entry); | 390 | $em->persist($entry); |
344 | $em->flush(); | 391 | $em->flush(); |
345 | 392 | ||
393 | // entry saved, dispatch event about it! | ||
394 | $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
395 | |||
346 | return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); | 396 | return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()])); |
347 | } | 397 | } |
348 | 398 | ||
@@ -431,6 +481,9 @@ class EntryController extends Controller | |||
431 | UrlGeneratorInterface::ABSOLUTE_PATH | 481 | UrlGeneratorInterface::ABSOLUTE_PATH |
432 | ); | 482 | ); |
433 | 483 | ||
484 | // entry deleted, dispatch event about it! | ||
485 | $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry)); | ||
486 | |||
434 | $em = $this->getDoctrine()->getManager(); | 487 | $em = $this->getDoctrine()->getManager(); |
435 | $em->remove($entry); | 488 | $em->remove($entry); |
436 | $em->flush(); | 489 | $em->flush(); |
@@ -486,8 +539,8 @@ class EntryController extends Controller | |||
486 | { | 539 | { |
487 | $this->checkUserAction($entry); | 540 | $this->checkUserAction($entry); |
488 | 541 | ||
489 | if (null === $entry->getUuid()) { | 542 | if (null === $entry->getUid()) { |
490 | $entry->generateUuid(); | 543 | $entry->generateUid(); |
491 | 544 | ||
492 | $em = $this->getDoctrine()->getManager(); | 545 | $em = $this->getDoctrine()->getManager(); |
493 | $em->persist($entry); | 546 | $em->persist($entry); |
@@ -495,7 +548,7 @@ class EntryController extends Controller | |||
495 | } | 548 | } |
496 | 549 | ||
497 | return $this->redirect($this->generateUrl('share_entry', [ | 550 | return $this->redirect($this->generateUrl('share_entry', [ |
498 | 'uuid' => $entry->getUuid(), | 551 | 'uid' => $entry->getUid(), |
499 | ])); | 552 | ])); |
500 | } | 553 | } |
501 | 554 | ||
@@ -512,7 +565,7 @@ class EntryController extends Controller | |||
512 | { | 565 | { |
513 | $this->checkUserAction($entry); | 566 | $this->checkUserAction($entry); |
514 | 567 | ||
515 | $entry->cleanUuid(); | 568 | $entry->cleanUid(); |
516 | 569 | ||
517 | $em = $this->getDoctrine()->getManager(); | 570 | $em = $this->getDoctrine()->getManager(); |
518 | $em->persist($entry); | 571 | $em->persist($entry); |
@@ -528,7 +581,7 @@ class EntryController extends Controller | |||
528 | * | 581 | * |
529 | * @param Entry $entry | 582 | * @param Entry $entry |
530 | * | 583 | * |
531 | * @Route("/share/{uuid}", requirements={"uuid" = ".+"}, name="share_entry") | 584 | * @Route("/share/{uid}", requirements={"uid" = ".+"}, name="share_entry") |
532 | * @Cache(maxage="25200", smaxage="25200", public=true) | 585 | * @Cache(maxage="25200", smaxage="25200", public=true) |
533 | * | 586 | * |
534 | * @return \Symfony\Component\HttpFoundation\Response | 587 | * @return \Symfony\Component\HttpFoundation\Response |
diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php index 79653cfe..abc3336a 100644 --- a/src/Wallabag/CoreBundle/Controller/ExportController.php +++ b/src/Wallabag/CoreBundle/Controller/ExportController.php | |||
@@ -48,7 +48,7 @@ class ExportController extends Controller | |||
48 | * | 48 | * |
49 | * @Route("/export/{category}.{format}", name="export_entries", requirements={ | 49 | * @Route("/export/{category}.{format}", name="export_entries", requirements={ |
50 | * "format": "epub|mobi|pdf|json|xml|txt|csv", | 50 | * "format": "epub|mobi|pdf|json|xml|txt|csv", |
51 | * "category": "all|unread|starred|archive|tag_entries|untagged" | 51 | * "category": "all|unread|starred|archive|tag_entries|untagged|search" |
52 | * }) | 52 | * }) |
53 | * | 53 | * |
54 | * @return \Symfony\Component\HttpFoundation\Response | 54 | * @return \Symfony\Component\HttpFoundation\Response |
diff --git a/src/Wallabag/CoreBundle/Controller/RssController.php b/src/Wallabag/CoreBundle/Controller/RssController.php index 38e3b5a0..92f18707 100644 --- a/src/Wallabag/CoreBundle/Controller/RssController.php +++ b/src/Wallabag/CoreBundle/Controller/RssController.php | |||
@@ -3,12 +3,15 @@ | |||
3 | namespace Wallabag\CoreBundle\Controller; | 3 | namespace Wallabag\CoreBundle\Controller; |
4 | 4 | ||
5 | use Pagerfanta\Adapter\DoctrineORMAdapter; | 5 | use Pagerfanta\Adapter\DoctrineORMAdapter; |
6 | use Pagerfanta\Exception\OutOfRangeCurrentPageException; | ||
6 | use Pagerfanta\Pagerfanta; | 7 | use Pagerfanta\Pagerfanta; |
7 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | 8 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; |
8 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | 9 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
10 | use Symfony\Component\HttpFoundation\Request; | ||
9 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | 11 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
10 | use Wallabag\CoreBundle\Entity\Entry; | 12 | use Wallabag\CoreBundle\Entity\Entry; |
11 | use Wallabag\UserBundle\Entity\User; | 13 | use Wallabag\UserBundle\Entity\User; |
14 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
12 | 15 | ||
13 | class RssController extends Controller | 16 | class RssController extends Controller |
14 | { | 17 | { |
@@ -20,9 +23,9 @@ class RssController extends Controller | |||
20 | * | 23 | * |
21 | * @return \Symfony\Component\HttpFoundation\Response | 24 | * @return \Symfony\Component\HttpFoundation\Response |
22 | */ | 25 | */ |
23 | public function showUnreadAction(User $user) | 26 | public function showUnreadAction(Request $request, User $user) |
24 | { | 27 | { |
25 | return $this->showEntries('unread', $user); | 28 | return $this->showEntries('unread', $user, $request->query->get('page', 1)); |
26 | } | 29 | } |
27 | 30 | ||
28 | /** | 31 | /** |
@@ -33,9 +36,9 @@ class RssController extends Controller | |||
33 | * | 36 | * |
34 | * @return \Symfony\Component\HttpFoundation\Response | 37 | * @return \Symfony\Component\HttpFoundation\Response |
35 | */ | 38 | */ |
36 | public function showArchiveAction(User $user) | 39 | public function showArchiveAction(Request $request, User $user) |
37 | { | 40 | { |
38 | return $this->showEntries('archive', $user); | 41 | return $this->showEntries('archive', $user, $request->query->get('page', 1)); |
39 | } | 42 | } |
40 | 43 | ||
41 | /** | 44 | /** |
@@ -46,9 +49,9 @@ class RssController extends Controller | |||
46 | * | 49 | * |
47 | * @return \Symfony\Component\HttpFoundation\Response | 50 | * @return \Symfony\Component\HttpFoundation\Response |
48 | */ | 51 | */ |
49 | public function showStarredAction(User $user) | 52 | public function showStarredAction(Request $request, User $user) |
50 | { | 53 | { |
51 | return $this->showEntries('starred', $user); | 54 | return $this->showEntries('starred', $user, $request->query->get('page', 1)); |
52 | } | 55 | } |
53 | 56 | ||
54 | /** | 57 | /** |
@@ -57,10 +60,11 @@ class RssController extends Controller | |||
57 | * | 60 | * |
58 | * @param string $type Entries type: unread, starred or archive | 61 | * @param string $type Entries type: unread, starred or archive |
59 | * @param User $user | 62 | * @param User $user |
63 | * @param int $page | ||
60 | * | 64 | * |
61 | * @return \Symfony\Component\HttpFoundation\Response | 65 | * @return \Symfony\Component\HttpFoundation\Response |
62 | */ | 66 | */ |
63 | private function showEntries($type, User $user) | 67 | private function showEntries($type, User $user, $page = 1) |
64 | { | 68 | { |
65 | $repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); | 69 | $repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); |
66 | 70 | ||
@@ -81,14 +85,32 @@ class RssController extends Controller | |||
81 | throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type)); | 85 | throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type)); |
82 | } | 86 | } |
83 | 87 | ||
84 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery()); | 88 | $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); |
85 | $entries = new Pagerfanta($pagerAdapter); | 89 | $entries = new Pagerfanta($pagerAdapter); |
86 | 90 | ||
87 | $perPage = $user->getConfig()->getRssLimit() ?: $this->getParameter('wallabag_core.rss_limit'); | 91 | $perPage = $user->getConfig()->getRssLimit() ?: $this->getParameter('wallabag_core.rss_limit'); |
88 | $entries->setMaxPerPage($perPage); | 92 | $entries->setMaxPerPage($perPage); |
89 | 93 | ||
94 | $url = $this->generateUrl( | ||
95 | $type.'_rss', | ||
96 | [ | ||
97 | 'username' => $user->getUsername(), | ||
98 | 'token' => $user->getConfig()->getRssToken(), | ||
99 | ], | ||
100 | UrlGeneratorInterface::ABSOLUTE_URL | ||
101 | ); | ||
102 | |||
103 | try { | ||
104 | $entries->setCurrentPage((int) $page); | ||
105 | } catch (OutOfRangeCurrentPageException $e) { | ||
106 | if ($page > 1) { | ||
107 | return $this->redirect($url.'?page='.$entries->getNbPages(), 302); | ||
108 | } | ||
109 | } | ||
110 | |||
90 | return $this->render('@WallabagCore/themes/common/Entry/entries.xml.twig', [ | 111 | return $this->render('@WallabagCore/themes/common/Entry/entries.xml.twig', [ |
91 | 'type' => $type, | 112 | 'type' => $type, |
113 | 'url' => $url, | ||
92 | 'entries' => $entries, | 114 | 'entries' => $entries, |
93 | ]); | 115 | ]); |
94 | } | 116 | } |
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php index 707f3bbe..8a093289 100644 --- a/src/Wallabag/CoreBundle/Controller/TagController.php +++ b/src/Wallabag/CoreBundle/Controller/TagController.php | |||
@@ -27,7 +27,7 @@ class TagController extends Controller | |||
27 | $form = $this->createForm(NewTagType::class, new Tag()); | 27 | $form = $this->createForm(NewTagType::class, new Tag()); |
28 | $form->handleRequest($request); | 28 | $form->handleRequest($request); |
29 | 29 | ||
30 | if ($form->isValid()) { | 30 | if ($form->isSubmitted() && $form->isValid()) { |
31 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry( | 31 | $this->get('wallabag_core.content_proxy')->assignTagsToEntry( |
32 | $entry, | 32 | $entry, |
33 | $form->get('label')->getData() | 33 | $form->get('label')->getData() |
@@ -90,15 +90,15 @@ class TagController extends Controller | |||
90 | 90 | ||
91 | $flatTags = []; | 91 | $flatTags = []; |
92 | 92 | ||
93 | foreach ($tags as $key => $tag) { | 93 | foreach ($tags as $tag) { |
94 | $nbEntries = $this->getDoctrine() | 94 | $nbEntries = $this->getDoctrine() |
95 | ->getRepository('WallabagCoreBundle:Entry') | 95 | ->getRepository('WallabagCoreBundle:Entry') |
96 | ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag['id']); | 96 | ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag->getId()); |
97 | 97 | ||
98 | $flatTags[] = [ | 98 | $flatTags[] = [ |
99 | 'id' => $tag['id'], | 99 | 'id' => $tag->getId(), |
100 | 'label' => $tag['label'], | 100 | 'label' => $tag->getLabel(), |
101 | 'slug' => $tag['slug'], | 101 | 'slug' => $tag->getSlug(), |
102 | 'nbEntries' => $nbEntries, | 102 | 'nbEntries' => $nbEntries, |
103 | ]; | 103 | ]; |
104 | } | 104 | } |
@@ -143,7 +143,7 @@ class TagController extends Controller | |||
143 | 'form' => null, | 143 | 'form' => null, |
144 | 'entries' => $entries, | 144 | 'entries' => $entries, |
145 | 'currentPage' => $page, | 145 | 'currentPage' => $page, |
146 | 'tag' => $tag->getLabel(), | 146 | 'tag' => $tag->getSlug(), |
147 | ]); | 147 | ]); |
148 | } | 148 | } |
149 | } | 149 | } |
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php index 921c739f..3d4d5def 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php | |||
@@ -21,6 +21,8 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface | |||
21 | $adminConfig->setReadingSpeed(1); | 21 | $adminConfig->setReadingSpeed(1); |
22 | $adminConfig->setLanguage('en'); | 22 | $adminConfig->setLanguage('en'); |
23 | $adminConfig->setPocketConsumerKey('xxxxx'); | 23 | $adminConfig->setPocketConsumerKey('xxxxx'); |
24 | $adminConfig->setActionMarkAsRead(0); | ||
25 | $adminConfig->setListMode(0); | ||
24 | 26 | ||
25 | $manager->persist($adminConfig); | 27 | $manager->persist($adminConfig); |
26 | 28 | ||
@@ -32,6 +34,8 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface | |||
32 | $bobConfig->setReadingSpeed(1); | 34 | $bobConfig->setReadingSpeed(1); |
33 | $bobConfig->setLanguage('fr'); | 35 | $bobConfig->setLanguage('fr'); |
34 | $bobConfig->setPocketConsumerKey(null); | 36 | $bobConfig->setPocketConsumerKey(null); |
37 | $bobConfig->setActionMarkAsRead(1); | ||
38 | $bobConfig->setListMode(1); | ||
35 | 39 | ||
36 | $manager->persist($bobConfig); | 40 | $manager->persist($bobConfig); |
37 | 41 | ||
@@ -43,6 +47,8 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface | |||
43 | $emptyConfig->setReadingSpeed(1); | 47 | $emptyConfig->setReadingSpeed(1); |
44 | $emptyConfig->setLanguage('en'); | 48 | $emptyConfig->setLanguage('en'); |
45 | $emptyConfig->setPocketConsumerKey(null); | 49 | $emptyConfig->setPocketConsumerKey(null); |
50 | $emptyConfig->setActionMarkAsRead(0); | ||
51 | $emptyConfig->setListMode(0); | ||
46 | 52 | ||
47 | $manager->persist($emptyConfig); | 53 | $manager->persist($emptyConfig); |
48 | 54 | ||
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php index a5e1be65..a723656e 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php | |||
@@ -36,6 +36,16 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface | |||
36 | 'section' => 'entry', | 36 | 'section' => 'entry', |
37 | ], | 37 | ], |
38 | [ | 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 | [ | ||
39 | 'name' => 'share_shaarli', | 49 | 'name' => 'share_shaarli', |
40 | 'value' => '1', | 50 | 'value' => '1', |
41 | 'section' => 'entry', | 51 | 'section' => 'entry', |
@@ -140,6 +150,16 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface | |||
140 | 'value' => 'wallabag', | 150 | 'value' => 'wallabag', |
141 | 'section' => 'misc', | 151 | 'section' => 'misc', |
142 | ], | 152 | ], |
153 | [ | ||
154 | 'name' => 'download_images_enabled', | ||
155 | 'value' => '0', | ||
156 | 'section' => 'misc', | ||
157 | ], | ||
158 | [ | ||
159 | 'name' => 'restricted_access', | ||
160 | 'value' => '0', | ||
161 | 'section' => 'entry', | ||
162 | ], | ||
143 | ]; | 163 | ]; |
144 | 164 | ||
145 | foreach ($settings as $setting) { | 165 | foreach ($settings as $setting) { |
@@ -158,6 +178,6 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface | |||
158 | */ | 178 | */ |
159 | public function getOrder() | 179 | public function getOrder() |
160 | { | 180 | { |
161 | return 50; | 181 | return 29; |
162 | } | 182 | } |
163 | } | 183 | } |
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php index 09e99f36..6de561e0 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTagData.php | |||
@@ -15,7 +15,7 @@ class LoadTagData extends AbstractFixture implements OrderedFixtureInterface | |||
15 | public function load(ObjectManager $manager) | 15 | public function load(ObjectManager $manager) |
16 | { | 16 | { |
17 | $tag1 = new Tag(); | 17 | $tag1 = new Tag(); |
18 | $tag1->setLabel('foo'); | 18 | $tag1->setLabel('foo bar'); |
19 | 19 | ||
20 | $manager->persist($tag1); | 20 | $manager->persist($tag1); |
21 | 21 | ||
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php index 3a3da024..006a18c3 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php | |||
@@ -41,6 +41,12 @@ class Configuration implements ConfigurationInterface | |||
41 | ->end() | 41 | ->end() |
42 | ->scalarNode('fetching_error_message') | 42 | ->scalarNode('fetching_error_message') |
43 | ->end() | 43 | ->end() |
44 | ->scalarNode('action_mark_as_read') | ||
45 | ->defaultValue(1) | ||
46 | ->end() | ||
47 | ->scalarNode('list_mode') | ||
48 | ->defaultValue(1) | ||
49 | ->end() | ||
44 | ->end() | 50 | ->end() |
45 | ; | 51 | ; |
46 | 52 | ||
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php index b4992d54..aa9ee339 100644 --- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php +++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php | |||
@@ -23,6 +23,8 @@ class WallabagCoreExtension extends Extension | |||
23 | $container->setParameter('wallabag_core.version', $config['version']); | 23 | $container->setParameter('wallabag_core.version', $config['version']); |
24 | $container->setParameter('wallabag_core.paypal_url', $config['paypal_url']); | 24 | $container->setParameter('wallabag_core.paypal_url', $config['paypal_url']); |
25 | $container->setParameter('wallabag_core.cache_lifetime', $config['cache_lifetime']); | 25 | $container->setParameter('wallabag_core.cache_lifetime', $config['cache_lifetime']); |
26 | $container->setParameter('wallabag_core.action_mark_as_read', $config['action_mark_as_read']); | ||
27 | $container->setParameter('wallabag_core.list_mode', $config['list_mode']); | ||
26 | $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']); | 28 | $container->setParameter('wallabag_core.fetching_error_message', $config['fetching_error_message']); |
27 | 29 | ||
28 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | 30 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
diff --git a/src/Wallabag/CoreBundle/Entity/Config.php b/src/Wallabag/CoreBundle/Entity/Config.php index 69393ac9..b902ae2c 100644 --- a/src/Wallabag/CoreBundle/Entity/Config.php +++ b/src/Wallabag/CoreBundle/Entity/Config.php | |||
@@ -16,6 +16,9 @@ use Wallabag\UserBundle\Entity\User; | |||
16 | */ | 16 | */ |
17 | class Config | 17 | class Config |
18 | { | 18 | { |
19 | const REDIRECT_TO_HOMEPAGE = 0; | ||
20 | const REDIRECT_TO_CURRENT_PAGE = 1; | ||
21 | |||
19 | /** | 22 | /** |
20 | * @var int | 23 | * @var int |
21 | * | 24 | * |
@@ -88,6 +91,20 @@ class Config | |||
88 | private $pocketConsumerKey; | 91 | private $pocketConsumerKey; |
89 | 92 | ||
90 | /** | 93 | /** |
94 | * @var int | ||
95 | * | ||
96 | * @ORM\Column(name="action_mark_as_read", type="integer", nullable=true, options={"default" = 0}) | ||
97 | */ | ||
98 | private $actionMarkAsRead; | ||
99 | |||
100 | /** | ||
101 | * @var int | ||
102 | * | ||
103 | * @ORM\Column(name="list_mode", type="integer", nullable=true) | ||
104 | */ | ||
105 | private $listMode; | ||
106 | |||
107 | /** | ||
91 | * @ORM\OneToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="config") | 108 | * @ORM\OneToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="config") |
92 | */ | 109 | */ |
93 | private $user; | 110 | private $user; |
@@ -310,6 +327,46 @@ class Config | |||
310 | } | 327 | } |
311 | 328 | ||
312 | /** | 329 | /** |
330 | * @return int | ||
331 | */ | ||
332 | public function getActionMarkAsRead() | ||
333 | { | ||
334 | return $this->actionMarkAsRead; | ||
335 | } | ||
336 | |||
337 | /** | ||
338 | * @param int $actionMarkAsRead | ||
339 | * | ||
340 | * @return Config | ||
341 | */ | ||
342 | public function setActionMarkAsRead($actionMarkAsRead) | ||
343 | { | ||
344 | $this->actionMarkAsRead = $actionMarkAsRead; | ||
345 | |||
346 | return $this; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * @return int | ||
351 | */ | ||
352 | public function getListMode() | ||
353 | { | ||
354 | return $this->listMode; | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * @param int $listMode | ||
359 | * | ||
360 | * @return Config | ||
361 | */ | ||
362 | public function setListMode($listMode) | ||
363 | { | ||
364 | $this->listMode = $listMode; | ||
365 | |||
366 | return $this; | ||
367 | } | ||
368 | |||
369 | /** | ||
313 | * @param TaggingRule $rule | 370 | * @param TaggingRule $rule |
314 | * | 371 | * |
315 | * @return Config | 372 | * @return Config |
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php index f2da3f4d..7276b437 100644 --- a/src/Wallabag/CoreBundle/Entity/Entry.php +++ b/src/Wallabag/CoreBundle/Entity/Entry.php | |||
@@ -19,7 +19,14 @@ use Wallabag\AnnotationBundle\Entity\Annotation; | |||
19 | * | 19 | * |
20 | * @XmlRoot("entry") | 20 | * @XmlRoot("entry") |
21 | * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") | 21 | * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") |
22 | * @ORM\Table(name="`entry`") | 22 | * @ORM\Table( |
23 | * name="`entry`", | ||
24 | * options={"collate"="utf8mb4_unicode_ci", "charset"="utf8mb4"}, | ||
25 | * indexes={ | ||
26 | * @ORM\Index(name="created_at", columns={"created_at"}), | ||
27 | * @ORM\Index(name="uid", columns={"uid"}) | ||
28 | * } | ||
29 | * ) | ||
23 | * @ORM\HasLifecycleCallbacks() | 30 | * @ORM\HasLifecycleCallbacks() |
24 | * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") | 31 | * @Hateoas\Relation("self", href = "expr('/api/entries/' ~ object.getId())") |
25 | */ | 32 | */ |
@@ -40,11 +47,11 @@ class Entry | |||
40 | /** | 47 | /** |
41 | * @var string | 48 | * @var string |
42 | * | 49 | * |
43 | * @ORM\Column(name="uuid", type="text", nullable=true) | 50 | * @ORM\Column(name="uid", type="string", length=23, nullable=true) |
44 | * | 51 | * |
45 | * @Groups({"entries_for_user", "export_all"}) | 52 | * @Groups({"entries_for_user", "export_all"}) |
46 | */ | 53 | */ |
47 | private $uuid; | 54 | private $uid; |
48 | 55 | ||
49 | /** | 56 | /** |
50 | * @var string | 57 | * @var string |
@@ -177,6 +184,15 @@ class Entry | |||
177 | private $isPublic; | 184 | private $isPublic; |
178 | 185 | ||
179 | /** | 186 | /** |
187 | * @var string | ||
188 | * | ||
189 | * @ORM\Column(name="http_status", type="string", length=3, nullable=true) | ||
190 | * | ||
191 | * @Groups({"entries_for_user", "export_all"}) | ||
192 | */ | ||
193 | private $httpStatus; | ||
194 | |||
195 | /** | ||
180 | * @Exclude | 196 | * @Exclude |
181 | * | 197 | * |
182 | * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="entries") | 198 | * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="entries") |
@@ -190,10 +206,10 @@ class Entry | |||
190 | * @ORM\JoinTable( | 206 | * @ORM\JoinTable( |
191 | * name="entry_tag", | 207 | * name="entry_tag", |
192 | * joinColumns={ | 208 | * joinColumns={ |
193 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") | 209 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="cascade") |
194 | * }, | 210 | * }, |
195 | * inverseJoinColumns={ | 211 | * inverseJoinColumns={ |
196 | * @ORM\JoinColumn(name="tag_id", referencedColumnName="id") | 212 | * @ORM\JoinColumn(name="tag_id", referencedColumnName="id", onDelete="cascade") |
197 | * } | 213 | * } |
198 | * ) | 214 | * ) |
199 | */ | 215 | */ |
@@ -636,33 +652,53 @@ class Entry | |||
636 | /** | 652 | /** |
637 | * @return string | 653 | * @return string |
638 | */ | 654 | */ |
639 | public function getUuid() | 655 | public function getUid() |
640 | { | 656 | { |
641 | return $this->uuid; | 657 | return $this->uid; |
642 | } | 658 | } |
643 | 659 | ||
644 | /** | 660 | /** |
645 | * @param string $uuid | 661 | * @param string $uid |
646 | * | 662 | * |
647 | * @return Entry | 663 | * @return Entry |
648 | */ | 664 | */ |
649 | public function setUuid($uuid) | 665 | public function setUid($uid) |
650 | { | 666 | { |
651 | $this->uuid = $uuid; | 667 | $this->uid = $uid; |
652 | 668 | ||
653 | return $this; | 669 | return $this; |
654 | } | 670 | } |
655 | 671 | ||
656 | public function generateUuid() | 672 | public function generateUid() |
657 | { | 673 | { |
658 | if (null === $this->uuid) { | 674 | if (null === $this->uid) { |
659 | // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter | 675 | // @see http://blog.kevingomez.fr/til/2015/07/26/why-is-uniqid-slow/ for true parameter |
660 | $this->uuid = uniqid('', true); | 676 | $this->uid = uniqid('', true); |
661 | } | 677 | } |
662 | } | 678 | } |
663 | 679 | ||
664 | public function cleanUuid() | 680 | public function cleanUid() |
681 | { | ||
682 | $this->uid = null; | ||
683 | } | ||
684 | |||
685 | /** | ||
686 | * @return int | ||
687 | */ | ||
688 | public function getHttpStatus() | ||
689 | { | ||
690 | return $this->httpStatus; | ||
691 | } | ||
692 | |||
693 | /** | ||
694 | * @param int $httpStatus | ||
695 | * | ||
696 | * @return Entry | ||
697 | */ | ||
698 | public function setHttpStatus($httpStatus) | ||
665 | { | 699 | { |
666 | $this->uuid = null; | 700 | $this->httpStatus = $httpStatus; |
701 | |||
702 | return $this; | ||
667 | } | 703 | } |
668 | } | 704 | } |
diff --git a/src/Wallabag/CoreBundle/Entity/TaggingRule.php b/src/Wallabag/CoreBundle/Entity/TaggingRule.php index 28914cc1..72651b19 100644 --- a/src/Wallabag/CoreBundle/Entity/TaggingRule.php +++ b/src/Wallabag/CoreBundle/Entity/TaggingRule.php | |||
@@ -28,6 +28,7 @@ class TaggingRule | |||
28 | * @var string | 28 | * @var string |
29 | * | 29 | * |
30 | * @Assert\NotBlank() | 30 | * @Assert\NotBlank() |
31 | * @Assert\Length(max=255) | ||
31 | * @RulerZAssert\ValidRule( | 32 | * @RulerZAssert\ValidRule( |
32 | * allowed_variables={"title", "url", "isArchived", "isStared", "content", "language", "mimetype", "readingTime", "domainName"}, | 33 | * allowed_variables={"title", "url", "isArchived", "isStared", "content", "language", "mimetype", "readingTime", "domainName"}, |
33 | * allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches"} | 34 | * allowed_operators={">", "<", ">=", "<=", "=", "is", "!=", "and", "not", "or", "matches"} |
diff --git a/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php new file mode 100644 index 00000000..e9061d04 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/EntryDeletedEvent.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\Event; | ||
6 | use Wallabag\CoreBundle\Entity\Entry; | ||
7 | |||
8 | /** | ||
9 | * This event is fired as soon as an entry is deleted. | ||
10 | */ | ||
11 | class EntryDeletedEvent extends Event | ||
12 | { | ||
13 | const NAME = 'entry.deleted'; | ||
14 | |||
15 | protected $entry; | ||
16 | |||
17 | public function __construct(Entry $entry) | ||
18 | { | ||
19 | $this->entry = $entry; | ||
20 | } | ||
21 | |||
22 | public function getEntry() | ||
23 | { | ||
24 | return $this->entry; | ||
25 | } | ||
26 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php new file mode 100644 index 00000000..5fdb5221 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/EntrySavedEvent.php | |||
@@ -0,0 +1,26 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\Event; | ||
6 | use Wallabag\CoreBundle\Entity\Entry; | ||
7 | |||
8 | /** | ||
9 | * This event is fired as soon as an entry was saved. | ||
10 | */ | ||
11 | class EntrySavedEvent extends Event | ||
12 | { | ||
13 | const NAME = 'entry.saved'; | ||
14 | |||
15 | protected $entry; | ||
16 | |||
17 | public function __construct(Entry $entry) | ||
18 | { | ||
19 | $this->entry = $entry; | ||
20 | } | ||
21 | |||
22 | public function getEntry() | ||
23 | { | ||
24 | return $this->entry; | ||
25 | } | ||
26 | } | ||
diff --git a/src/Wallabag/CoreBundle/EventListener/LocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php index a1c7e5ab..b435d99e 100644 --- a/src/Wallabag/CoreBundle/EventListener/LocaleListener.php +++ b/src/Wallabag/CoreBundle/Event/Listener/LocaleListener.php | |||
@@ -1,6 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\EventListener; | 3 | namespace Wallabag\CoreBundle\Event\Listener; |
4 | 4 | ||
5 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | 5 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
6 | use Symfony\Component\HttpKernel\Event\GetResponseEvent; | 6 | use Symfony\Component\HttpKernel\Event\GetResponseEvent; |
diff --git a/src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php index 82d1a63a..367cdfb0 100644 --- a/src/Wallabag/CoreBundle/EventListener/UserLocaleListener.php +++ b/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php | |||
@@ -1,6 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\EventListener; | 3 | namespace Wallabag\CoreBundle\Event\Listener; |
4 | 4 | ||
5 | use Symfony\Component\HttpFoundation\Session\Session; | 5 | use Symfony\Component\HttpFoundation\Session\Session; |
6 | use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; | 6 | use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; |
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php new file mode 100644 index 00000000..4ebe837b --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Subscriber/DownloadImagesSubscriber.php | |||
@@ -0,0 +1,121 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Subscriber; | ||
4 | |||
5 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
6 | use Psr\Log\LoggerInterface; | ||
7 | use Wallabag\CoreBundle\Helper\DownloadImages; | ||
8 | use Wallabag\CoreBundle\Entity\Entry; | ||
9 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
10 | use Wallabag\CoreBundle\Event\EntryDeletedEvent; | ||
11 | use Doctrine\ORM\EntityManager; | ||
12 | |||
13 | class DownloadImagesSubscriber implements EventSubscriberInterface | ||
14 | { | ||
15 | private $em; | ||
16 | private $downloadImages; | ||
17 | private $enabled; | ||
18 | private $logger; | ||
19 | |||
20 | public function __construct(EntityManager $em, DownloadImages $downloadImages, $enabled, LoggerInterface $logger) | ||
21 | { | ||
22 | $this->em = $em; | ||
23 | $this->downloadImages = $downloadImages; | ||
24 | $this->enabled = $enabled; | ||
25 | $this->logger = $logger; | ||
26 | } | ||
27 | |||
28 | public static function getSubscribedEvents() | ||
29 | { | ||
30 | return [ | ||
31 | EntrySavedEvent::NAME => 'onEntrySaved', | ||
32 | EntryDeletedEvent::NAME => 'onEntryDeleted', | ||
33 | ]; | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * Download images and updated the data into the entry. | ||
38 | * | ||
39 | * @param EntrySavedEvent $event | ||
40 | */ | ||
41 | public function onEntrySaved(EntrySavedEvent $event) | ||
42 | { | ||
43 | if (!$this->enabled) { | ||
44 | $this->logger->debug('DownloadImagesSubscriber: disabled.'); | ||
45 | |||
46 | return; | ||
47 | } | ||
48 | |||
49 | $entry = $event->getEntry(); | ||
50 | |||
51 | $html = $this->downloadImages($entry); | ||
52 | if (false !== $html) { | ||
53 | $this->logger->debug('DownloadImagesSubscriber: updated html.'); | ||
54 | |||
55 | $entry->setContent($html); | ||
56 | } | ||
57 | |||
58 | // update preview picture | ||
59 | $previewPicture = $this->downloadPreviewImage($entry); | ||
60 | if (false !== $previewPicture) { | ||
61 | $this->logger->debug('DownloadImagesSubscriber: update preview picture.'); | ||
62 | |||
63 | $entry->setPreviewPicture($previewPicture); | ||
64 | } | ||
65 | |||
66 | $this->em->persist($entry); | ||
67 | $this->em->flush(); | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * Remove images related to the entry. | ||
72 | * | ||
73 | * @param EntryDeletedEvent $event | ||
74 | */ | ||
75 | public function onEntryDeleted(EntryDeletedEvent $event) | ||
76 | { | ||
77 | if (!$this->enabled) { | ||
78 | $this->logger->debug('DownloadImagesSubscriber: disabled.'); | ||
79 | |||
80 | return; | ||
81 | } | ||
82 | |||
83 | $this->downloadImages->removeImages($event->getEntry()->getId()); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Download all images from the html. | ||
88 | * | ||
89 | * @todo If we want to add async download, it should be done in that method | ||
90 | * | ||
91 | * @param Entry $entry | ||
92 | * | ||
93 | * @return string|false False in case of async | ||
94 | */ | ||
95 | private function downloadImages(Entry $entry) | ||
96 | { | ||
97 | return $this->downloadImages->processHtml( | ||
98 | $entry->getId(), | ||
99 | $entry->getContent(), | ||
100 | $entry->getUrl() | ||
101 | ); | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * Download the preview picture. | ||
106 | * | ||
107 | * @todo If we want to add async download, it should be done in that method | ||
108 | * | ||
109 | * @param Entry $entry | ||
110 | * | ||
111 | * @return string|false False in case of async | ||
112 | */ | ||
113 | private function downloadPreviewImage(Entry $entry) | ||
114 | { | ||
115 | return $this->downloadImages->processSingleImage( | ||
116 | $entry->getId(), | ||
117 | $entry->getPreviewPicture(), | ||
118 | $entry->getUrl() | ||
119 | ); | ||
120 | } | ||
121 | } | ||
diff --git a/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php new file mode 100644 index 00000000..3b4c4cf9 --- /dev/null +++ b/src/Wallabag/CoreBundle/Event/Subscriber/SQLiteCascadeDeleteSubscriber.php | |||
@@ -0,0 +1,70 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Event\Subscriber; | ||
4 | |||
5 | use Doctrine\Common\EventSubscriber; | ||
6 | use Doctrine\ORM\Event\LifecycleEventArgs; | ||
7 | use Wallabag\CoreBundle\Entity\Entry; | ||
8 | use Doctrine\Bundle\DoctrineBundle\Registry; | ||
9 | |||
10 | /** | ||
11 | * SQLite doesn't care about cascading remove, so we need to manually remove associated stuf for an Entry. | ||
12 | * Foreign Key Support can be enabled by running `PRAGMA foreign_keys = ON;` at runtime (AT RUNTIME !). | ||
13 | * But it needs a compilation flag that not all SQLite instance has ... | ||
14 | * | ||
15 | * @see https://www.sqlite.org/foreignkeys.html#fk_enable | ||
16 | */ | ||
17 | class SQLiteCascadeDeleteSubscriber implements EventSubscriber | ||
18 | { | ||
19 | private $doctrine; | ||
20 | |||
21 | /** | ||
22 | * @param \Doctrine\Bundle\DoctrineBundle\Registry $doctrine | ||
23 | */ | ||
24 | public function __construct(Registry $doctrine) | ||
25 | { | ||
26 | $this->doctrine = $doctrine; | ||
27 | } | ||
28 | |||
29 | /** | ||
30 | * @return array | ||
31 | */ | ||
32 | public function getSubscribedEvents() | ||
33 | { | ||
34 | return [ | ||
35 | 'preRemove', | ||
36 | ]; | ||
37 | } | ||
38 | |||
39 | /** | ||
40 | * We removed everything related to the upcoming removed entry because SQLite can't handle it on it own. | ||
41 | * We do it in the preRemove, because we can't retrieve tags in the postRemove (because the entry id is gone). | ||
42 | * | ||
43 | * @param LifecycleEventArgs $args | ||
44 | */ | ||
45 | public function preRemove(LifecycleEventArgs $args) | ||
46 | { | ||
47 | $entity = $args->getEntity(); | ||
48 | |||
49 | if (!$this->doctrine->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver || | ||
50 | !$entity instanceof Entry) { | ||
51 | return; | ||
52 | } | ||
53 | |||
54 | $em = $this->doctrine->getManager(); | ||
55 | |||
56 | if (null !== $entity->getTags()) { | ||
57 | foreach ($entity->getTags() as $tag) { | ||
58 | $entity->removeTag($tag); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | if (null !== $entity->getAnnotations()) { | ||
63 | foreach ($entity->getAnnotations() as $annotation) { | ||
64 | $em->remove($annotation); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | $em->flush(); | ||
69 | } | ||
70 | } | ||
diff --git a/src/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriber.php b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php index 0379ad6a..711c3bf8 100644 --- a/src/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriber.php +++ b/src/Wallabag/CoreBundle/Event/Subscriber/TablePrefixSubscriber.php | |||
@@ -1,6 +1,6 @@ | |||
1 | <?php | 1 | <?php |
2 | 2 | ||
3 | namespace Wallabag\CoreBundle\Subscriber; | 3 | namespace Wallabag\CoreBundle\Event\Subscriber; |
4 | 4 | ||
5 | use Doctrine\Common\EventSubscriber; | 5 | use Doctrine\Common\EventSubscriber; |
6 | use Doctrine\ORM\Event\LoadClassMetadataEventArgs; | 6 | use Doctrine\ORM\Event\LoadClassMetadataEventArgs; |
@@ -39,7 +39,7 @@ class TablePrefixSubscriber implements EventSubscriber | |||
39 | return; | 39 | return; |
40 | } | 40 | } |
41 | 41 | ||
42 | $classMetadata->setTableName($this->prefix.$classMetadata->getTableName()); | 42 | $classMetadata->setPrimaryTable(['name' => $this->prefix.$classMetadata->getTableName()]); |
43 | 43 | ||
44 | foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { | 44 | foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { |
45 | if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && isset($classMetadata->associationMappings[$fieldName]['joinTable']['name'])) { | 45 | if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && isset($classMetadata->associationMappings[$fieldName]['joinTable']['name'])) { |
diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php index 0bac2874..7e3b9dd4 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php | |||
@@ -7,6 +7,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | |||
7 | use Symfony\Component\Form\Extension\Core\Type\SubmitType; | 7 | use Symfony\Component\Form\Extension\Core\Type\SubmitType; |
8 | use Symfony\Component\Form\FormBuilderInterface; | 8 | use Symfony\Component\Form\FormBuilderInterface; |
9 | use Symfony\Component\OptionsResolver\OptionsResolver; | 9 | use Symfony\Component\OptionsResolver\OptionsResolver; |
10 | use Wallabag\CoreBundle\Entity\Config; | ||
10 | 11 | ||
11 | class ConfigType extends AbstractType | 12 | class ConfigType extends AbstractType |
12 | { | 13 | { |
@@ -48,6 +49,13 @@ class ConfigType extends AbstractType | |||
48 | 'config.form_settings.reading_speed.400_word' => '2', | 49 | 'config.form_settings.reading_speed.400_word' => '2', |
49 | ], | 50 | ], |
50 | ]) | 51 | ]) |
52 | ->add('action_mark_as_read', ChoiceType::class, [ | ||
53 | 'label' => 'config.form_settings.action_mark_as_read.label', | ||
54 | 'choices' => [ | ||
55 | 'config.form_settings.action_mark_as_read.redirect_homepage' => Config::REDIRECT_TO_HOMEPAGE, | ||
56 | 'config.form_settings.action_mark_as_read.redirect_current_page' => Config::REDIRECT_TO_CURRENT_PAGE, | ||
57 | ], | ||
58 | ]) | ||
51 | ->add('language', ChoiceType::class, [ | 59 | ->add('language', ChoiceType::class, [ |
52 | 'choices' => array_flip($this->languages), | 60 | 'choices' => array_flip($this->languages), |
53 | 'label' => 'config.form_settings.language_label', | 61 | 'label' => 'config.form_settings.language_label', |
diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php index a3e36fdd..ee66c728 100644 --- a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php +++ b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php | |||
@@ -11,6 +11,7 @@ use Lexik\Bundle\FormFilterBundle\Filter\Form\Type\CheckboxFilterType; | |||
11 | use Lexik\Bundle\FormFilterBundle\Filter\Form\Type\ChoiceFilterType; | 11 | use Lexik\Bundle\FormFilterBundle\Filter\Form\Type\ChoiceFilterType; |
12 | use Symfony\Component\Form\AbstractType; | 12 | use Symfony\Component\Form\AbstractType; |
13 | use Symfony\Component\Form\FormBuilderInterface; | 13 | use Symfony\Component\Form\FormBuilderInterface; |
14 | use Symfony\Component\HttpFoundation\Response; | ||
14 | use Symfony\Component\OptionsResolver\OptionsResolver; | 15 | use Symfony\Component\OptionsResolver\OptionsResolver; |
15 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | 16 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; |
16 | 17 | ||
@@ -89,12 +90,27 @@ class EntryFilterType extends AbstractType | |||
89 | if (strlen($value) <= 2 || empty($value)) { | 90 | if (strlen($value) <= 2 || empty($value)) { |
90 | return; | 91 | return; |
91 | } | 92 | } |
92 | $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->literal('%'.$value.'%')); | 93 | $expression = $filterQuery->getExpr()->like($field, $filterQuery->getExpr()->lower($filterQuery->getExpr()->literal('%'.$value.'%'))); |
93 | 94 | ||
94 | return $filterQuery->createCondition($expression); | 95 | return $filterQuery->createCondition($expression); |
95 | }, | 96 | }, |
96 | 'label' => 'entry.filters.domain_label', | 97 | 'label' => 'entry.filters.domain_label', |
97 | ]) | 98 | ]) |
99 | ->add('httpStatus', TextFilterType::class, [ | ||
100 | 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { | ||
101 | $value = $values['value']; | ||
102 | if (false === array_key_exists($value, Response::$statusTexts)) { | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | $paramName = sprintf('%s', str_replace('.', '_', $field)); | ||
107 | $expression = $filterQuery->getExpr()->eq($field, ':'.$paramName); | ||
108 | $parameters = array($paramName => $value); | ||
109 | |||
110 | return $filterQuery->createCondition($expression, $parameters); | ||
111 | }, | ||
112 | 'label' => 'entry.filters.http_status_label', | ||
113 | ]) | ||
98 | ->add('isArchived', CheckboxFilterType::class, [ | 114 | ->add('isArchived', CheckboxFilterType::class, [ |
99 | 'label' => 'entry.filters.archived_label', | 115 | 'label' => 'entry.filters.archived_label', |
100 | ]) | 116 | ]) |
diff --git a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php index 3db4105f..e830ade4 100644 --- a/src/Wallabag/CoreBundle/Form/Type/NewTagType.php +++ b/src/Wallabag/CoreBundle/Form/Type/NewTagType.php | |||
@@ -3,6 +3,7 @@ | |||
3 | namespace Wallabag\CoreBundle\Form\Type; | 3 | namespace Wallabag\CoreBundle\Form\Type; |
4 | 4 | ||
5 | use Symfony\Component\Form\AbstractType; | 5 | use Symfony\Component\Form\AbstractType; |
6 | use Symfony\Component\Form\Extension\Core\Type\SubmitType; | ||
6 | use Symfony\Component\Form\Extension\Core\Type\TextType; | 7 | use Symfony\Component\Form\Extension\Core\Type\TextType; |
7 | use Symfony\Component\Form\FormBuilderInterface; | 8 | use Symfony\Component\Form\FormBuilderInterface; |
8 | use Symfony\Component\OptionsResolver\OptionsResolver; | 9 | use Symfony\Component\OptionsResolver\OptionsResolver; |
@@ -12,7 +13,15 @@ class NewTagType extends AbstractType | |||
12 | public function buildForm(FormBuilderInterface $builder, array $options) | 13 | public function buildForm(FormBuilderInterface $builder, array $options) |
13 | { | 14 | { |
14 | $builder | 15 | $builder |
15 | ->add('label', TextType::class, ['required' => true]) | 16 | ->add('label', TextType::class, [ |
17 | 'required' => true, | ||
18 | 'attr' => [ | ||
19 | 'placeholder' => 'tag.new.placeholder', | ||
20 | ], | ||
21 | ]) | ||
22 | ->add('add', SubmitType::class, [ | ||
23 | 'label' => 'tag.new.add', | ||
24 | ]) | ||
16 | ; | 25 | ; |
17 | } | 26 | } |
18 | 27 | ||
diff --git a/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php b/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php new file mode 100644 index 00000000..b56cae8e --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/SearchEntryType.php | |||
@@ -0,0 +1,29 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Form\Type; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
7 | use Symfony\Component\Form\FormBuilderInterface; | ||
8 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
9 | |||
10 | class SearchEntryType extends AbstractType | ||
11 | { | ||
12 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
13 | { | ||
14 | $builder | ||
15 | ->setMethod('GET') | ||
16 | ->add('term', TextType::class, [ | ||
17 | 'required' => true, | ||
18 | 'label' => 'entry.new.form_search.term_label', | ||
19 | ]) | ||
20 | ; | ||
21 | } | ||
22 | |||
23 | public function configureOptions(OptionsResolver $resolver) | ||
24 | { | ||
25 | $resolver->setDefaults([ | ||
26 | 'csrf_protection' => false, | ||
27 | ]); | ||
28 | } | ||
29 | } | ||
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php new file mode 100644 index 00000000..6d4129e8 --- /dev/null +++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php | |||
@@ -0,0 +1,68 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\GuzzleSiteAuthenticator; | ||
4 | |||
5 | use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig; | ||
6 | use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfigBuilder; | ||
7 | use Graby\SiteConfig\ConfigBuilder; | ||
8 | use OutOfRangeException; | ||
9 | |||
10 | class GrabySiteConfigBuilder implements SiteConfigBuilder | ||
11 | { | ||
12 | /** | ||
13 | * @var \Graby\SiteConfig\ConfigBuilder | ||
14 | */ | ||
15 | private $grabyConfigBuilder; | ||
16 | /** | ||
17 | * @var array | ||
18 | */ | ||
19 | private $credentials; | ||
20 | |||
21 | /** | ||
22 | * GrabySiteConfigBuilder constructor. | ||
23 | * | ||
24 | * @param \Graby\SiteConfig\ConfigBuilder $grabyConfigBuilder | ||
25 | * @param array $credentials | ||
26 | */ | ||
27 | public function __construct(ConfigBuilder $grabyConfigBuilder, array $credentials = []) | ||
28 | { | ||
29 | $this->grabyConfigBuilder = $grabyConfigBuilder; | ||
30 | $this->credentials = $credentials; | ||
31 | } | ||
32 | |||
33 | /** | ||
34 | * Builds the SiteConfig for a host. | ||
35 | * | ||
36 | * @param string $host The "www." prefix is ignored | ||
37 | * | ||
38 | * @return SiteConfig | ||
39 | * | ||
40 | * @throws OutOfRangeException If there is no config for $host | ||
41 | */ | ||
42 | public function buildForHost($host) | ||
43 | { | ||
44 | // required by credentials below | ||
45 | $host = strtolower($host); | ||
46 | if (substr($host, 0, 4) == 'www.') { | ||
47 | $host = substr($host, 4); | ||
48 | } | ||
49 | |||
50 | $config = $this->grabyConfigBuilder->buildForHost($host); | ||
51 | $parameters = [ | ||
52 | 'host' => $host, | ||
53 | 'requiresLogin' => $config->requires_login ?: false, | ||
54 | 'loginUri' => $config->login_uri ?: null, | ||
55 | 'usernameField' => $config->login_username_field ?: null, | ||
56 | 'passwordField' => $config->login_password_field ?: null, | ||
57 | 'extraFields' => is_array($config->login_extra_fields) ? $config->login_extra_fields : [], | ||
58 | 'notLoggedInXpath' => $config->not_logged_in_xpath ?: null, | ||
59 | ]; | ||
60 | |||
61 | if (isset($this->credentials[$host])) { | ||
62 | $parameters['username'] = $this->credentials[$host]['username']; | ||
63 | $parameters['password'] = $this->credentials[$host]['password']; | ||
64 | } | ||
65 | |||
66 | return new SiteConfig($parameters); | ||
67 | } | ||
68 | } | ||
diff --git a/src/Wallabag/CoreBundle/Helper/ContentProxy.php b/src/Wallabag/CoreBundle/Helper/ContentProxy.php index bbd5db5d..0130bd2b 100644 --- a/src/Wallabag/CoreBundle/Helper/ContentProxy.php +++ b/src/Wallabag/CoreBundle/Helper/ContentProxy.php | |||
@@ -3,7 +3,7 @@ | |||
3 | namespace Wallabag\CoreBundle\Helper; | 3 | namespace Wallabag\CoreBundle\Helper; |
4 | 4 | ||
5 | use Graby\Graby; | 5 | use Graby\Graby; |
6 | use Psr\Log\LoggerInterface as Logger; | 6 | use Psr\Log\LoggerInterface; |
7 | use Wallabag\CoreBundle\Entity\Entry; | 7 | use Wallabag\CoreBundle\Entity\Entry; |
8 | use Wallabag\CoreBundle\Entity\Tag; | 8 | use Wallabag\CoreBundle\Entity\Tag; |
9 | use Wallabag\CoreBundle\Tools\Utils; | 9 | use Wallabag\CoreBundle\Tools\Utils; |
@@ -21,14 +21,16 @@ class ContentProxy | |||
21 | protected $logger; | 21 | protected $logger; |
22 | protected $tagRepository; | 22 | protected $tagRepository; |
23 | protected $mimeGuesser; | 23 | protected $mimeGuesser; |
24 | protected $fetchingErrorMessage; | ||
24 | 25 | ||
25 | public function __construct(Graby $graby, RuleBasedTagger $tagger, TagRepository $tagRepository, Logger $logger) | 26 | public function __construct(Graby $graby, RuleBasedTagger $tagger, TagRepository $tagRepository, LoggerInterface $logger, $fetchingErrorMessage) |
26 | { | 27 | { |
27 | $this->graby = $graby; | 28 | $this->graby = $graby; |
28 | $this->tagger = $tagger; | 29 | $this->tagger = $tagger; |
29 | $this->logger = $logger; | 30 | $this->logger = $logger; |
30 | $this->tagRepository = $tagRepository; | 31 | $this->tagRepository = $tagRepository; |
31 | $this->mimeGuesser = new MimeTypeExtensionGuesser(); | 32 | $this->mimeGuesser = new MimeTypeExtensionGuesser(); |
33 | $this->fetchingErrorMessage = $fetchingErrorMessage; | ||
32 | } | 34 | } |
33 | 35 | ||
34 | /** | 36 | /** |
@@ -48,7 +50,13 @@ class ContentProxy | |||
48 | { | 50 | { |
49 | // do we have to fetch the content or the provided one is ok? | 51 | // do we have to fetch the content or the provided one is ok? |
50 | if (empty($content) || false === $this->validateContent($content)) { | 52 | if (empty($content) || false === $this->validateContent($content)) { |
51 | $content = $this->graby->fetchContent($url); | 53 | $fetchedContent = $this->graby->fetchContent($url); |
54 | |||
55 | // when content is imported, we have information in $content | ||
56 | // in case fetching content goes bad, we'll keep the imported information instead of overriding them | ||
57 | if (empty($content) || $fetchedContent['html'] !== $this->fetchingErrorMessage) { | ||
58 | $content = $fetchedContent; | ||
59 | } | ||
52 | } | 60 | } |
53 | 61 | ||
54 | $title = $content['title']; | 62 | $title = $content['title']; |
@@ -58,7 +66,7 @@ class ContentProxy | |||
58 | 66 | ||
59 | $html = $content['html']; | 67 | $html = $content['html']; |
60 | if (false === $html) { | 68 | if (false === $html) { |
61 | $html = '<p>Unable to retrieve readable content.</p>'; | 69 | $html = $this->fetchingErrorMessage; |
62 | 70 | ||
63 | if (isset($content['open_graph']['og_description'])) { | 71 | if (isset($content['open_graph']['og_description'])) { |
64 | $html .= '<p><i>But we found a short description: </i></p>'; | 72 | $html .= '<p><i>But we found a short description: </i></p>'; |
@@ -69,8 +77,10 @@ class ContentProxy | |||
69 | $entry->setUrl($content['url'] ?: $url); | 77 | $entry->setUrl($content['url'] ?: $url); |
70 | $entry->setTitle($title); | 78 | $entry->setTitle($title); |
71 | $entry->setContent($html); | 79 | $entry->setContent($html); |
72 | $entry->setLanguage($content['language']); | 80 | $entry->setHttpStatus(isset($content['status']) ? $content['status'] : ''); |
73 | $entry->setMimetype($content['content_type']); | 81 | |
82 | $entry->setLanguage(isset($content['language']) ? $content['language'] : ''); | ||
83 | $entry->setMimetype(isset($content['content_type']) ? $content['content_type'] : ''); | ||
74 | $entry->setReadingTime(Utils::getReadingTime($html)); | 84 | $entry->setReadingTime(Utils::getReadingTime($html)); |
75 | 85 | ||
76 | $domainName = parse_url($entry->getUrl(), PHP_URL_HOST); | 86 | $domainName = parse_url($entry->getUrl(), PHP_URL_HOST); |
@@ -83,7 +93,7 @@ class ContentProxy | |||
83 | } | 93 | } |
84 | 94 | ||
85 | // if content is an image define as a preview too | 95 | // if content is an image define as a preview too |
86 | if (in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { | 96 | if (isset($content['content_type']) && in_array($this->mimeGuesser->guess($content['content_type']), ['jpeg', 'jpg', 'gif', 'png'], true)) { |
87 | $entry->setPreviewPicture($content['url']); | 97 | $entry->setPreviewPicture($content['url']); |
88 | } | 98 | } |
89 | 99 | ||
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php new file mode 100644 index 00000000..c83f9618 --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php | |||
@@ -0,0 +1,233 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Helper; | ||
4 | |||
5 | use Psr\Log\LoggerInterface; | ||
6 | use Symfony\Component\DomCrawler\Crawler; | ||
7 | use GuzzleHttp\Client; | ||
8 | use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser; | ||
9 | use Symfony\Component\Finder\Finder; | ||
10 | |||
11 | class DownloadImages | ||
12 | { | ||
13 | const REGENERATE_PICTURES_QUALITY = 80; | ||
14 | |||
15 | private $client; | ||
16 | private $baseFolder; | ||
17 | private $logger; | ||
18 | private $mimeGuesser; | ||
19 | private $wallabagUrl; | ||
20 | |||
21 | public function __construct(Client $client, $baseFolder, $wallabagUrl, LoggerInterface $logger) | ||
22 | { | ||
23 | $this->client = $client; | ||
24 | $this->baseFolder = $baseFolder; | ||
25 | $this->wallabagUrl = rtrim($wallabagUrl, '/'); | ||
26 | $this->logger = $logger; | ||
27 | $this->mimeGuesser = new MimeTypeExtensionGuesser(); | ||
28 | |||
29 | $this->setFolder(); | ||
30 | } | ||
31 | |||
32 | /** | ||
33 | * Setup base folder where all images are going to be saved. | ||
34 | */ | ||
35 | private function setFolder() | ||
36 | { | ||
37 | // if folder doesn't exist, attempt to create one and store the folder name in property $folder | ||
38 | if (!file_exists($this->baseFolder)) { | ||
39 | mkdir($this->baseFolder, 0755, true); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Process the html and extract image from it, save them to local and return the updated html. | ||
45 | * | ||
46 | * @param int $entryId ID of the entry | ||
47 | * @param string $html | ||
48 | * @param string $url Used as a base path for relative image and folder | ||
49 | * | ||
50 | * @return string | ||
51 | */ | ||
52 | public function processHtml($entryId, $html, $url) | ||
53 | { | ||
54 | $crawler = new Crawler($html); | ||
55 | $result = $crawler | ||
56 | ->filterXpath('//img') | ||
57 | ->extract(array('src')); | ||
58 | |||
59 | $relativePath = $this->getRelativePath($entryId); | ||
60 | |||
61 | // download and save the image to the folder | ||
62 | foreach ($result as $image) { | ||
63 | $imagePath = $this->processSingleImage($entryId, $image, $url, $relativePath); | ||
64 | |||
65 | if (false === $imagePath) { | ||
66 | continue; | ||
67 | } | ||
68 | |||
69 | $html = str_replace($image, $imagePath, $html); | ||
70 | } | ||
71 | |||
72 | return $html; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * Process a single image: | ||
77 | * - retrieve it | ||
78 | * - re-saved it (for security reason) | ||
79 | * - return the new local path. | ||
80 | * | ||
81 | * @param int $entryId ID of the entry | ||
82 | * @param string $imagePath Path to the image to retrieve | ||
83 | * @param string $url Url from where the image were found | ||
84 | * @param string $relativePath Relative local path to saved the image | ||
85 | * | ||
86 | * @return string Relative url to access the image from the web | ||
87 | */ | ||
88 | public function processSingleImage($entryId, $imagePath, $url, $relativePath = null) | ||
89 | { | ||
90 | if (null === $relativePath) { | ||
91 | $relativePath = $this->getRelativePath($entryId); | ||
92 | } | ||
93 | |||
94 | $this->logger->debug('DownloadImages: working on image: '.$imagePath); | ||
95 | |||
96 | $folderPath = $this->baseFolder.'/'.$relativePath; | ||
97 | |||
98 | // build image path | ||
99 | $absolutePath = $this->getAbsoluteLink($url, $imagePath); | ||
100 | if (false === $absolutePath) { | ||
101 | $this->logger->error('DownloadImages: Can not determine the absolute path for that image, skipping.'); | ||
102 | |||
103 | return false; | ||
104 | } | ||
105 | |||
106 | try { | ||
107 | $res = $this->client->get($absolutePath); | ||
108 | } catch (\Exception $e) { | ||
109 | $this->logger->error('DownloadImages: Can not retrieve image, skipping.', ['exception' => $e]); | ||
110 | |||
111 | return false; | ||
112 | } | ||
113 | |||
114 | $ext = $this->mimeGuesser->guess($res->getHeader('content-type')); | ||
115 | $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); | ||
116 | if (!in_array($ext, ['jpeg', 'jpg', 'gif', 'png'], true)) { | ||
117 | $this->logger->error('DownloadImages: Processed image with not allowed extension. Skipping '.$imagePath); | ||
118 | |||
119 | return false; | ||
120 | } | ||
121 | $hashImage = hash('crc32', $absolutePath); | ||
122 | $localPath = $folderPath.'/'.$hashImage.'.'.$ext; | ||
123 | |||
124 | try { | ||
125 | $im = imagecreatefromstring($res->getBody()); | ||
126 | } catch (\Exception $e) { | ||
127 | $im = false; | ||
128 | } | ||
129 | |||
130 | if (false === $im) { | ||
131 | $this->logger->error('DownloadImages: Error while regenerating image', ['path' => $localPath]); | ||
132 | |||
133 | return false; | ||
134 | } | ||
135 | |||
136 | switch ($ext) { | ||
137 | case 'gif': | ||
138 | imagegif($im, $localPath); | ||
139 | $this->logger->debug('DownloadImages: Re-creating gif'); | ||
140 | break; | ||
141 | case 'jpeg': | ||
142 | case 'jpg': | ||
143 | imagejpeg($im, $localPath, self::REGENERATE_PICTURES_QUALITY); | ||
144 | $this->logger->debug('DownloadImages: Re-creating jpg'); | ||
145 | break; | ||
146 | case 'png': | ||
147 | imagepng($im, $localPath, ceil(self::REGENERATE_PICTURES_QUALITY / 100 * 9)); | ||
148 | $this->logger->debug('DownloadImages: Re-creating png'); | ||
149 | } | ||
150 | |||
151 | imagedestroy($im); | ||
152 | |||
153 | return $this->wallabagUrl.'/assets/images/'.$relativePath.'/'.$hashImage.'.'.$ext; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Remove all images for the given entry id. | ||
158 | * | ||
159 | * @param int $entryId ID of the entry | ||
160 | */ | ||
161 | public function removeImages($entryId) | ||
162 | { | ||
163 | $relativePath = $this->getRelativePath($entryId); | ||
164 | $folderPath = $this->baseFolder.'/'.$relativePath; | ||
165 | |||
166 | $finder = new Finder(); | ||
167 | $finder | ||
168 | ->files() | ||
169 | ->ignoreDotFiles(true) | ||
170 | ->in($folderPath); | ||
171 | |||
172 | foreach ($finder as $file) { | ||
173 | @unlink($file->getRealPath()); | ||
174 | } | ||
175 | |||
176 | @rmdir($folderPath); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * Generate the folder where we are going to save images based on the entry url. | ||
181 | * | ||
182 | * @param int $entryId ID of the entry | ||
183 | * | ||
184 | * @return string | ||
185 | */ | ||
186 | private function getRelativePath($entryId) | ||
187 | { | ||
188 | $hashId = hash('crc32', $entryId); | ||
189 | $relativePath = $hashId[0].'/'.$hashId[1].'/'.$hashId; | ||
190 | $folderPath = $this->baseFolder.'/'.$relativePath; | ||
191 | |||
192 | if (!file_exists($folderPath)) { | ||
193 | mkdir($folderPath, 0777, true); | ||
194 | } | ||
195 | |||
196 | $this->logger->debug('DownloadImages: Folder used for that Entry id', ['folder' => $folderPath, 'entryId' => $entryId]); | ||
197 | |||
198 | return $relativePath; | ||
199 | } | ||
200 | |||
201 | /** | ||
202 | * Make an $url absolute based on the $base. | ||
203 | * | ||
204 | * @see Graby->makeAbsoluteStr | ||
205 | * | ||
206 | * @param string $base Base url | ||
207 | * @param string $url Url to make it absolute | ||
208 | * | ||
209 | * @return false|string | ||
210 | */ | ||
211 | private function getAbsoluteLink($base, $url) | ||
212 | { | ||
213 | if (preg_match('!^https?://!i', $url)) { | ||
214 | // already absolute | ||
215 | return $url; | ||
216 | } | ||
217 | |||
218 | $base = new \SimplePie_IRI($base); | ||
219 | |||
220 | // remove '//' in URL path (causes URLs not to resolve properly) | ||
221 | if (isset($base->ipath)) { | ||
222 | $base->ipath = preg_replace('!//+!', '/', $base->ipath); | ||
223 | } | ||
224 | |||
225 | if ($absolute = \SimplePie_IRI::absolutize($base, $url)) { | ||
226 | return $absolute->get_uri(); | ||
227 | } | ||
228 | |||
229 | $this->logger->error('DownloadImages: Can not make an absolute link', ['base' => $base, 'url' => $url]); | ||
230 | |||
231 | return false; | ||
232 | } | ||
233 | } | ||
diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php new file mode 100644 index 00000000..8891887b --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php | |||
@@ -0,0 +1,54 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Helper; | ||
4 | |||
5 | use Graby\Ring\Client\SafeCurlHandler; | ||
6 | use GuzzleHttp\Client; | ||
7 | use GuzzleHttp\Cookie\CookieJar; | ||
8 | use GuzzleHttp\Event\SubscriberInterface; | ||
9 | |||
10 | /** | ||
11 | * Builds and configures the Guzzle HTTP client. | ||
12 | */ | ||
13 | class HttpClientFactory | ||
14 | { | ||
15 | /** @var \GuzzleHttp\Event\SubscriberInterface */ | ||
16 | private $authenticatorSubscriber; | ||
17 | |||
18 | /** @var \GuzzleHttp\Cookie\CookieJar */ | ||
19 | private $cookieJar; | ||
20 | |||
21 | private $restrictedAccess; | ||
22 | |||
23 | /** | ||
24 | * HttpClientFactory constructor. | ||
25 | * | ||
26 | * @param \GuzzleHttp\Event\SubscriberInterface $authenticatorSubscriber | ||
27 | * @param \GuzzleHttp\Cookie\CookieJar $cookieJar | ||
28 | * @param string $restrictedAccess this param is a kind of boolean. Values: 0 or 1 | ||
29 | */ | ||
30 | public function __construct(SubscriberInterface $authenticatorSubscriber, CookieJar $cookieJar, $restrictedAccess) | ||
31 | { | ||
32 | $this->authenticatorSubscriber = $authenticatorSubscriber; | ||
33 | $this->cookieJar = $cookieJar; | ||
34 | $this->restrictedAccess = $restrictedAccess; | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * @return \GuzzleHttp\Client|null | ||
39 | */ | ||
40 | public function buildHttpClient() | ||
41 | { | ||
42 | if (0 === (int) $this->restrictedAccess) { | ||
43 | return null; | ||
44 | } | ||
45 | |||
46 | // we clear the cookie to avoid websites who use cookies for analytics | ||
47 | $this->cookieJar->clear(); | ||
48 | // need to set the (shared) cookie jar | ||
49 | $client = new Client(['handler' => new SafeCurlHandler(), 'defaults' => ['cookies' => $this->cookieJar]]); | ||
50 | $client->getEmitter()->attach($this->authenticatorSubscriber); | ||
51 | |||
52 | return $client; | ||
53 | } | ||
54 | } | ||
diff --git a/src/Wallabag/CoreBundle/Helper/Redirect.php b/src/Wallabag/CoreBundle/Helper/Redirect.php index c14c79d1..f78b7fe0 100644 --- a/src/Wallabag/CoreBundle/Helper/Redirect.php +++ b/src/Wallabag/CoreBundle/Helper/Redirect.php | |||
@@ -3,6 +3,8 @@ | |||
3 | namespace Wallabag\CoreBundle\Helper; | 3 | namespace Wallabag\CoreBundle\Helper; |
4 | 4 | ||
5 | use Symfony\Component\Routing\Router; | 5 | use Symfony\Component\Routing\Router; |
6 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; | ||
7 | use Wallabag\CoreBundle\Entity\Config; | ||
6 | 8 | ||
7 | /** | 9 | /** |
8 | * Manage redirections to avoid redirecting to empty routes. | 10 | * Manage redirections to avoid redirecting to empty routes. |
@@ -10,10 +12,12 @@ use Symfony\Component\Routing\Router; | |||
10 | class Redirect | 12 | class Redirect |
11 | { | 13 | { |
12 | private $router; | 14 | private $router; |
15 | private $tokenStorage; | ||
13 | 16 | ||
14 | public function __construct(Router $router) | 17 | public function __construct(Router $router, TokenStorageInterface $tokenStorage) |
15 | { | 18 | { |
16 | $this->router = $router; | 19 | $this->router = $router; |
20 | $this->tokenStorage = $tokenStorage; | ||
17 | } | 21 | } |
18 | 22 | ||
19 | /** | 23 | /** |
@@ -24,6 +28,16 @@ class Redirect | |||
24 | */ | 28 | */ |
25 | public function to($url, $fallback = '') | 29 | public function to($url, $fallback = '') |
26 | { | 30 | { |
31 | $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null; | ||
32 | |||
33 | if (null === $user || !is_object($user)) { | ||
34 | return $url; | ||
35 | } | ||
36 | |||
37 | if (Config::REDIRECT_TO_HOMEPAGE === $user->getConfig()->getActionMarkAsRead()) { | ||
38 | return $this->router->generate('homepage'); | ||
39 | } | ||
40 | |||
27 | if (null !== $url) { | 41 | if (null !== $url) { |
28 | return $url; | 42 | return $url; |
29 | } | 43 | } |
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 4f03ae0f..b9532fa2 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php | |||
@@ -20,8 +20,7 @@ class EntryRepository extends EntityRepository | |||
20 | private function getBuilderByUser($userId) | 20 | private function getBuilderByUser($userId) |
21 | { | 21 | { |
22 | return $this->createQueryBuilder('e') | 22 | return $this->createQueryBuilder('e') |
23 | ->leftJoin('e.user', 'u') | 23 | ->andWhere('e.user = :userId')->setParameter('userId', $userId) |
24 | ->andWhere('u.id = :userId')->setParameter('userId', $userId) | ||
25 | ->orderBy('e.createdAt', 'desc') | 24 | ->orderBy('e.createdAt', 'desc') |
26 | ; | 25 | ; |
27 | } | 26 | } |
@@ -86,6 +85,36 @@ class EntryRepository extends EntityRepository | |||
86 | } | 85 | } |
87 | 86 | ||
88 | /** | 87 | /** |
88 | * Retrieves entries filtered with a search term for a user. | ||
89 | * | ||
90 | * @param int $userId | ||
91 | * @param string $term | ||
92 | * @param strint $currentRoute | ||
93 | * | ||
94 | * @return QueryBuilder | ||
95 | */ | ||
96 | public function getBuilderForSearchByUser($userId, $term, $currentRoute) | ||
97 | { | ||
98 | $qb = $this | ||
99 | ->getBuilderByUser($userId); | ||
100 | |||
101 | if ('starred' === $currentRoute) { | ||
102 | $qb->andWhere('e.isStarred = true'); | ||
103 | } elseif ('unread' === $currentRoute) { | ||
104 | $qb->andWhere('e.isArchived = false'); | ||
105 | } elseif ('archive' === $currentRoute) { | ||
106 | $qb->andWhere('e.isArchived = true'); | ||
107 | } | ||
108 | |||
109 | $qb | ||
110 | ->andWhere('e.content LIKE :term OR e.title LIKE :term')->setParameter('term', '%'.$term.'%') | ||
111 | ->leftJoin('e.tags', 't') | ||
112 | ->groupBy('e.id'); | ||
113 | |||
114 | return $qb; | ||
115 | } | ||
116 | |||
117 | /** | ||
89 | * Retrieves untagged entries for a user. | 118 | * Retrieves untagged entries for a user. |
90 | * | 119 | * |
91 | * @param int $userId | 120 | * @param int $userId |
@@ -96,9 +125,7 @@ class EntryRepository extends EntityRepository | |||
96 | { | 125 | { |
97 | return $this | 126 | return $this |
98 | ->getBuilderByUser($userId) | 127 | ->getBuilderByUser($userId) |
99 | ->leftJoin('e.tags', 't') | 128 | ->andWhere('size(e.tags) = 0'); |
100 | ->groupBy('e.id') | ||
101 | ->having('count(t.id) = 0'); | ||
102 | } | 129 | } |
103 | 130 | ||
104 | /** | 131 | /** |
@@ -144,7 +171,7 @@ class EntryRepository extends EntityRepository | |||
144 | $qb->orderBy('e.updatedAt', $order); | 171 | $qb->orderBy('e.updatedAt', $order); |
145 | } | 172 | } |
146 | 173 | ||
147 | $pagerAdapter = new DoctrineORMAdapter($qb); | 174 | $pagerAdapter = new DoctrineORMAdapter($qb, true, false); |
148 | 175 | ||
149 | return new Pagerfanta($pagerAdapter); | 176 | return new Pagerfanta($pagerAdapter); |
150 | } | 177 | } |
@@ -329,4 +356,18 @@ class EntryRepository extends EntityRepository | |||
329 | 356 | ||
330 | return $qb->getQuery()->getSingleScalarResult(); | 357 | return $qb->getQuery()->getSingleScalarResult(); |
331 | } | 358 | } |
359 | |||
360 | /** | ||
361 | * Remove all entries for a user id. | ||
362 | * Used when a user want to reset all informations. | ||
363 | * | ||
364 | * @param int $userId | ||
365 | */ | ||
366 | public function removeAllByUserId($userId) | ||
367 | { | ||
368 | $this->getEntityManager() | ||
369 | ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = :userId') | ||
370 | ->setParameter('userId', $userId) | ||
371 | ->execute(); | ||
372 | } | ||
332 | } | 373 | } |
diff --git a/src/Wallabag/CoreBundle/Repository/TagRepository.php b/src/Wallabag/CoreBundle/Repository/TagRepository.php index e76878d4..81445989 100644 --- a/src/Wallabag/CoreBundle/Repository/TagRepository.php +++ b/src/Wallabag/CoreBundle/Repository/TagRepository.php | |||
@@ -34,6 +34,9 @@ class TagRepository extends EntityRepository | |||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Find all tags per user. | 36 | * Find all tags per user. |
37 | * Instead of just left joined on the Entry table, we select only id and group by id to avoid tag multiplication in results. | ||
38 | * Once we have all tags id, we can safely request them one by one. | ||
39 | * This'll still be fastest than the previous query. | ||
37 | * | 40 | * |
38 | * @param int $userId | 41 | * @param int $userId |
39 | * | 42 | * |
@@ -41,15 +44,20 @@ class TagRepository extends EntityRepository | |||
41 | */ | 44 | */ |
42 | public function findAllTags($userId) | 45 | public function findAllTags($userId) |
43 | { | 46 | { |
44 | return $this->createQueryBuilder('t') | 47 | $ids = $this->createQueryBuilder('t') |
45 | ->select('t.slug', 't.label', 't.id') | 48 | ->select('t.id') |
46 | ->leftJoin('t.entries', 'e') | 49 | ->leftJoin('t.entries', 'e') |
47 | ->where('e.user = :userId')->setParameter('userId', $userId) | 50 | ->where('e.user = :userId')->setParameter('userId', $userId) |
48 | ->groupBy('t.slug') | 51 | ->groupBy('t.id') |
49 | ->addGroupBy('t.label') | ||
50 | ->addGroupBy('t.id') | ||
51 | ->getQuery() | 52 | ->getQuery() |
52 | ->getArrayResult(); | 53 | ->getArrayResult(); |
54 | |||
55 | $tags = []; | ||
56 | foreach ($ids as $id) { | ||
57 | $tags[] = $this->find($id); | ||
58 | } | ||
59 | |||
60 | return $tags; | ||
53 | } | 61 | } |
54 | 62 | ||
55 | /** | 63 | /** |
diff --git a/src/Wallabag/CoreBundle/Resources/config/parameters.yml b/src/Wallabag/CoreBundle/Resources/config/parameters.yml index 6068e84c..4948f385 100644 --- a/src/Wallabag/CoreBundle/Resources/config/parameters.yml +++ b/src/Wallabag/CoreBundle/Resources/config/parameters.yml | |||
@@ -1,8 +1,9 @@ | |||
1 | parameters: | 1 | parameters: |
2 | addons_url: | 2 | addons_url: |
3 | firefox: https://addons.mozilla.org/firefox/addon/wallabag-v2/ | 3 | firefox: https://addons.mozilla.org/firefox/addon/wallabagger/ |
4 | chrome: https://chrome.google.com/webstore/detail/wallabagit/peehlcgckcnclnjlndmoddifcicdnabm | 4 | chrome: https://chrome.google.com/webstore/detail/wallabagger/gbmgphmejlcoihgedabhgjdkcahacjlj |
5 | opera: https://addons.opera.com/en/extensions/details/wallabagger/?display=en | ||
5 | f_droid: https://f-droid.org/app/fr.gaulupeau.apps.InThePoche | 6 | f_droid: https://f-droid.org/app/fr.gaulupeau.apps.InThePoche |
6 | google_play: https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche | 7 | google_play: https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche |
7 | ios: https://itunes.apple.com/app/wallabag/id828331015?mt=8 | 8 | ios: https://itunes.apple.com/app/wallabag-2/id1170800946?mt=8 |
8 | windows: https://www.microsoft.com/store/apps/wallabag/9nblggh11646 | 9 | windows: https://www.microsoft.com/store/apps/wallabag/9nblggh11646 |
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml index ed66d2be..fadd5e49 100644 --- a/src/Wallabag/CoreBundle/Resources/config/services.yml +++ b/src/Wallabag/CoreBundle/Resources/config/services.yml | |||
@@ -30,7 +30,7 @@ services: | |||
30 | - "@doctrine" | 30 | - "@doctrine" |
31 | 31 | ||
32 | wallabag_core.subscriber.table_prefix: | 32 | wallabag_core.subscriber.table_prefix: |
33 | class: Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber | 33 | class: Wallabag\CoreBundle\Event\Subscriber\TablePrefixSubscriber |
34 | arguments: | 34 | arguments: |
35 | - "%database_table_prefix%" | 35 | - "%database_table_prefix%" |
36 | tags: | 36 | tags: |
@@ -41,11 +41,44 @@ services: | |||
41 | arguments: | 41 | arguments: |
42 | - | 42 | - |
43 | error_message: '%wallabag_core.fetching_error_message%' | 43 | error_message: '%wallabag_core.fetching_error_message%' |
44 | - "@wallabag_core.guzzle.http_client" | ||
45 | - "@wallabag_core.graby.config_builder" | ||
44 | calls: | 46 | calls: |
45 | - [ setLogger, [ "@logger" ] ] | 47 | - [ setLogger, [ "@logger" ] ] |
46 | tags: | 48 | tags: |
47 | - { name: monolog.logger, channel: graby } | 49 | - { name: monolog.logger, channel: graby } |
48 | 50 | ||
51 | wallabag_core.graby.config_builder: | ||
52 | class: Graby\SiteConfig\ConfigBuilder | ||
53 | arguments: | ||
54 | - {} | ||
55 | - "@logger" | ||
56 | |||
57 | wallabag_core.guzzle.http_client: | ||
58 | class: GuzzleHttp\ClientInterface | ||
59 | factory: ["@wallabag_core.guzzle.http_client_factory", buildHttpClient] | ||
60 | |||
61 | wallabag_core.guzzle_authenticator.config_builder: | ||
62 | class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder | ||
63 | arguments: | ||
64 | - "@wallabag_core.graby.config_builder" | ||
65 | - "%sites_credentials%" | ||
66 | |||
67 | # service alias override | ||
68 | bd_guzzle_site_authenticator.site_config_builder: | ||
69 | alias: wallabag_core.guzzle_authenticator.config_builder | ||
70 | |||
71 | wallabag_core.guzzle.http_client_factory: | ||
72 | class: Wallabag\CoreBundle\Helper\HttpClientFactory | ||
73 | arguments: | ||
74 | - "@bd_guzzle_site_authenticator.authenticator_subscriber" | ||
75 | - "@wallabag_core.guzzle.cookie_jar" | ||
76 | - '@=service(''craue_config'').get(''restricted_access'')' | ||
77 | |||
78 | wallabag_core.guzzle.cookie_jar: | ||
79 | class: GuzzleHttp\Cookie\FileCookieJar | ||
80 | arguments: ["%kernel.cache_dir%/cookiejar.json"] | ||
81 | |||
49 | wallabag_core.content_proxy: | 82 | wallabag_core.content_proxy: |
50 | class: Wallabag\CoreBundle\Helper\ContentProxy | 83 | class: Wallabag\CoreBundle\Helper\ContentProxy |
51 | arguments: | 84 | arguments: |
@@ -53,6 +86,7 @@ services: | |||
53 | - "@wallabag_core.rule_based_tagger" | 86 | - "@wallabag_core.rule_based_tagger" |
54 | - "@wallabag_core.tag_repository" | 87 | - "@wallabag_core.tag_repository" |
55 | - "@logger" | 88 | - "@logger" |
89 | - '%wallabag_core.fetching_error_message%' | ||
56 | 90 | ||
57 | wallabag_core.rule_based_tagger: | 91 | wallabag_core.rule_based_tagger: |
58 | class: Wallabag\CoreBundle\Helper\RuleBasedTagger | 92 | class: Wallabag\CoreBundle\Helper\RuleBasedTagger |
@@ -94,6 +128,7 @@ services: | |||
94 | class: Wallabag\CoreBundle\Helper\Redirect | 128 | class: Wallabag\CoreBundle\Helper\Redirect |
95 | arguments: | 129 | arguments: |
96 | - "@router" | 130 | - "@router" |
131 | - "@security.token_storage" | ||
97 | 132 | ||
98 | wallabag_core.helper.prepare_pager_for_entries: | 133 | wallabag_core.helper.prepare_pager_for_entries: |
99 | class: Wallabag\CoreBundle\Helper\PreparePagerForEntries | 134 | class: Wallabag\CoreBundle\Helper\PreparePagerForEntries |
@@ -109,9 +144,38 @@ services: | |||
109 | host: '%redis_host%' | 144 | host: '%redis_host%' |
110 | port: '%redis_port%' | 145 | port: '%redis_port%' |
111 | path: '%redis_path%' | 146 | path: '%redis_path%' |
147 | password: '%redis_password%' | ||
112 | 148 | ||
113 | wallabag_core.exception_controller: | 149 | wallabag_core.exception_controller: |
114 | class: Wallabag\CoreBundle\Controller\ExceptionController | 150 | class: Wallabag\CoreBundle\Controller\ExceptionController |
115 | arguments: | 151 | arguments: |
116 | - '@twig' | 152 | - '@twig' |
117 | - '%kernel.debug%' | 153 | - '%kernel.debug%' |
154 | |||
155 | wallabag_core.subscriber.sqlite_cascade_delete: | ||
156 | class: Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber | ||
157 | arguments: | ||
158 | - "@doctrine" | ||
159 | tags: | ||
160 | - { name: doctrine.event_subscriber } | ||
161 | |||
162 | wallabag_core.subscriber.download_images: | ||
163 | class: Wallabag\CoreBundle\Event\Subscriber\DownloadImagesSubscriber | ||
164 | arguments: | ||
165 | - "@doctrine.orm.default_entity_manager" | ||
166 | - "@wallabag_core.entry.download_images" | ||
167 | - '@=service(''craue_config'').get(''download_images_enabled'')' | ||
168 | - "@logger" | ||
169 | tags: | ||
170 | - { name: kernel.event_subscriber } | ||
171 | |||
172 | wallabag_core.entry.download_images: | ||
173 | class: Wallabag\CoreBundle\Helper\DownloadImages | ||
174 | arguments: | ||
175 | - "@wallabag_core.entry.download_images.client" | ||
176 | - "%kernel.root_dir%/../web/assets/images" | ||
177 | - '@=service(''craue_config'').get(''wallabag_url'')' | ||
178 | - "@logger" | ||
179 | |||
180 | wallabag_core.entry.download_images.client: | ||
181 | class: GuzzleHttp\Client | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml index a1bee173..3380edca 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | # 200_word: 'I read ~200 words per minute' | 70 | # 200_word: 'I read ~200 words per minute' |
71 | # 300_word: 'I read ~300 words per minute' | 71 | # 300_word: 'I read ~300 words per minute' |
72 | # 400_word: 'I read ~400 words per minute' | 72 | # 400_word: 'I read ~400 words per minute' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: Brugers nøgle til Pocket for at importere materialer | 77 | pocket_consumer_key_label: Brugers nøgle til Pocket for at importere materialer |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'Emailadresse' | 99 | email_label: 'Emailadresse' |
95 | # twoFactorAuthentication_label: 'Two factor authentication' | 100 | # twoFactorAuthentication_label: 'Two factor authentication' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Gammel adgangskode' | 116 | old_password_label: 'Gammel adgangskode' |
@@ -145,6 +162,7 @@ entry: | |||
145 | # archived: 'Archived entries' | 162 | # archived: 'Archived entries' |
146 | # filtered: 'Filtered entries' | 163 | # filtered: 'Filtered entries' |
147 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' | 168 | # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Har et vist billede' | 186 | preview_picture_label: 'Har et vist billede' |
169 | preview_picture_help: 'Forhåndsvis billede' | 187 | preview_picture_help: 'Forhåndsvis billede' |
170 | language_label: 'Sprog' | 188 | language_label: 'Sprog' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Læsetid i minutter' | 191 | label: 'Læsetid i minutter' |
173 | from: 'fra' | 192 | from: 'fra' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | # page_title: 'Edit an entry' | 234 | # page_title: 'Edit an entry' |
214 | # title_label: 'Title' | 235 | # title_label: 'Title' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'How-to' | 274 | page_title: 'How-to' |
254 | # page_description: 'There are several ways to save an article:' | 275 | # page_description: 'There are several ways to save an article:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Browserudvidelser' | 280 | browser_addons: 'Browserudvidelser' |
257 | mobile_apps: 'Apps' | 281 | mobile_apps: 'Apps' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Standardudvidelse til Firefox' | 286 | firefox: 'Standardudvidelse til Firefox' |
263 | chrome: 'Chrome-udvidelse' | 287 | chrome: 'Chrome-udvidelse' |
288 | opera: 'Opera-udvidelse' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | # windows: 'on the Microsoft Store' | 294 | # windows: 'on the Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Træk dette link til din bogmærkeliste:' | 296 | description: 'Træk dette link til din bogmærkeliste:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | # page_title: 'Quickstart' | 326 | # page_title: 'Quickstart' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' | 382 | # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' |
331 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | # page_title: 'Import' | 389 | # page_title: 'Import' |
@@ -362,6 +417,7 @@ import: | |||
362 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
363 | worker: | 418 | worker: |
364 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | # firefox: | 421 | # firefox: |
366 | # page_title: 'Import > Firefox' | 422 | # page_title: 'Import > Firefox' |
367 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | # page_title: 'Import > Instapaper' | 430 | # page_title: 'Import > Instapaper' |
375 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
376 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | # page_title: 'Developer' | 439 | # page_title: 'Developer' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'Emailadresse' | 505 | email_label: 'Emailadresse' |
446 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
447 | # locked_label: 'Locked' | ||
448 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
449 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
450 | # save: Save | 509 | # save: Save |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'RSS-oplysninger opdateret' | 524 | rss_updated: 'RSS-oplysninger opdateret' |
466 | # tagging_rules_updated: 'Tagging rules updated' | 525 | # tagging_rules_updated: 'Tagging rules updated' |
467 | # tagging_rules_deleted: 'Tagging rule deleted' | 526 | # tagging_rules_deleted: 'Tagging rule deleted' |
468 | # user_added: 'User "%username%" added' | ||
469 | # rss_token_updated: 'RSS token updated' | 527 | # rss_token_updated: 'RSS token updated' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | # entry_already_saved: 'Entry already saved on %date%' | 533 | # entry_already_saved: 'Entry already saved on %date%' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | # client_created: 'New client created.' | 558 | # client_created: 'New client created.' |
498 | # client_deleted: 'Client deleted' | 559 | # client_deleted: 'Client deleted' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml index c9625d06..cfa11e82 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'Ich lese ~200 Wörter pro Minute' | 70 | 200_word: 'Ich lese ~200 Wörter pro Minute' |
71 | 300_word: 'Ich lese ~300 Wörter pro Minute' | 71 | 300_word: 'Ich lese ~300 Wörter pro Minute' |
72 | 400_word: 'Ich lese ~400 Wörter pro Minute' | 72 | 400_word: 'Ich lese ~400 Wörter pro Minute' |
73 | action_mark_as_read: | ||
74 | label: 'Wohin soll nach dem Gelesenmarkieren eines Artikels weitergeleitet werden?' | ||
75 | redirect_homepage: 'Zur Homepage' | ||
76 | redirect_current_page: 'Zur aktuellen Seite' | ||
73 | pocket_consumer_key_label: Consumer-Key für Pocket, um Inhalte zu importieren | 77 | pocket_consumer_key_label: Consumer-Key für Pocket, um Inhalte zu importieren |
78 | android_configuration: Konfiguriere deine Android Application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'E-Mail-Adresse' | 99 | email_label: 'E-Mail-Adresse' |
95 | twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' | 100 | twoFactorAuthentication_label: 'Zwei-Faktor-Authentifizierung' |
96 | # 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: | ||
103 | title: Lösche mein Konto (a.k.a Gefahrenzone) | ||
104 | description: Wenn du dein Konto löschst, werden ALL deine Artikel, ALL deine Tags, ALL deine Anmerkungen und dein Konto dauerhaft gelöscht (kann NICHT RÜCKGÄNGIG gemacht werden). Du wirst anschließend ausgeloggt. | ||
105 | confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN) | ||
106 | button: Lösche mein Konto | ||
107 | reset: | ||
108 | title: Zurücksetzen (a.k.a Gefahrenzone) | ||
109 | description: Beim Nutzen der folgenden Schaltflächenhast du die Möglichkeit, einige Informationen von deinem Konto zu entfernen. Sei dir bewusst, dass dies NICHT RÜCKGÄNGIG zu machen ist. | ||
110 | annotations: Entferne ALLE Annotationen | ||
111 | tags: Entferne ALLE Tags | ||
112 | entries: Entferne ALLE Einträge | ||
113 | confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Altes Kennwort' | 116 | old_password_label: 'Altes Kennwort' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Archivierte Einträge' | 162 | archived: 'Archivierte Einträge' |
146 | filtered: 'Gefilterte Einträge' | 163 | filtered: 'Gefilterte Einträge' |
147 | filtered_tags: 'Gefiltert nach Tags:' | 164 | filtered_tags: 'Gefiltert nach Tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | untagged: 'Nicht getaggte Einträge' | 166 | untagged: 'Nicht getaggte Einträge' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' | 168 | number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Vorschaubild vorhanden' | 186 | preview_picture_label: 'Vorschaubild vorhanden' |
169 | preview_picture_help: 'Vorschaubild' | 187 | preview_picture_help: 'Vorschaubild' |
170 | language_label: 'Sprache' | 188 | language_label: 'Sprache' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Lesezeit in Minuten' | 191 | label: 'Lesezeit in Minuten' |
173 | from: 'von' | 192 | from: 'von' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'https://website.de' | 228 | placeholder: 'https://website.de' |
210 | form_new: | 229 | form_new: |
211 | url_label: URL | 230 | url_label: URL |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Eintrag bearbeiten' | 234 | page_title: 'Eintrag bearbeiten' |
214 | title_label: 'Titel' | 235 | title_label: 'Titel' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'How-To' | 274 | page_title: 'How-To' |
254 | page_description: 'Es gibt mehrere Möglichkeiten, einen Artikel zu speichern:' | 275 | page_description: 'Es gibt mehrere Möglichkeiten, einen Artikel zu speichern:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Browser-Erweiterungen' | 280 | browser_addons: 'Browser-Erweiterungen' |
257 | mobile_apps: 'Apps' | 281 | mobile_apps: 'Apps' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Firefox-Erweiterung' | 286 | firefox: 'Firefox-Erweiterung' |
263 | chrome: 'Chrome-Erweiterung' | 287 | chrome: 'Chrome-Erweiterung' |
288 | opera: 'Opera-Erweiterung' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'im Microsoft-Store' | 294 | windows: 'im Microsoft-Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Ziehe diesen Link in deine Lesezeichenleiste:' | 296 | description: 'Ziehe diesen Link in deine Lesezeichenleiste:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Schnelleinstieg' | 326 | page_title: 'Schnelleinstieg' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: '{0} Es gibt keine Tags.|{1} Es gibt einen Tag.|]1,Inf[ Es gibt %count% Tags.' | 382 | number_on_the_page: '{0} Es gibt keine Tags.|{1} Es gibt einen Tag.|]1,Inf[ Es gibt %count% Tags.' |
331 | see_untagged_entries: 'Zeige nicht getaggte Einträge' | 383 | see_untagged_entries: 'Zeige nicht getaggte Einträge' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Importieren' | 389 | page_title: 'Importieren' |
@@ -362,6 +417,7 @@ import: | |||
362 | how_to: 'Bitte wähle deinen Readability Export aus und klicke den unteren Button für das Hochladen und Importieren dessen.' | 417 | how_to: 'Bitte wähle deinen Readability Export aus und klicke den unteren Button für das Hochladen und Importieren dessen.' |
363 | worker: | 418 | worker: |
364 | enabled: "Der Import erfolgt asynchron. Sobald der Import gestartet ist, wird diese Aufgabe extern abgearbeitet. Der aktuelle Service dafür ist:" | 419 | enabled: "Der Import erfolgt asynchron. Sobald der Import gestartet ist, wird diese Aufgabe extern abgearbeitet. Der aktuelle Service dafür ist:" |
420 | download_images_warning: "Du hast das Herunterladen von Bildern für deine Artikel aktiviert. Verbunden mit dem klassischen Import kann es ewig dauern fortzufahren (oder sogar fehlschlagen). Wir <strong>empfehlen</strong> den asynchronen Import zu aktivieren, um Fehler zu vermeiden." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Aus Firefox importieren' | 422 | page_title: 'Aus Firefox importieren' |
367 | description: "Dieser Import wird all deine Lesezeichen aus Firefox importieren. Gehe zu deinen Lesezeichen (Strg+Shift+O), dann auf \"Importen und Sichern\", wähle \"Sichern…\". Du erhälst eine .json Datei." | 423 | description: "Dieser Import wird all deine Lesezeichen aus Firefox importieren. Gehe zu deinen Lesezeichen (Strg+Shift+O), dann auf \"Importen und Sichern\", wähle \"Sichern…\". Du erhälst eine .json Datei." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Aus Instapaper importieren' | 430 | page_title: 'Aus Instapaper importieren' |
375 | description: 'Dieser Import wird all deine Instapaper Artikel importieren. Auf der Einstellungsseite (https://www.instapaper.com/user) klickst du auf "Download .CSV Datei" in dem Abschnitt "Export". Eine CSV Datei wird heruntergeladen (z.B. "instapaper-export.csv").' | 431 | description: 'Dieser Import wird all deine Instapaper Artikel importieren. Auf der Einstellungsseite (https://www.instapaper.com/user) klickst du auf "Download .CSV Datei" in dem Abschnitt "Export". Eine CSV Datei wird heruntergeladen (z.B. "instapaper-export.csv").' |
376 | how_to: "Bitte wähle deine Instapaper Sicherungsdatei aus und klicke den nachfolgenden Button zum Importieren." | 432 | how_to: "Bitte wähle deine Instapaper Sicherungsdatei aus und klicke den nachfolgenden Button zum Importieren." |
433 | pinboard: | ||
434 | page_title: "Aus Pinboard importieren" | ||
435 | description: 'Dieser Import wird all deine Pinboard Artikel importieren. Auf der Seite Backup (https://pinboard.in/settings/backup) klickst du auf "JSON" in dem Abschnitt "Lesezeichen". Eine JSON Datei wird dann heruntergeladen (z.B. "pinboard_export").' | ||
436 | how_to: 'Bitte wähle deinen Pinboard Export aus und klicke den nachfolgenden Button zum Importieren.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Entwickler' | 439 | page_title: 'Entwickler' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'E-Mail-Adresse' | 505 | email_label: 'E-Mail-Adresse' |
446 | enabled_label: 'Aktiviert' | 506 | enabled_label: 'Aktiviert' |
447 | locked_label: 'Gesperrt' | ||
448 | last_login_label: 'Letzter Login' | 507 | last_login_label: 'Letzter Login' |
449 | twofactor_label: Zwei-Faktor-Authentifizierung | 508 | twofactor_label: Zwei-Faktor-Authentifizierung |
450 | save: Speichern | 509 | save: Speichern |
@@ -453,7 +512,7 @@ user: | |||
453 | back_to_list: Zurück zur Liste | 512 | back_to_list: Zurück zur Liste |
454 | 513 | ||
455 | error: | 514 | error: |
456 | # page_title: An error occurred | 515 | page_title: Ein Fehler ist aufgetreten |
457 | 516 | ||
458 | flashes: | 517 | flashes: |
459 | config: | 518 | config: |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'RSS-Informationen aktualisiert' | 524 | rss_updated: 'RSS-Informationen aktualisiert' |
466 | tagging_rules_updated: 'Tagging-Regeln aktualisiert' | 525 | tagging_rules_updated: 'Tagging-Regeln aktualisiert' |
467 | tagging_rules_deleted: 'Tagging-Regel gelöscht' | 526 | tagging_rules_deleted: 'Tagging-Regel gelöscht' |
468 | user_added: 'Benutzer "%username%" erstellt' | ||
469 | rss_token_updated: 'RSS-Token aktualisiert' | 527 | rss_token_updated: 'RSS-Token aktualisiert' |
528 | annotations_reset: Anmerkungen zurücksetzen | ||
529 | tags_reset: Tags zurücksetzen | ||
530 | entries_reset: Einträge zurücksetzen | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: 'Eintrag bereits am %date% gespeichert' | 533 | entry_already_saved: 'Eintrag bereits am %date% gespeichert' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: 'Neuer Client erstellt.' | 558 | client_created: 'Neuer Client erstellt.' |
498 | client_deleted: 'Client gelöscht' | 559 | client_deleted: 'Client gelöscht' |
560 | user: | ||
561 | notice: | ||
562 | added: 'Benutzer "%username%" hinzugefügt' | ||
563 | updated: 'Benutzer "%username%" aktualisiert' | ||
564 | deleted: 'Benutzer "%username%" gelöscht' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index 139cdc24..673a0a16 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'I read ~200 words per minute' | 70 | 200_word: 'I read ~200 words per minute' |
71 | 300_word: 'I read ~300 words per minute' | 71 | 300_word: 'I read ~300 words per minute' |
72 | 400_word: 'I read ~400 words per minute' | 72 | 400_word: 'I read ~400 words per minute' |
73 | action_mark_as_read: | ||
74 | label: 'Where do you want to be redirected after mark an article as read?' | ||
75 | redirect_homepage: 'To the homepage' | ||
76 | redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: Consumer key for Pocket to import contents | 77 | pocket_consumer_key_label: Consumer key for Pocket to import contents |
78 | android_configuration: Configure your Android application | ||
74 | help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | help_items_per_page: "You can change the number of articles displayed on each page." | 80 | help_items_per_page: "You can change the number of articles displayed on each page." |
76 | help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'Email' | 99 | email_label: 'Email' |
95 | twoFactorAuthentication_label: 'Two factor authentication' | 100 | twoFactorAuthentication_label: 'Two factor authentication' |
96 | 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: | ||
103 | title: Delete my account (a.k.a danger zone) | ||
104 | description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | button: Delete my account | ||
107 | reset: | ||
108 | title: Reset area (a.k.a danger zone) | ||
109 | description: By hitting buttons below you'll have ability to remove some information from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | annotations: Remove ALL annotations | ||
111 | tags: Remove ALL tags | ||
112 | entries: Remove ALL entries | ||
113 | confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Current password' | 116 | old_password_label: 'Current password' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Archived entries' | 162 | archived: 'Archived entries' |
146 | filtered: 'Filtered entries' | 163 | filtered: 'Filtered entries' |
147 | filtered_tags: 'Filtered by tags:' | 164 | filtered_tags: 'Filtered by tags:' |
165 | filtered_search: 'Filtered by search:' | ||
148 | untagged: 'Untagged entries' | 166 | untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' | 168 | number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Has a preview picture' | 186 | preview_picture_label: 'Has a preview picture' |
169 | preview_picture_help: 'Preview picture' | 187 | preview_picture_help: 'Preview picture' |
170 | language_label: 'Language' | 188 | language_label: 'Language' |
189 | http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Reading time in minutes' | 191 | label: 'Reading time in minutes' |
173 | from: 'from' | 192 | from: 'from' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Edit an entry' | 234 | page_title: 'Edit an entry' |
214 | title_label: 'Title' | 235 | title_label: 'Title' |
@@ -251,6 +272,9 @@ about: | |||
251 | 272 | ||
252 | howto: | 273 | howto: |
253 | page_title: 'How to' | 274 | page_title: 'How to' |
275 | tab_menu: | ||
276 | add_link: "Add a link" | ||
277 | shortcuts: "Use shortcuts" | ||
254 | page_description: 'There are several ways to save an article:' | 278 | page_description: 'There are several ways to save an article:' |
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Browser addons' | 280 | browser_addons: 'Browser addons' |
@@ -259,8 +283,9 @@ howto: | |||
259 | form: | 283 | form: |
260 | description: 'Thanks to this form' | 284 | description: 'Thanks to this form' |
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Standard Firefox Add-On' | 286 | firefox: 'Firefox addon' |
263 | chrome: 'Chrome Extension' | 287 | chrome: 'Chrome addon' |
288 | opera: 'Opera addon' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'on the Microsoft Store' | 294 | windows: 'on the Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Drag & drop this link to your bookmarks bar:' | 296 | description: 'Drag & drop this link to your bookmarks bar:' |
297 | shortcuts: | ||
298 | page_description: Here are the shortcuts available in wallabag. | ||
299 | shortcut: Shortcut | ||
300 | action: Action | ||
301 | all_pages_title: Shortcuts available in all pages | ||
302 | go_unread: Go to unread | ||
303 | go_starred: Go to starred | ||
304 | go_archive: Go to archive | ||
305 | go_all: Go to all entries | ||
306 | go_tags: Go to tags | ||
307 | go_config: Go to config | ||
308 | go_import: Go to import | ||
309 | go_developers: Go to developers | ||
310 | go_howto: Go to howto (this page!) | ||
311 | go_logout: Logout | ||
312 | list_title: Shortcuts available in listing pages | ||
313 | search: Display the search form | ||
314 | article_title: Shortcuts available in entry view | ||
315 | open_original: Open original URL of the entry | ||
316 | toggle_favorite: Toggle star status for the entry | ||
317 | toggle_archive: Toggle read status for the entry | ||
318 | delete: Delete the entry | ||
319 | material_title: Shortcuts available with Material theme only | ||
320 | add_link: Add a new link | ||
321 | hide_form: Hide the current form (search or new link) | ||
322 | arrows_navigation: Navigate through articles | ||
323 | open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Quickstart' | 326 | page_title: 'Quickstart' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.' | 382 | number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.' |
331 | see_untagged_entries: 'See untagged entries' | 383 | see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | add: 'Add' | ||
386 | placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Import' | 389 | page_title: 'Import' |
@@ -362,6 +417,7 @@ import: | |||
362 | how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
363 | worker: | 418 | worker: |
364 | enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Import > Firefox' | 422 | page_title: 'Import > Firefox' |
367 | description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Import > Instapaper' | 430 | page_title: 'Import > Instapaper' |
375 | description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
376 | how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | page_title: "Import > Pinboard" | ||
435 | description: 'This importer will import all your Pinboard articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Developer' | 439 | page_title: 'Developer' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'Email' | 505 | email_label: 'Email' |
446 | enabled_label: 'Enabled' | 506 | enabled_label: 'Enabled' |
447 | locked_label: 'Locked' | ||
448 | last_login_label: 'Last login' | 507 | last_login_label: 'Last login' |
449 | twofactor_label: Two factor authentication | 508 | twofactor_label: Two factor authentication |
450 | save: Save | 509 | save: Save |
@@ -466,6 +525,9 @@ flashes: | |||
466 | tagging_rules_updated: 'Tagging rules updated' | 525 | tagging_rules_updated: 'Tagging rules updated' |
467 | tagging_rules_deleted: 'Tagging rule deleted' | 526 | tagging_rules_deleted: 'Tagging rule deleted' |
468 | rss_token_updated: 'RSS token updated' | 527 | rss_token_updated: 'RSS token updated' |
528 | annotations_reset: Annotations reset | ||
529 | tags_reset: Tags reset | ||
530 | entries_reset: Entries reset | ||
469 | entry: | 531 | entry: |
470 | notice: | 532 | notice: |
471 | entry_already_saved: 'Entry already saved on %date%' | 533 | entry_already_saved: 'Entry already saved on %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml index 70e64bec..d08edd6e 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'Leo ~200 palabras por minuto' | 70 | 200_word: 'Leo ~200 palabras por minuto' |
71 | 300_word: 'Leo ~300 palabras por minuto' | 71 | 300_word: 'Leo ~300 palabras por minuto' |
72 | 400_word: 'Leo ~400 palabras por minuto' | 72 | 400_word: 'Leo ~400 palabras por minuto' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | # pocket_consumer_key_label: Consumer key for Pocket to import contents | 77 | # pocket_consumer_key_label: Consumer key for Pocket to import contents |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'Direccion e-mail' | 99 | email_label: 'Direccion e-mail' |
95 | twoFactorAuthentication_label: 'Autentificación de dos factores' | 100 | twoFactorAuthentication_label: 'Autentificación de dos factores' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Contraseña actual' | 116 | old_password_label: 'Contraseña actual' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Artículos archivados' | 162 | archived: 'Artículos archivados' |
146 | filtered: 'Artículos filtrados' | 163 | filtered: 'Artículos filtrados' |
147 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' | 168 | number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Hay una foto' | 186 | preview_picture_label: 'Hay una foto' |
169 | preview_picture_help: 'Foto de preview' | 187 | preview_picture_help: 'Foto de preview' |
170 | language_label: 'Idioma' | 188 | language_label: 'Idioma' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Duración de lectura en minutos' | 191 | label: 'Duración de lectura en minutos' |
173 | from: 'de' | 192 | from: 'de' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Editar un artículo' | 234 | page_title: 'Editar un artículo' |
214 | title_label: 'Título' | 235 | title_label: 'Título' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'Ayuda' | 274 | page_title: 'Ayuda' |
254 | page_description: 'Hay muchas maneras para guardar un artículo:' | 275 | page_description: 'Hay muchas maneras para guardar un artículo:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Extensiones de navigador' | 280 | browser_addons: 'Extensiones de navigador' |
257 | mobile_apps: 'Aplicaciones para smartphone' | 281 | mobile_apps: 'Aplicaciones para smartphone' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Extensión Firefox' | 286 | firefox: 'Extensión Firefox' |
263 | chrome: 'Extensión Chrome' | 287 | chrome: 'Extensión Chrome' |
288 | opera: 'Extensión Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'por la tienda de Microsoft' | 294 | windows: 'por la tienda de Microsoft' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Desplazar y soltar este link en la barra de marcadores :' | 296 | description: 'Desplazar y soltar este link en la barra de marcadores :' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Comienzo rápido' | 326 | page_title: 'Comienzo rápido' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: '{0} No hay ninguna etiqueta.|{1} Hay una etiqueta.|]1,Inf[ Hay %count% etiquetas.' | 382 | number_on_the_page: '{0} No hay ninguna etiqueta.|{1} Hay una etiqueta.|]1,Inf[ Hay %count% etiquetas.' |
331 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Importar' | 389 | page_title: 'Importar' |
@@ -362,6 +417,7 @@ import: | |||
362 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
363 | worker: | 418 | worker: |
364 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Importar > Firefox' | 422 | page_title: 'Importar > Firefox' |
367 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Importar > Instapaper' | 430 | page_title: 'Importar > Instapaper' |
375 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
376 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | page_title: "Importar > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Promotor' | 439 | page_title: 'Promotor' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'Email' | 505 | email_label: 'Email' |
446 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
447 | # locked_label: 'Locked' | ||
448 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
449 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
450 | # save: Save | 509 | # save: Save |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'La configuración de los feeds RSS ha sido actualizada' | 524 | rss_updated: 'La configuración de los feeds RSS ha sido actualizada' |
466 | tagging_rules_updated: 'Regla de etiquetado borrada' | 525 | tagging_rules_updated: 'Regla de etiquetado borrada' |
467 | tagging_rules_deleted: 'Regla de etiquetado actualizada' | 526 | tagging_rules_deleted: 'Regla de etiquetado actualizada' |
468 | user_added: 'Usuario "%username%" añadido' | ||
469 | rss_token_updated: 'RSS token actualizado' | 527 | rss_token_updated: 'RSS token actualizado' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: 'Entrada ya guardada por %fecha%' | 533 | entry_already_saved: 'Entrada ya guardada por %fecha%' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: 'Nuevo cliente creado.' | 558 | client_created: 'Nuevo cliente creado.' |
498 | client_deleted: 'Cliente suprimido' | 559 | client_deleted: 'Cliente suprimido' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml index 75359901..ad6144b8 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'من تقریباً ۲۰۰ واژه را در دقیقه میخوانم' | 70 | 200_word: 'من تقریباً ۲۰۰ واژه را در دقیقه میخوانم' |
71 | 300_word: 'من تقریباً ۳۰۰ واژه را در دقیقه میخوانم' | 71 | 300_word: 'من تقریباً ۳۰۰ واژه را در دقیقه میخوانم' |
72 | 400_word: 'من تقریباً ۴۰۰ واژه را در دقیقه میخوانم' | 72 | 400_word: 'من تقریباً ۴۰۰ واژه را در دقیقه میخوانم' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: کلید کاربری Pocket برای درونریزی مطالب | 77 | pocket_consumer_key_label: کلید کاربری Pocket برای درونریزی مطالب |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'نشانی ایمیل' | 99 | email_label: 'نشانی ایمیل' |
95 | twoFactorAuthentication_label: 'تأیید ۲مرحلهای' | 100 | twoFactorAuthentication_label: 'تأیید ۲مرحلهای' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'رمز قدیمی' | 116 | old_password_label: 'رمز قدیمی' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'مقالههای بایگانیشده' | 162 | archived: 'مقالههای بایگانیشده' |
146 | filtered: 'مقالههای فیلترشده' | 163 | filtered: 'مقالههای فیلترشده' |
147 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} هیج مقالهای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' | 168 | number_on_the_page: '{0} هیج مقالهای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'دارای عکس پیشنمایش' | 186 | preview_picture_label: 'دارای عکس پیشنمایش' |
169 | preview_picture_help: 'پیشنمایش عکس' | 187 | preview_picture_help: 'پیشنمایش عکس' |
170 | language_label: 'زبان' | 188 | language_label: 'زبان' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'زمان خواندن به دقیقه' | 191 | label: 'زمان خواندن به دقیقه' |
173 | from: 'از' | 192 | from: 'از' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: نشانی | 230 | url_label: نشانی |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'ویرایش مقاله' | 234 | page_title: 'ویرایش مقاله' |
214 | title_label: 'عنوان' | 235 | title_label: 'عنوان' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'خودآموز' | 274 | page_title: 'خودآموز' |
254 | page_description: 'راههای زیادی برای ذخیرهٔ مقالهها هست:' | 275 | page_description: 'راههای زیادی برای ذخیرهٔ مقالهها هست:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'افزونه برای مرورگرها' | 280 | browser_addons: 'افزونه برای مرورگرها' |
257 | mobile_apps: 'برنامههای موبایل' | 281 | mobile_apps: 'برنامههای موبایل' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'افزونهٔ فایرفاکس' | 286 | firefox: 'افزونهٔ فایرفاکس' |
263 | chrome: 'افزونهٔ کروم' | 287 | chrome: 'افزونهٔ کروم' |
288 | # opera: 'Opera addon' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'از راه F-Droid' | 291 | via_f_droid: 'از راه F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'از راه Microsoft Store' | 294 | windows: 'از راه Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'این پیوند را به نوار بوکمارک مرورگرتان بکشید:' | 296 | description: 'این پیوند را به نوار بوکمارک مرورگرتان بکشید:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Quickstart' | 326 | page_title: 'Quickstart' |
@@ -279,6 +331,7 @@ quickstart: | |||
279 | paragraph_2: 'ادامه دهید!' | 331 | paragraph_2: 'ادامه دهید!' |
280 | configure: | 332 | configure: |
281 | title: 'برنامه را تنظیم کنید' | 333 | title: 'برنامه را تنظیم کنید' |
334 | # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.' | ||
282 | language: 'زبان و نمای برنامه را تغییر دهید' | 335 | language: 'زبان و نمای برنامه را تغییر دهید' |
283 | rss: 'خوراک آر-اس-اس را فعال کنید' | 336 | rss: 'خوراک آر-اس-اس را فعال کنید' |
284 | tagging_rules: 'قانونهای برچسبگذاری خودکار مقالههایتان را تعریف کنید' | 337 | tagging_rules: 'قانونهای برچسبگذاری خودکار مقالههایتان را تعریف کنید' |
@@ -328,6 +381,9 @@ tag: | |||
328 | list: | 381 | list: |
329 | number_on_the_page: '{0} هیچ برچسبی نیست.|{1} یک برچسب هست.|]1,Inf[ %count% برچسب هست.' | 382 | number_on_the_page: '{0} هیچ برچسبی نیست.|{1} یک برچسب هست.|]1,Inf[ %count% برچسب هست.' |
330 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
331 | 387 | ||
332 | import: | 388 | import: |
333 | page_title: 'درونریزی' | 389 | page_title: 'درونریزی' |
@@ -361,6 +417,7 @@ import: | |||
361 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
362 | worker: | 418 | worker: |
363 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
364 | firefox: | 421 | firefox: |
365 | page_title: 'درونریزی > Firefox' | 422 | page_title: 'درونریزی > Firefox' |
366 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -373,6 +430,10 @@ import: | |||
373 | page_title: 'درونریزی > Instapaper' | 430 | page_title: 'درونریزی > Instapaper' |
374 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
375 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
376 | 437 | ||
377 | developer: | 438 | developer: |
378 | # page_title: 'Developer' | 439 | # page_title: 'Developer' |
@@ -443,7 +504,6 @@ user: | |||
443 | plain_password_label: '????' | 504 | plain_password_label: '????' |
444 | email_label: 'نشانی ایمیل' | 505 | email_label: 'نشانی ایمیل' |
445 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
446 | # locked_label: 'Locked' | ||
447 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
448 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
449 | # save: Save | 509 | # save: Save |
@@ -464,8 +524,10 @@ flashes: | |||
464 | rss_updated: 'اطلاعات آر-اس-اس بهروز شد' | 524 | rss_updated: 'اطلاعات آر-اس-اس بهروز شد' |
465 | tagging_rules_updated: 'برچسبگذاری خودکار بهروز شد' | 525 | tagging_rules_updated: 'برچسبگذاری خودکار بهروز شد' |
466 | tagging_rules_deleted: 'قانون برچسبگذاری پاک شد' | 526 | tagging_rules_deleted: 'قانون برچسبگذاری پاک شد' |
467 | user_added: 'کابر "%username%" افزوده شد' | ||
468 | rss_token_updated: 'کد آر-اس-اس بهروز شد' | 527 | rss_token_updated: 'کد آر-اس-اس بهروز شد' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
469 | entry: | 531 | entry: |
470 | notice: | 532 | notice: |
471 | entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' | 533 | entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' |
@@ -495,3 +557,8 @@ flashes: | |||
495 | notice: | 557 | notice: |
496 | # client_created: 'New client created.' | 558 | # client_created: 'New client created.' |
497 | # client_deleted: 'Client deleted' | 559 | # client_deleted: 'Client deleted' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index f2c9d8db..6f4befc9 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml | |||
@@ -46,7 +46,7 @@ footer: | |||
46 | social: "Social" | 46 | social: "Social" |
47 | powered_by: "propulsé par" | 47 | powered_by: "propulsé par" |
48 | about: "À propos" | 48 | about: "À propos" |
49 | stats: Depuis le %user_creation% vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour ! | 49 | stats: Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour ! |
50 | 50 | ||
51 | config: | 51 | config: |
52 | page_title: "Configuration" | 52 | page_title: "Configuration" |
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: "Je lis environ 200 mots par minute" | 70 | 200_word: "Je lis environ 200 mots par minute" |
71 | 300_word: "Je lis environ 300 mots par minute" | 71 | 300_word: "Je lis environ 300 mots par minute" |
72 | 400_word: "Je lis environ 400 mots par minute" | 72 | 400_word: "Je lis environ 400 mots par minute" |
73 | action_mark_as_read: | ||
74 | label: 'Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?' | ||
75 | redirect_homepage: "À la page d'accueil" | ||
76 | redirect_current_page: 'À la page courante' | ||
73 | pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données | 77 | pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données |
78 | android_configuration: Configurez votre application Android | ||
74 | help_theme: "L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème que vous préférez." | 79 | help_theme: "L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème que vous préférez." |
75 | help_items_per_page: "Vous pouvez définir le nombre d'articles affichés sur chaque page." | 80 | help_items_per_page: "Vous pouvez définir le nombre d'articles affichés sur chaque page." |
76 | help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article." | 81 | help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: "Adresse courriel" | 99 | email_label: "Adresse courriel" |
95 | twoFactorAuthentication_label: "Double authentification" | 100 | twoFactorAuthentication_label: "Double authentification" |
96 | help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email." | 101 | help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email." |
102 | delete: | ||
103 | title: Supprimer mon compte (attention danger !) | ||
104 | description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. | ||
105 | confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE) | ||
106 | button: 'Supprimer mon compte' | ||
107 | reset: | ||
108 | title: Réinitialisation (attention danger !) | ||
109 | description: En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES ! | ||
110 | annotations: Supprimer TOUTES les annotations | ||
111 | tags: Supprimer TOUS les tags | ||
112 | entries: Supprimer TOUS les articles | ||
113 | confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE) | ||
97 | form_password: | 114 | form_password: |
98 | description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères." | 115 | description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères." |
99 | old_password_label: "Mot de passe actuel" | 116 | old_password_label: "Mot de passe actuel" |
@@ -128,7 +145,7 @@ config: | |||
128 | domainName: "Le nom de domaine de l’article" | 145 | domainName: "Le nom de domaine de l’article" |
129 | operator_description: | 146 | operator_description: |
130 | label: "Opérateur" | 147 | label: "Opérateur" |
131 | less_than: "Moins que…..." | 148 | less_than: "Moins que…" |
132 | strictly_less_than: "Strictement moins que…" | 149 | strictly_less_than: "Strictement moins que…" |
133 | greater_than: "Plus que…" | 150 | greater_than: "Plus que…" |
134 | strictly_greater_than: "Strictement plus que…" | 151 | strictly_greater_than: "Strictement plus que…" |
@@ -145,9 +162,10 @@ entry: | |||
145 | archived: "Articles lus" | 162 | archived: "Articles lus" |
146 | filtered: "Articles filtrés" | 163 | filtered: "Articles filtrés" |
147 | filtered_tags: "Articles filtrés par tags :" | 164 | filtered_tags: "Articles filtrés par tags :" |
165 | filtered_search: 'Articles filtrés par recherche :' | ||
148 | untagged: "Article sans tag" | 166 | untagged: "Article sans tag" |
149 | list: | 167 | list: |
150 | number_on_the_page: "{0} Il n’y a pas d’articles.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." | 168 | number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles." |
151 | reading_time: "durée de lecture" | 169 | reading_time: "durée de lecture" |
152 | reading_time_minutes: "durée de lecture: %readingTime% min" | 170 | reading_time_minutes: "durée de lecture: %readingTime% min" |
153 | reading_time_less_one_minute: "durée de lecture: <small class=\"inferieur\"><</small> 1 min" | 171 | reading_time_less_one_minute: "durée de lecture: <small class=\"inferieur\"><</small> 1 min" |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: "A une photo" | 186 | preview_picture_label: "A une photo" |
169 | preview_picture_help: "Photo" | 187 | preview_picture_help: "Photo" |
170 | language_label: "Langue" | 188 | language_label: "Langue" |
189 | http_status_label: 'Statut HTTP' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: "Durée de lecture en minutes" | 191 | label: "Durée de lecture en minutes" |
173 | from: "de" | 192 | from: "de" |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: "http://website.com" | 228 | placeholder: "http://website.com" |
210 | form_new: | 229 | form_new: |
211 | url_label: "Adresse" | 230 | url_label: "Adresse" |
231 | search: | ||
232 | placeholder: "Que recherchez-vous ?" | ||
212 | edit: | 233 | edit: |
213 | page_title: "Éditer un article" | 234 | page_title: "Éditer un article" |
214 | title_label: "Titre" | 235 | title_label: "Titre" |
@@ -251,6 +272,9 @@ about: | |||
251 | 272 | ||
252 | howto: | 273 | howto: |
253 | page_title: "Aide" | 274 | page_title: "Aide" |
275 | tab_menu: | ||
276 | add_link: "Ajouter un lien" | ||
277 | shortcuts: "Utiliser les raccourcis" | ||
254 | page_description: "Il y a plusieurs façon d’enregistrer un article :" | 278 | page_description: "Il y a plusieurs façon d’enregistrer un article :" |
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: "Extensions de navigateur" | 280 | browser_addons: "Extensions de navigateur" |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: "Extension Firefox" | 286 | firefox: "Extension Firefox" |
263 | chrome: "Extension Chrome" | 287 | chrome: "Extension Chrome" |
288 | opera: "Extension Opera" | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: "via F-Droid" | 291 | via_f_droid: "via F-Droid" |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: "sur Microsoft Store" | 294 | windows: "sur Microsoft Store" |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: "Glissez et déposez ce lien dans votre barre de favoris :" | 296 | description: "Glissez et déposez ce lien dans votre barre de favoris :" |
297 | shortcuts: | ||
298 | page_description: Voici les raccourcis disponibles dans wallabag. | ||
299 | shortcut: Raccourci | ||
300 | action: Action | ||
301 | all_pages_title: Raccourcis disponibles dans toutes les pages | ||
302 | go_unread: Afficher les articles non lus | ||
303 | go_starred: Afficher les articles favoris | ||
304 | go_archive: Afficher les articles lus | ||
305 | go_all: Afficher tous les articles | ||
306 | go_tags: Afficher les tags | ||
307 | go_config: Aller à la configuration | ||
308 | go_import: Aller aux imports | ||
309 | go_developers: Aller à la section Développeurs | ||
310 | go_howto: Afficher l'aide (cette page !) | ||
311 | go_logout: Se déconnecter | ||
312 | list_title: Raccourcis disponibles dans les pages de liste | ||
313 | search: Afficher le formulaire de recherche | ||
314 | article_title: Raccourcis disponibles quand on affiche un article | ||
315 | open_original: Ouvrir l'URL originale de l'article | ||
316 | toggle_favorite: Changer le statut Favori de l'article | ||
317 | toggle_archive: Changer le status Lu de l'article | ||
318 | delete: Supprimer l'article | ||
319 | material_title: Raccourcis disponibles avec le thème Material uniquement | ||
320 | add_link: Ajouter un nouvel article | ||
321 | hide_form: Masquer le formulaire courant (recherche ou nouvel article) | ||
322 | arrows_navigation: Naviguer à travers les articles | ||
323 | open_article: Afficher l'article sélectionné | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: "Pour bien débuter" | 326 | page_title: "Pour bien débuter" |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: "{0} Il n’y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags." | 382 | number_on_the_page: "{0} Il n’y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags." |
331 | see_untagged_entries: "Voir les articles sans tag" | 383 | see_untagged_entries: "Voir les articles sans tag" |
384 | new: | ||
385 | add: 'Ajouter' | ||
386 | placeholder: 'Vous pouvez ajouter plusieurs tags, séparés par une virgule.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: "Importer" | 389 | page_title: "Importer" |
@@ -362,9 +417,10 @@ import: | |||
362 | how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." | 417 | how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer." |
363 | worker: | 418 | worker: |
364 | enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" | 419 | enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :" |
420 | download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d'activer les imports asynchrones." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: "Import > Firefox" | 422 | page_title: "Import > Firefox" |
367 | description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>" | 423 | description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde… ». Vous allez récupérer un fichier .json. </p>" |
368 | how_to: "Choisissez le fichier de sauvegarde de vos marques-page et cliquez sur le bouton pour l’importer. Soyez avertis que le processus peut prendre un temps assez long car tous les articles doivent être récupérés en ligne." | 424 | how_to: "Choisissez le fichier de sauvegarde de vos marques-page et cliquez sur le bouton pour l’importer. Soyez avertis que le processus peut prendre un temps assez long car tous les articles doivent être récupérés en ligne." |
369 | chrome: | 425 | chrome: |
370 | page_title: "Import > Chrome" | 426 | page_title: "Import > Chrome" |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: "Import > Instapaper" | 430 | page_title: "Import > Instapaper" |
375 | description: "Sur la page des paramètres (https://www.instapaper.com/user), cliquez sur « Download .CSV file » dans la section « Export ». Un fichier CSV sera téléchargé (« instapaper-export.csv »)." | 431 | description: "Sur la page des paramètres (https://www.instapaper.com/user), cliquez sur « Download .CSV file » dans la section « Export ». Un fichier CSV sera téléchargé (« instapaper-export.csv »)." |
376 | how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour l’importer." | 432 | how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour l’importer." |
433 | pinboard: | ||
434 | page_title: "Import > Pinboard" | ||
435 | description: "Sur la page « Backup » (https://pinboard.in/settings/backup), cliquez sur « JSON » dans la section « Bookmarks ». Un fichier json (sans extension) sera téléchargé (« pinboard_export »)." | ||
436 | how_to: "Choisissez le fichier de votre export Pinboard et cliquez sur le bouton ci-dessous pour l’importer." | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: "Développeur" | 439 | page_title: "Développeur" |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: "Mot de passe en clair" | 504 | plain_password_label: "Mot de passe en clair" |
445 | email_label: "Adresse courriel" | 505 | email_label: "Adresse courriel" |
446 | enabled_label: "Activé" | 506 | enabled_label: "Activé" |
447 | locked_label: "Bloqué" | ||
448 | last_login_label: "Dernière connexion" | 507 | last_login_label: "Dernière connexion" |
449 | twofactor_label: "Double authentification" | 508 | twofactor_label: "Double authentification" |
450 | save: "Sauvegarder" | 509 | save: "Sauvegarder" |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: "La configuration des flux RSS a bien été mise à jour" | 524 | rss_updated: "La configuration des flux RSS a bien été mise à jour" |
466 | tagging_rules_updated: "Règles mises à jour" | 525 | tagging_rules_updated: "Règles mises à jour" |
467 | tagging_rules_deleted: "Règle supprimée" | 526 | tagging_rules_deleted: "Règle supprimée" |
468 | user_added: "Utilisateur \"%username%\" ajouté" | ||
469 | rss_token_updated: "Jeton RSS mis à jour" | 527 | rss_token_updated: "Jeton RSS mis à jour" |
528 | annotations_reset: Annotations supprimées | ||
529 | tags_reset: Tags supprimés | ||
530 | entries_reset: Articles supprimés | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: "Article déjà sauvegardé le %date%" | 533 | entry_already_saved: "Article déjà sauvegardé le %date%" |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: "Nouveau client %name% créé" | 558 | client_created: "Nouveau client %name% créé" |
498 | client_deleted: "Client %name% supprimé" | 559 | client_deleted: "Client %name% supprimé" |
560 | user: | ||
561 | notice: | ||
562 | added: 'Utilisateur "%username%" ajouté' | ||
563 | updated: 'Utilisateur "%username%" mis à jour' | ||
564 | deleted: 'Utilisateur "%username%" supprimé' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml index b7d066ab..bbb526dc 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'Leggo ~200 parole al minuto' | 70 | 200_word: 'Leggo ~200 parole al minuto' |
71 | 300_word: 'Leggo ~300 parole al minuto' | 71 | 300_word: 'Leggo ~300 parole al minuto' |
72 | 400_word: 'Leggo ~400 parole al minuto' | 72 | 400_word: 'Leggo ~400 parole al minuto' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: Consumer key per Pocket per importare i contenuti | 77 | pocket_consumer_key_label: Consumer key per Pocket per importare i contenuti |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'E-mail' | 99 | email_label: 'E-mail' |
95 | twoFactorAuthentication_label: 'Two factor authentication' | 100 | twoFactorAuthentication_label: 'Two factor authentication' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Password corrente' | 116 | old_password_label: 'Password corrente' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Contenuti archiviati' | 162 | archived: 'Contenuti archiviati' |
146 | filtered: 'Contenuti filtrati' | 163 | filtered: 'Contenuti filtrati' |
147 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." | 168 | number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: "Ha un'immagine di anteprima" | 186 | preview_picture_label: "Ha un'immagine di anteprima" |
169 | preview_picture_help: 'Immagine di anteprima' | 187 | preview_picture_help: 'Immagine di anteprima' |
170 | language_label: 'Lingua' | 188 | language_label: 'Lingua' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Tempo di lettura in minuti' | 191 | label: 'Tempo di lettura in minuti' |
173 | from: 'da' | 192 | from: 'da' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Modifica voce' | 234 | page_title: 'Modifica voce' |
214 | title_label: 'Titolo' | 235 | title_label: 'Titolo' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'How to' | 274 | page_title: 'How to' |
254 | page_description: 'Ci sono diversi modi per salvare un contenuto:' | 275 | page_description: 'Ci sono diversi modi per salvare un contenuto:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'tramite addons del Browser' | 280 | browser_addons: 'tramite addons del Browser' |
257 | mobile_apps: 'tramite app Mobile' | 281 | mobile_apps: 'tramite app Mobile' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Add-On di Firefox' | 286 | firefox: 'Add-On di Firefox' |
263 | chrome: 'Estensione di Chrome' | 287 | chrome: 'Estensione di Chrome' |
288 | opera: 'Estensione di Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'sullo store di Microsoft' | 294 | windows: 'sullo store di Microsoft' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Trascinando e rilasciando questo link sulla barra dei bookmark del tuo browser:' | 296 | description: 'Trascinando e rilasciando questo link sulla barra dei bookmark del tuo browser:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Introduzione' | 326 | page_title: 'Introduzione' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag." | 382 | number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag." |
331 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Importa' | 389 | page_title: 'Importa' |
@@ -362,6 +417,7 @@ import: | |||
362 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
363 | worker: | 418 | worker: |
364 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Importa da > Firefox' | 422 | page_title: 'Importa da > Firefox' |
367 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Importa da > Instapaper' | 430 | page_title: 'Importa da > Instapaper' |
375 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
376 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | page_title: "Importa da > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Sviluppatori' | 439 | page_title: 'Sviluppatori' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'E-mail' | 505 | email_label: 'E-mail' |
446 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
447 | # locked_label: 'Locked' | ||
448 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
449 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
450 | # save: Save | 509 | # save: Save |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'Informazioni RSS aggiornate' | 524 | rss_updated: 'Informazioni RSS aggiornate' |
466 | tagging_rules_updated: 'Regole di tagging aggiornate' | 525 | tagging_rules_updated: 'Regole di tagging aggiornate' |
467 | tagging_rules_deleted: 'Regola di tagging aggiornate' | 526 | tagging_rules_deleted: 'Regola di tagging aggiornate' |
468 | user_added: 'Utente "%username%" aggiunto' | ||
469 | rss_token_updated: 'RSS token aggiornato' | 527 | rss_token_updated: 'RSS token aggiornato' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: 'Contenuto già salvato in data %date%' | 533 | entry_already_saved: 'Contenuto già salvato in data %date%' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: 'Nuovo client creato.' | 558 | client_created: 'Nuovo client creato.' |
498 | client_deleted: 'Client eliminato' | 559 | client_deleted: 'Client eliminato' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml index 16ef1e5d..33c1a660 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml | |||
@@ -25,13 +25,13 @@ menu: | |||
25 | internal_settings: 'Configuracion interna' | 25 | internal_settings: 'Configuracion interna' |
26 | import: 'Importar' | 26 | import: 'Importar' |
27 | howto: 'Ajuda' | 27 | howto: 'Ajuda' |
28 | developer: 'Desvolopador' | 28 | developer: 'Desvolopaire' |
29 | logout: 'Desconnexion' | 29 | logout: 'Desconnexion' |
30 | about: 'A prepaus' | 30 | about: 'A prepaus' |
31 | search: 'Cercar' | 31 | search: 'Cercar' |
32 | save_link: 'Enregistrar un novèl article' | 32 | save_link: 'Enregistrar un novèl article' |
33 | back_to_unread: 'Tornar als articles pas legits' | 33 | back_to_unread: 'Tornar als articles pas legits' |
34 | # users_management: 'Users management' | 34 | users_management: 'Gestion dels utilizaires' |
35 | top: | 35 | top: |
36 | add_new_entry: 'Enregistrar un novèl article' | 36 | add_new_entry: 'Enregistrar un novèl article' |
37 | search: 'Cercar' | 37 | search: 'Cercar' |
@@ -46,7 +46,7 @@ footer: | |||
46 | social: 'Social' | 46 | social: 'Social' |
47 | powered_by: 'propulsat per' | 47 | powered_by: 'propulsat per' |
48 | about: 'A prepaus' | 48 | about: 'A prepaus' |
49 | # stats: Since %user_creation% you read %nb_archives% articles. That is about %per_day% a day! | 49 | stats: "Dempuèi %user_creation% avètz legit %nb_archives% articles. Es a l'entorn de %per_day% per jorn !" |
50 | 50 | ||
51 | config: | 51 | config: |
52 | page_title: 'Configuracion' | 52 | page_title: 'Configuracion' |
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: "Legissi a l'entorn de 200 mots per minuta" | 70 | 200_word: "Legissi a l'entorn de 200 mots per minuta" |
71 | 300_word: "Legissi a l'entorn de 300 mots per minuta" | 71 | 300_word: "Legissi a l'entorn de 300 mots per minuta" |
72 | 400_word: "Legissi a l'entorn de 400 mots per minuta" | 72 | 400_word: "Legissi a l'entorn de 400 mots per minuta" |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas | 77 | pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas |
78 | android_configuration: Configuratz vòstra aplicacion Android | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'Adreça de corrièl' | 99 | email_label: 'Adreça de corrièl' |
95 | twoFactorAuthentication_label: 'Dobla autentificacion' | 100 | twoFactorAuthentication_label: 'Dobla autentificacion' |
96 | # 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: | ||
103 | title: Suprimir mon compte (Mèfi zòna perilhosa) | ||
104 | description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat. | ||
105 | confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE) | ||
106 | button: Suprimir mon compte | ||
107 | reset: | ||
108 | title: Zòna de reïnicializacion (Mèfi zòna perilhosa) | ||
109 | description: En clicant sul boton çai-jos auretz la possibilitat de levar qualques informacions de vòstre compte. Mèfi que totas aquelas accions son IRREVERSIBLAS. | ||
110 | annotations: Levar TOTAS las anotacions | ||
111 | tags: Levar TOTAS las etiquetas | ||
112 | entries: Levar TOTES los articles | ||
113 | confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Senhal actual' | 116 | old_password_label: 'Senhal actual' |
@@ -103,7 +120,7 @@ config: | |||
103 | if_label: 'se' | 120 | if_label: 'se' |
104 | then_tag_as_label: 'alara atribuir las etiquetas' | 121 | then_tag_as_label: 'alara atribuir las etiquetas' |
105 | delete_rule_label: 'suprimir' | 122 | delete_rule_label: 'suprimir' |
106 | # edit_rule_label: 'edit' | 123 | edit_rule_label: 'modificar' |
107 | rule_label: 'Règla' | 124 | rule_label: 'Règla' |
108 | tags_label: 'Etiquetas' | 125 | tags_label: 'Etiquetas' |
109 | faq: | 126 | faq: |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Articles legits' | 162 | archived: 'Articles legits' |
146 | filtered: 'Articles filtrats' | 163 | filtered: 'Articles filtrats' |
147 | filtered_tags: 'Filtats per etiquetas:' | 164 | filtered_tags: 'Filtats per etiquetas:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | untagged: 'Articles sens etiqueta' | 166 | untagged: 'Articles sens etiqueta' |
149 | list: | 167 | list: |
150 | number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." | 168 | number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'A una fotò' | 186 | preview_picture_label: 'A una fotò' |
169 | preview_picture_help: 'Fotò' | 187 | preview_picture_help: 'Fotò' |
170 | language_label: 'Lenga' | 188 | language_label: 'Lenga' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Durada de lectura en minutas' | 191 | label: 'Durada de lectura en minutas' |
173 | from: 'de' | 192 | from: 'de' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Modificar un article' | 234 | page_title: 'Modificar un article' |
214 | title_label: 'Títol' | 235 | title_label: 'Títol' |
@@ -216,7 +237,7 @@ entry: | |||
216 | is_public_label: 'Public' | 237 | is_public_label: 'Public' |
217 | save_label: 'Enregistrar' | 238 | save_label: 'Enregistrar' |
218 | public: | 239 | public: |
219 | # shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>" | 240 | shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>" |
220 | 241 | ||
221 | about: | 242 | about: |
222 | page_title: 'A prepaus' | 243 | page_title: 'A prepaus' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'Ajuda' | 274 | page_title: 'Ajuda' |
254 | page_description: "I a mai d'un biais d'enregistrar un article :" | 275 | page_description: "I a mai d'un biais d'enregistrar un article :" |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Extensions de navigator' | 280 | browser_addons: 'Extensions de navigator' |
257 | mobile_apps: 'Aplicacions mobil' | 281 | mobile_apps: 'Aplicacions mobil' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Extension Firefox' | 286 | firefox: 'Extension Firefox' |
263 | chrome: 'Extension Chrome' | 287 | chrome: 'Extension Chrome' |
288 | opera: 'Extension Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,17 +294,44 @@ howto: | |||
269 | windows: 'sus Microsoft Store' | 294 | windows: 'sus Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Lisatz-depausatz aqueste ligam dins vòstra barra de favorits :' | 296 | description: 'Lisatz-depausatz aqueste ligam dins vòstra barra de favorits :' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Per ben començar' | 326 | page_title: 'Per ben començar' |
275 | # more: 'More…' | 327 | more: 'Mai…' |
276 | intro: | 328 | intro: |
277 | title: 'Benvenguda sus wallabag !' | 329 | title: 'Benvenguda sus wallabag !' |
278 | paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas fonccionalitats que vos poirián interessar per vos apropriar aquesta aisina." | 330 | paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas fonccionalitats que vos poirián interessar per vos apropriar aquesta aisina." |
279 | paragraph_2: 'Seguètz-nos ' | 331 | paragraph_2: 'Seguètz-nos ' |
280 | configure: | 332 | configure: |
281 | title: "Configuratz l'aplicacio" | 333 | title: "Configuratz l'aplicacion" |
282 | # description: 'In order to have an application which suits you, have a look into the configuration of wallabag.' | 334 | description: "Per fin d'aver una aplicacion que vos va ben, anatz veire la configuracion de wallabag." |
283 | language: "Cambiatz la lenga e l'estil de l'aplicacion" | 335 | language: "Cambiatz la lenga e l'estil de l'aplicacion" |
284 | rss: 'Activatz los fluxes RSS' | 336 | rss: 'Activatz los fluxes RSS' |
285 | tagging_rules: 'Escrivètz de règlas per classar automaticament vòstres articles' | 337 | tagging_rules: 'Escrivètz de règlas per classar automaticament vòstres articles' |
@@ -293,7 +345,7 @@ quickstart: | |||
293 | import: 'Configurar los impòrt' | 345 | import: 'Configurar los impòrt' |
294 | first_steps: | 346 | first_steps: |
295 | title: 'Primièrs passes' | 347 | title: 'Primièrs passes' |
296 | # description: "Now wallabag is well configured, it's time to archive the web. You can click on the top right sign + to add a link." | 348 | description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam." |
297 | new_article: 'Ajustatz vòstre primièr article' | 349 | new_article: 'Ajustatz vòstre primièr article' |
298 | unread_articles: 'E racaptatz-lo !' | 350 | unread_articles: 'E racaptatz-lo !' |
299 | migrate: | 351 | migrate: |
@@ -305,14 +357,14 @@ quickstart: | |||
305 | readability: 'Migrar dempuèi Readability' | 357 | readability: 'Migrar dempuèi Readability' |
306 | instapaper: 'Migrar dempuèi Instapaper' | 358 | instapaper: 'Migrar dempuèi Instapaper' |
307 | developer: | 359 | developer: |
308 | title: 'Pels desvolopadors' | 360 | title: 'Pels desvolopaires' |
309 | # description: 'We also thought to the developers: Docker, API, translations, etc.' | 361 | description: 'Avèm tanben pensat als desvolopaires : Docker, API, traduccions, etc.' |
310 | create_application: 'Crear vòstra aplicacion tèrça' | 362 | create_application: 'Crear vòstra aplicacion tèrça' |
311 | # use_docker: 'Use Docker to install wallabag' | 363 | use_docker: 'Utilizar Docker per installar wallabag' |
312 | docs: | 364 | docs: |
313 | title: 'Documentacion complèta' | 365 | title: 'Documentacion complèta' |
314 | # description: "There are so much features in wallabag. Don't hesitate to read the manual to know them and to learn how to use them." | 366 | description: "I a un fum de fonccionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar." |
315 | annotate: 'Anotatar vòstre article' | 367 | annotate: 'Anotar vòstre article' |
316 | export: 'Convertissètz vòstres articles en ePub o en PDF' | 368 | export: 'Convertissètz vòstres articles en ePub o en PDF' |
317 | search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa" | 369 | search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa" |
318 | fetching_errors: "Qué far se mon article es pas recuperat coma cal ?" | 370 | fetching_errors: "Qué far se mon article es pas recuperat coma cal ?" |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: "{0} I a pas cap d'etiquetas.|{1} I a una etiqueta.|]1,Inf[ I a %count% etiquetas." | 382 | number_on_the_page: "{0} I a pas cap d'etiquetas.|{1} I a una etiqueta.|]1,Inf[ I a %count% etiquetas." |
331 | see_untagged_entries: "Afichar las entradas sens pas cap d'etiquetas" | 383 | see_untagged_entries: "Afichar las entradas sens pas cap d'etiquetas" |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Importar' | 389 | page_title: 'Importar' |
@@ -362,6 +417,7 @@ import: | |||
362 | how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar." | 417 | how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar." |
363 | worker: | 418 | worker: |
364 | enabled: "L'importacion se fa de manièra asincròna. Un còp l'importacion lançada, una aisina externa s'ocuparà dels messatges un per un. Lo servici actual es : " | 419 | enabled: "L'importacion se fa de manièra asincròna. Un còp l'importacion lançada, una aisina externa s'ocuparà dels messatges un per un. Lo servici actual es : " |
420 | download_images_warning: "Avètz activat lo telecargament de los imatges de vòstres articles. Combinat amb l'importacion classica, aquò pòt tardar un long moment (o benlèu fracassar). <strong>Recomandem fòrtament</strong> l'activacion de l'importacion asincròna per evitar las errors." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Importar > Firefox' | 422 | page_title: 'Importar > Firefox' |
367 | description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Importar > Instapaper' | 430 | page_title: 'Importar > Instapaper' |
375 | description: "Aquesta aisina importarà totas vòstres articles d'Instapaper. Sus la pagina de paramètres (https://www.instapaper.com/user), clicatz sus \"Download .CSV file\" dins la seccion \"Export\". Un fichièr CSV serà telecargat (aital \"instapaper-export.csv\")." | 431 | description: "Aquesta aisina importarà totas vòstres articles d'Instapaper. Sus la pagina de paramètres (https://www.instapaper.com/user), clicatz sus \"Download .CSV file\" dins la seccion \"Export\". Un fichièr CSV serà telecargat (aital \"instapaper-export.csv\")." |
376 | how_to: "Mercés de causir vòstre fichièr Instapaper e de clicar sul boton dejós per lo telecargar e l'importar" | 432 | how_to: "Mercés de causir vòstre fichièr Instapaper e de clicar sul boton dejós per lo telecargar e l'importar" |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Desvolopaire' | 439 | page_title: 'Desvolopaire' |
@@ -397,7 +457,7 @@ developer: | |||
397 | warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag." | 457 | warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag." |
398 | action: 'Suprimir aqueste client' | 458 | action: 'Suprimir aqueste client' |
399 | client: | 459 | client: |
400 | page_title: 'Desvlopador > Novèl client' | 460 | page_title: 'Desvolopaire > Novèl client' |
401 | page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion." | 461 | page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion." |
402 | form: | 462 | form: |
403 | name_label: "Nom del client" | 463 | name_label: "Nom del client" |
@@ -405,7 +465,7 @@ developer: | |||
405 | save_label: 'Crear un novèl client' | 465 | save_label: 'Crear un novèl client' |
406 | action_back: 'Retorn' | 466 | action_back: 'Retorn' |
407 | client_parameter: | 467 | client_parameter: |
408 | page_title: 'Desvolopador > Los paramètres de vòstre client' | 468 | page_title: 'Desvolopaire > Los paramètres de vòstre client' |
409 | page_description: 'Vaquí los paramètres de vòstre client' | 469 | page_description: 'Vaquí los paramètres de vòstre client' |
410 | field_name: 'Nom del client' | 470 | field_name: 'Nom del client' |
411 | field_id: 'ID Client' | 471 | field_id: 'ID Client' |
@@ -413,7 +473,7 @@ developer: | |||
413 | back: 'Retour' | 473 | back: 'Retour' |
414 | read_howto: 'Legir "cossí crear ma primièra aplicacion"' | 474 | read_howto: 'Legir "cossí crear ma primièra aplicacion"' |
415 | howto: | 475 | howto: |
416 | page_title: 'Desvolopador > Cossí crear ma primièra aplicacion' | 476 | page_title: 'Desvolopaire > Cossí crear ma primièra aplicacion' |
417 | description: | 477 | description: |
418 | paragraph_1: "Las comandas seguentas utilizan la <a href=\"https://github.com/jkbrzt/httpie\">bibliotèca HTTPie</a>. Asseguratz-vos que siasqueòu installadas abans de l'utilizar." | 478 | paragraph_1: "Las comandas seguentas utilizan la <a href=\"https://github.com/jkbrzt/httpie\">bibliotèca HTTPie</a>. Asseguratz-vos que siasqueòu installadas abans de l'utilizar." |
419 | paragraph_2: "Vos cal un geton per escambiar entre vòstra aplicacion e l'API de wallabar." | 479 | paragraph_2: "Vos cal un geton per escambiar entre vòstra aplicacion e l'API de wallabar." |
@@ -426,34 +486,33 @@ developer: | |||
426 | back: 'Retorn' | 486 | back: 'Retorn' |
427 | 487 | ||
428 | user: | 488 | user: |
429 | # page_title: Users management | 489 | page_title: 'Gestion dels utilizaires' |
430 | # new_user: Create a new user | 490 | new_user: 'Crear un novèl utilizaire' |
431 | # edit_user: Edit an existing user | 491 | edit_user: 'Modificar un utilizaire existent' |
432 | # description: "Here you can manage all users (create, edit and delete)" | 492 | description: "Aquí podètz gerir totes los utilizaires (crear, modificar e suprimir)" |
433 | # list: | 493 | list: |
434 | # actions: Actions | 494 | actions: 'Accions' |
435 | # edit_action: Edit | 495 | edit_action: 'Modificar' |
436 | # yes: Yes | 496 | yes: 'Òc' |
437 | # no: No | 497 | no: 'Non' |
438 | # create_new_one: Create a new user | 498 | create_new_one: 'Crear un novèl utilizaire' |
439 | form: | 499 | form: |
440 | username_label: "Nom d'utilizaire" | 500 | username_label: "Nom d'utilizaire" |
441 | # name_label: 'Name' | 501 | name_label: 'Nom' |
442 | password_label: 'Senhal' | 502 | password_label: 'Senhal' |
443 | repeat_new_password_label: 'Confirmatz vòstre novèl senhal' | 503 | repeat_new_password_label: 'Confirmatz vòstre novèl senhal' |
444 | plain_password_label: 'Senhal en clar' | 504 | plain_password_label: 'Senhal en clar' |
445 | email_label: 'Adreça de corrièl' | 505 | email_label: 'Adreça de corrièl' |
446 | # enabled_label: 'Enabled' | 506 | enabled_label: 'Actiu' |
447 | # locked_label: 'Locked' | 507 | last_login_label: 'Darrièra connexion' |
448 | # last_login_label: 'Last login' | 508 | twofactor_label: 'Autentificacion doble-factor' |
449 | # twofactor_label: Two factor authentication | 509 | save: 'Enregistrar' |
450 | # save: Save | 510 | delete: 'Suprimir' |
451 | # delete: Delete | 511 | delete_confirm: 'Sètz segur ?' |
452 | # delete_confirm: Are you sure? | 512 | back_to_list: 'Tornar a la lista' |
453 | # back_to_list: Back to list | ||
454 | 513 | ||
455 | error: | 514 | error: |
456 | # page_title: An error occurred | 515 | page_title: Una error s'es produsida |
457 | 516 | ||
458 | flashes: | 517 | flashes: |
459 | config: | 518 | config: |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' | 524 | rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' |
466 | tagging_rules_updated: 'Règlas misa a jorn' | 525 | tagging_rules_updated: 'Règlas misa a jorn' |
467 | tagging_rules_deleted: 'Règla suprimida' | 526 | tagging_rules_deleted: 'Règla suprimida' |
468 | user_added: 'Utilizaire "%username%" apondut' | ||
469 | rss_token_updated: 'Geton RSS mes a jorn' | 527 | rss_token_updated: 'Geton RSS mes a jorn' |
528 | annotations_reset: Anotacions levadas | ||
529 | tags_reset: Etiquetas levadas | ||
530 | entries_reset: Articles levats | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: 'Article ja salvargardat lo %date%' | 533 | entry_already_saved: 'Article ja salvargardat lo %date%' |
@@ -477,12 +538,12 @@ flashes: | |||
477 | entry_reloaded_failed: "L'article es estat cargat de nòu mai la recuperacion del contengut a fracassat" | 538 | entry_reloaded_failed: "L'article es estat cargat de nòu mai la recuperacion del contengut a fracassat" |
478 | entry_archived: 'Article marcat coma legit' | 539 | entry_archived: 'Article marcat coma legit' |
479 | entry_unarchived: 'Article marcat coma pas legit' | 540 | entry_unarchived: 'Article marcat coma pas legit' |
480 | entry_starred: 'Article apondut dins los favorits' | 541 | entry_starred: 'Article ajustat dins los favorits' |
481 | entry_unstarred: 'Article quitat dels favorits' | 542 | entry_unstarred: 'Article quitat dels favorits' |
482 | entry_deleted: 'Article suprimit' | 543 | entry_deleted: 'Article suprimit' |
483 | tag: | 544 | tag: |
484 | notice: | 545 | notice: |
485 | tag_added: 'Etiqueta aponduda' | 546 | tag_added: 'Etiqueta ajustada' |
486 | import: | 547 | import: |
487 | notice: | 548 | notice: |
488 | failed: "L'importacion a fracassat, mercés de tornar ensajar" | 549 | failed: "L'importacion a fracassat, mercés de tornar ensajar" |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: 'Novèl client creat' | 558 | client_created: 'Novèl client creat' |
498 | client_deleted: 'Client suprimit' | 559 | client_deleted: 'Client suprimit' |
560 | user: | ||
561 | notice: | ||
562 | added: 'Utilizaire "%username%" ajustat' | ||
563 | updated: 'Utilizaire "%username%" mes a jorn' | ||
564 | deleted: 'Utilizaire "%username%" suprimit' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml index 73250cc0..1eb83d53 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml | |||
@@ -61,7 +61,7 @@ config: | |||
61 | save: 'Zapisz' | 61 | save: 'Zapisz' |
62 | form_settings: | 62 | form_settings: |
63 | theme_label: 'Temat' | 63 | theme_label: 'Temat' |
64 | items_per_page_label: 'Ilość elementóœ na stronie' | 64 | items_per_page_label: 'Ilość elementów na stronie' |
65 | language_label: 'Język' | 65 | language_label: 'Język' |
66 | reading_speed: | 66 | reading_speed: |
67 | label: 'Prędkość czytania' | 67 | label: 'Prędkość czytania' |
@@ -70,12 +70,17 @@ config: | |||
70 | 200_word: 'Czytam ~200 słów na minutę' | 70 | 200_word: 'Czytam ~200 słów na minutę' |
71 | 300_word: 'Czytam ~300 słów na minutę' | 71 | 300_word: 'Czytam ~300 słów na minutę' |
72 | 400_word: 'Czytam ~400 słów na minutę' | 72 | 400_word: 'Czytam ~400 słów na minutę' |
73 | action_mark_as_read: | ||
74 | label: 'Gdzie zostaniesz przekierowany po oznaczeniu artukuły jako przeczytanego' | ||
75 | redirect_homepage: 'do strony głównej' | ||
76 | redirect_current_page: 'do bieżącej strony' | ||
73 | pocket_consumer_key_label: 'Klucz klienta Pocket do importu zawartości' | 77 | pocket_consumer_key_label: 'Klucz klienta Pocket do importu zawartości' |
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 78 | android_configuration: Skonfiguruj swoją androidową aplikację |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 79 | help_theme: "Dopasuj wallabag do swoich potrzeb. Tutaj możesz wybrać preferowany przez ciebie motyw." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 80 | help_items_per_page: "Możesz zmienić ilość artykułów wyświetlanych na każdej stronie." |
77 | # help_language: "You can change the language of wallabag interface." | 81 | help_reading_speed: "wallabag oblicza czas czytania każdego artykułu. Dzięki tej liście możesz określić swoje tempo. Wallabag przeliczy ponownie czas potrzebny, na przeczytanie każdego z artykułów." |
78 | # help_pocket_consumer_key: "Required for Pocket import. You can create it in your Pocket account." | 82 | help_language: "Możesz zmienić język interfejsu wallabag." |
83 | help_pocket_consumer_key: "Wymagane dla importu z Pocket. Możesz go stworzyć na swoim koncie Pocket." | ||
79 | form_rss: | 84 | form_rss: |
80 | description: 'Kanały RSS prowadzone przez wallabag pozwalają Ci na czytanie twoich zapisanych artykułów w twoium ulubionym czytniku RSS. Musisz najpierw wynegenerować tokena.' | 85 | description: 'Kanały RSS prowadzone przez wallabag pozwalają Ci na czytanie twoich zapisanych artykułów w twoium ulubionym czytniku RSS. Musisz najpierw wynegenerować tokena.' |
81 | token_label: 'Token RSS' | 86 | token_label: 'Token RSS' |
@@ -93,9 +98,21 @@ config: | |||
93 | name_label: 'Nazwa' | 98 | name_label: 'Nazwa' |
94 | email_label: 'Adres email' | 99 | email_label: 'Adres email' |
95 | twoFactorAuthentication_label: 'Autoryzacja dwuetapowa' | 100 | twoFactorAuthentication_label: 'Autoryzacja dwuetapowa' |
96 | # help_twoFactorAuthentication: "If you enable 2FA, each time you want to login to wallabag, you'll receive a code by email." | 101 | help_twoFactorAuthentication: "Jeżeli włączysz autoryzację dwuetapową. Za każdym razem, kiedy będziesz chciał się zalogować, dostaniesz kod na swój e-mail." |
102 | delete: | ||
103 | title: Usuń moje konto (niebezpieczna strefa !) | ||
104 | description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany. | ||
105 | confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) | ||
106 | button: Usuń moje konto | ||
107 | reset: | ||
108 | title: Reset (niebezpieczna strefa) | ||
109 | description: Poniższe przyciski pozwalają usunąć pewne informacje z twojego konta. Uważaj te operacje są NIEODWRACALNE. | ||
110 | annotations: Usuń WSZYSTKIE adnotacje | ||
111 | tags: Usuń WSZYSTKIE tagi | ||
112 | entries: usuń WSZYTSTKIE wpisy | ||
113 | confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | description: "Tutaj możesz zmienić swoje hasło. Twoje nowe hasło powinno mieć conajmniej 8 znaków." |
99 | old_password_label: 'Stare hasło' | 116 | old_password_label: 'Stare hasło' |
100 | new_password_label: 'Nowe hasło' | 117 | new_password_label: 'Nowe hasło' |
101 | repeat_new_password_label: 'Powtórz nowe hasło' | 118 | repeat_new_password_label: 'Powtórz nowe hasło' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Zarchiwizowane wpisy' | 162 | archived: 'Zarchiwizowane wpisy' |
146 | filtered: 'Odfiltrowane wpisy' | 163 | filtered: 'Odfiltrowane wpisy' |
147 | filtered_tags: 'Filtrowane po tagach:' | 164 | filtered_tags: 'Filtrowane po tagach:' |
165 | filtered_search: 'Filtrowanie po wyszukiwaniu:' | ||
148 | untagged: 'Odtaguj wpisy' | 166 | untagged: 'Odtaguj wpisy' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' | 168 | number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Posiada podgląd obrazu' | 186 | preview_picture_label: 'Posiada podgląd obrazu' |
169 | preview_picture_help: 'Podgląd obrazu' | 187 | preview_picture_help: 'Podgląd obrazu' |
170 | language_label: 'Język' | 188 | language_label: 'Język' |
189 | http_status_label: 'Status HTTP' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Czas czytania w minutach' | 191 | label: 'Czas czytania w minutach' |
173 | from: 'od' | 192 | from: 'od' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | placeholder: 'Czego szukasz?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Edytuj wpis' | 234 | page_title: 'Edytuj wpis' |
214 | title_label: 'Tytuł' | 235 | title_label: 'Tytuł' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'Howto' | 274 | page_title: 'Howto' |
254 | page_description: 'Sposoby zapisania artykułu:' | 275 | page_description: 'Sposoby zapisania artykułu:' |
276 | tab_menu: | ||
277 | add_link: "Dodaj link" | ||
278 | shortcuts: "Użyj skrótów" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Wtyczki dla przeglądarki' | 280 | browser_addons: 'Wtyczki dla przeglądarki' |
257 | mobile_apps: 'Aplikacje mobilne' | 281 | mobile_apps: 'Aplikacje mobilne' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Standardowe rozszerzenie dla Firefox' | 286 | firefox: 'Standardowe rozszerzenie dla Firefox' |
263 | chrome: 'Rozszerzenie dla Chrome' | 287 | chrome: 'Rozszerzenie dla Chrome' |
288 | opera: 'Rozszerzenie dla Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'w F-Droid' | 291 | via_f_droid: 'w F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'w Microsoft Store' | 294 | windows: 'w Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Przeciągnij i upuść ten link na swój pasek zakładek' | 296 | description: 'Przeciągnij i upuść ten link na swój pasek zakładek' |
297 | shortcuts: | ||
298 | page_description: Tutaj znajdują się skróty dostępne w wallabag. | ||
299 | shortcut: Skrót | ||
300 | action: Akcja | ||
301 | all_pages_title: Skróty dostępne na wszystkich stronach | ||
302 | go_unread: Idź do nieprzeczytanych | ||
303 | go_starred: Idź do oznaczonych gwiazdką | ||
304 | go_archive: Idź do archiwum | ||
305 | go_all: Idź do wszystkich wpisów | ||
306 | go_tags: Idź do tagów | ||
307 | go_config: Idź do konfiguracji | ||
308 | go_import: Idź do importu | ||
309 | go_developers: Idź do deweloperów | ||
310 | go_howto: Idź do howto (tej strony!) | ||
311 | go_logout: Wyloguj | ||
312 | list_title: Skróty dostępne w spisie stron | ||
313 | search: Pokaż formularz wyszukiwania | ||
314 | article_title: Skróty dostępne w widoku artykułu | ||
315 | open_original: Otwórz oryginalny adres URL wpisu | ||
316 | toggle_favorite: Oznacz wpis gwiazdką | ||
317 | toggle_archive: Oznacz wpis jako przeczytany | ||
318 | delete: Usuń wpis | ||
319 | material_title: Skróty dostępne wyłącznie w motywie Material | ||
320 | add_link: Dodaj nowy link | ||
321 | hide_form: Ukryj obecny formularz (wyszukiwania lub nowego linku) | ||
322 | arrows_navigation: Nawiguj pomiędzy artykułami | ||
323 | open_article: Wyświetl zaznaczony wpis | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Szybki start' | 326 | page_title: 'Szybki start' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: '{0} Nie ma tagów.|{1} Jest jeden tag.|]1,Inf[ Są %count% tagi.' | 382 | number_on_the_page: '{0} Nie ma tagów.|{1} Jest jeden tag.|]1,Inf[ Są %count% tagi.' |
331 | see_untagged_entries: 'Zobacz nieotagowane wpisy' | 383 | see_untagged_entries: 'Zobacz nieotagowane wpisy' |
384 | new: | ||
385 | add: 'Dodaj' | ||
386 | placeholder: 'Możesz dodać kilka tagów, oddzielając je przecinkami.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Import' | 389 | page_title: 'Import' |
@@ -362,6 +417,7 @@ import: | |||
362 | how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.' | 417 | how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.' |
363 | worker: | 418 | worker: |
364 | enabled: "Import jest wykonywany asynchronicznie. Od momentu rozpoczęcia importu, zewnętrzna usługa może zajmować się na raz tylko jednym zadaniem. Bieżącą usługą jest:" | 419 | enabled: "Import jest wykonywany asynchronicznie. Od momentu rozpoczęcia importu, zewnętrzna usługa może zajmować się na raz tylko jednym zadaniem. Bieżącą usługą jest:" |
420 | download_images_warning: "Włączyłeś pobieranie obrazów dla swoich artykułów. W połączeniu z klasycznym importem, może to zająć dużo czasu (lub zakończyć się niepowodzeniem).<strong>Zdecydowanie zalecamy</strong> włączenie asynchronicznego importu, w celu uniknięcia błędów." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Import > Firefox' | 422 | page_title: 'Import > Firefox' |
367 | description: "Ten importer zaimportuje wszystkie twoje zakładki z Firefoksa. Idź do twoich zakładek (Ctrl+Shift+O), następnie w \"Import i kopie zapasowe\", wybierz \"Utwórz kopię zapasową...\". Uzyskasz plik .json." | 423 | description: "Ten importer zaimportuje wszystkie twoje zakładki z Firefoksa. Idź do twoich zakładek (Ctrl+Shift+O), następnie w \"Import i kopie zapasowe\", wybierz \"Utwórz kopię zapasową...\". Uzyskasz plik .json." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Import > Instapaper' | 430 | page_title: 'Import > Instapaper' |
375 | description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Instapaper. W ustawieniach (https://www.instapaper.com/user), kliknij na "Download .CSV file" w sekcji "Export". Otrzymasz plik CSV.' | 431 | description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Instapaper. W ustawieniach (https://www.instapaper.com/user), kliknij na "Download .CSV file" w sekcji "Export". Otrzymasz plik CSV.' |
376 | how_to: 'Wybierz swój plik eksportu z Instapaper i kliknij poniższy przycisk, aby go załadować.' | 432 | how_to: 'Wybierz swój plik eksportu z Instapaper i kliknij poniższy przycisk, aby go załadować.' |
433 | pinboard: | ||
434 | page_title: "Import > Pinboard" | ||
435 | description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Pinboard. W ustawieniach kopii zapasowej (https://pinboard.in/settings/backup), kliknij na "JSON" w sekcji "Bookmarks". Otrzymasz plik "pinboard_export".' | ||
436 | how_to: 'Wybierz swój plik eksportu z Pinboard i kliknij poniższy przycisk, aby go załadować.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Deweloper' | 439 | page_title: 'Deweloper' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: 'Jawne hasło' | 504 | plain_password_label: 'Jawne hasło' |
445 | email_label: 'Adres email' | 505 | email_label: 'Adres email' |
446 | enabled_label: 'Włączony' | 506 | enabled_label: 'Włączony' |
447 | locked_label: 'Zablokowany' | ||
448 | last_login_label: 'Ostatnie logowanie' | 507 | last_login_label: 'Ostatnie logowanie' |
449 | twofactor_label: Autoryzacja dwuetapowa | 508 | twofactor_label: Autoryzacja dwuetapowa |
450 | save: Zapisz | 509 | save: Zapisz |
@@ -453,7 +512,7 @@ user: | |||
453 | back_to_list: Powrót do listy | 512 | back_to_list: Powrót do listy |
454 | 513 | ||
455 | error: | 514 | error: |
456 | # page_title: An error occurred | 515 | page_title: Wystąpił błąd |
457 | 516 | ||
458 | flashes: | 517 | flashes: |
459 | config: | 518 | config: |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'Informacje RSS zaktualizowane' | 524 | rss_updated: 'Informacje RSS zaktualizowane' |
466 | tagging_rules_updated: 'Reguły tagowania zaktualizowane' | 525 | tagging_rules_updated: 'Reguły tagowania zaktualizowane' |
467 | tagging_rules_deleted: 'Reguła tagowania usunięta' | 526 | tagging_rules_deleted: 'Reguła tagowania usunięta' |
468 | user_added: 'Użytkownik "%username%" dodany' | ||
469 | rss_token_updated: 'Token kanału RSS zaktualizowany' | 527 | rss_token_updated: 'Token kanału RSS zaktualizowany' |
528 | annotations_reset: Zresetuj adnotacje | ||
529 | tags_reset: Zresetuj tagi | ||
530 | entries_reset: Zresetuj wpisy | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | entry_already_saved: 'Wpis już został dodany %date%' | 533 | entry_already_saved: 'Wpis już został dodany %date%' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | client_created: 'Nowy klient utworzony.' | 558 | client_created: 'Nowy klient utworzony.' |
498 | client_deleted: 'Klient usunięty' | 559 | client_deleted: 'Klient usunięty' |
560 | user: | ||
561 | notice: | ||
562 | added: 'Użytkownik "%username%" dodany' | ||
563 | updated: 'Użytkownik "%username%" zaktualizowany' | ||
564 | deleted: 'Użytkownik "%username%" usunięty' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml index a375ac7b..f58b2115 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | 200_word: 'Posso ler ~200 palavras por minuto' | 70 | 200_word: 'Posso ler ~200 palavras por minuto' |
71 | 300_word: 'Posso ler ~300 palavras por minuto' | 71 | 300_word: 'Posso ler ~300 palavras por minuto' |
72 | 400_word: 'Posso ler ~400 palavras por minuto' | 72 | 400_word: 'Posso ler ~400 palavras por minuto' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: 'Chave do consumidor do Pocket para importar conteúdo' | 77 | pocket_consumer_key_label: 'Chave do consumidor do Pocket para importar conteúdo' |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'E-mail' | 99 | email_label: 'E-mail' |
95 | twoFactorAuthentication_label: 'Autenticação de dois passos' | 100 | twoFactorAuthentication_label: 'Autenticação de dois passos' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Senha atual' | 116 | old_password_label: 'Senha atual' |
@@ -145,6 +162,7 @@ entry: | |||
145 | archived: 'Entradas arquivadas' | 162 | archived: 'Entradas arquivadas' |
146 | filtered: 'Entradas filtradas' | 163 | filtered: 'Entradas filtradas' |
147 | filtered_tags: 'Filtrar por tags:' | 164 | filtered_tags: 'Filtrar por tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | untagged: 'Entradas sem tags' | 166 | untagged: 'Entradas sem tags' |
149 | list: | 167 | list: |
150 | number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.' | 168 | number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Possui uma imagem de preview' | 186 | preview_picture_label: 'Possui uma imagem de preview' |
169 | preview_picture_help: 'Imagem de preview' | 187 | preview_picture_help: 'Imagem de preview' |
170 | language_label: 'Idioma' | 188 | language_label: 'Idioma' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Tempo de leitura em minutos' | 191 | label: 'Tempo de leitura em minutos' |
173 | from: 'de' | 192 | from: 'de' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | page_title: 'Editar uma entrada' | 234 | page_title: 'Editar uma entrada' |
214 | title_label: 'Título' | 235 | title_label: 'Título' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'How to' | 274 | page_title: 'How to' |
254 | page_description: 'Existem diferentes formas de salvar um artigo:' | 275 | page_description: 'Existem diferentes formas de salvar um artigo:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Extensões de navegadores' | 280 | browser_addons: 'Extensões de navegadores' |
257 | mobile_apps: "App's móveis" | 281 | mobile_apps: "App's móveis" |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Extensão padrão do Firefox' | 286 | firefox: 'Extensão padrão do Firefox' |
263 | chrome: 'Extensão do Chrome' | 287 | chrome: 'Extensão do Chrome' |
288 | opera: 'Extensão do Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'via F-Droid' | 291 | via_f_droid: 'via F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'na Microsoft Store' | 294 | windows: 'na Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Arraste e solve este link na sua barra de favoritos:' | 296 | description: 'Arraste e solve este link na sua barra de favoritos:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | page_title: 'Começo Rápido' | 326 | page_title: 'Começo Rápido' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | number_on_the_page: '{0} Não existem tags.|{1} Uma tag.|]1,Inf[ Existem %count% tags.' | 382 | number_on_the_page: '{0} Não existem tags.|{1} Uma tag.|]1,Inf[ Existem %count% tags.' |
331 | see_untagged_entries: 'Ver entradas sem tags' | 383 | see_untagged_entries: 'Ver entradas sem tags' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | page_title: 'Importar' | 389 | page_title: 'Importar' |
@@ -362,6 +417,7 @@ import: | |||
362 | how_to: 'Por favor, selecione sua exportação do Readability e clique no botão abaixo para importá-la.' | 417 | how_to: 'Por favor, selecione sua exportação do Readability e clique no botão abaixo para importá-la.' |
363 | worker: | 418 | worker: |
364 | enabled: "A importação é feita assíncronamente. Uma vez que a tarefa de importação é iniciada, um trabalho externo pode executar tarefas uma por vez. O serviço atual é:" | 419 | enabled: "A importação é feita assíncronamente. Uma vez que a tarefa de importação é iniciada, um trabalho externo pode executar tarefas uma por vez. O serviço atual é:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | firefox: | 421 | firefox: |
366 | page_title: 'Importar > Firefox' | 422 | page_title: 'Importar > Firefox' |
367 | description: "Com este importador você importa todos os favoritos de seu Firefox. Somente vá até seus favoritos (Ctrl+Maj+O), e em \"Importar e Backup\" e escolha \"Backup...\". Você terá então um arquivo .json." | 423 | description: "Com este importador você importa todos os favoritos de seu Firefox. Somente vá até seus favoritos (Ctrl+Maj+O), e em \"Importar e Backup\" e escolha \"Backup...\". Você terá então um arquivo .json." |
@@ -374,6 +430,10 @@ import: | |||
374 | page_title: 'Importar > Instapaper' | 430 | page_title: 'Importar > Instapaper' |
375 | description: 'Este importador pode importar todos os artigos do seu Instapaper. Nas página de configurações (https://www.instapaper.com/user), clique em "Download .CSV file" na seção "Export". Um arquivo CSV será baixado (algo como "instapaper-export.csv").' | 431 | description: 'Este importador pode importar todos os artigos do seu Instapaper. Nas página de configurações (https://www.instapaper.com/user), clique em "Download .CSV file" na seção "Export". Um arquivo CSV será baixado (algo como "instapaper-export.csv").' |
376 | how_to: 'Por favor, selecione sua exportação do seu Instapaper e clique no botão abaixo para importá-la.' | 432 | how_to: 'Por favor, selecione sua exportação do seu Instapaper e clique no botão abaixo para importá-la.' |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | page_title: 'Desenvolvedor' | 439 | page_title: 'Desenvolvedor' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'E-mail' | 505 | email_label: 'E-mail' |
446 | enabled_label: 'Habilitado' | 506 | enabled_label: 'Habilitado' |
447 | locked_label: 'Travado' | ||
448 | last_login_label: 'Último login' | 507 | last_login_label: 'Último login' |
449 | twofactor_label: 'Autenticação de dois passos' | 508 | twofactor_label: 'Autenticação de dois passos' |
450 | save: 'Salvar' | 509 | save: 'Salvar' |
@@ -452,17 +511,23 @@ user: | |||
452 | delete_confirm: 'Tem certeza?' | 511 | delete_confirm: 'Tem certeza?' |
453 | back_to_list: 'Voltar para a lista' | 512 | back_to_list: 'Voltar para a lista' |
454 | 513 | ||
514 | error: | ||
515 | # page_title: An error occurred | ||
516 | |||
455 | flashes: | 517 | flashes: |
456 | config: | 518 | config: |
457 | notice: | 519 | notice: |
458 | config_saved: 'Configiração salva.' | 520 | config_saved: 'Configiração salva.' |
459 | password_updated: 'Senha atualizada' | 521 | password_updated: 'Senha atualizada' |
460 | password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.' | 522 | password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.' |
461 | user_updated: 'Informação atualizada' | 523 | # user_updated: 'Information updated' |
462 | rss_updated: 'Informação de RSS atualizada' | 524 | rss_updated: 'Informação de RSS atualizada' |
463 | tagging_rules_updated: 'Regras de tags atualizadas' | 525 | tagging_rules_updated: 'Regras de tags atualizadas' |
464 | tagging_rules_deleted: 'Regra de tag apagada' | 526 | tagging_rules_deleted: 'Regra de tag apagada' |
465 | rss_token_updated: 'Token RSS atualizado' | 527 | rss_token_updated: 'Token RSS atualizado' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
466 | entry: | 531 | entry: |
467 | notice: | 532 | notice: |
468 | entry_already_saved: 'Entrada já foi salva em %date%' | 533 | entry_already_saved: 'Entrada já foi salva em %date%' |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml index 7d8fcea3..b9a57e36 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | # 200_word: 'I read ~200 words per minute' | 70 | # 200_word: 'I read ~200 words per minute' |
71 | # 300_word: 'I read ~300 words per minute' | 71 | # 300_word: 'I read ~300 words per minute' |
72 | # 400_word: 'I read ~400 words per minute' | 72 | # 400_word: 'I read ~400 words per minute' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | pocket_consumer_key_label: Cheie consumator pentru importarea contentului din Pocket | 77 | pocket_consumer_key_label: Cheie consumator pentru importarea contentului din Pocket |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'E-mail' | 99 | email_label: 'E-mail' |
95 | # twoFactorAuthentication_label: 'Two factor authentication' | 100 | # twoFactorAuthentication_label: 'Two factor authentication' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Parola veche' | 116 | old_password_label: 'Parola veche' |
@@ -145,6 +162,7 @@ entry: | |||
145 | # archived: 'Archived entries' | 162 | # archived: 'Archived entries' |
146 | # filtered: 'Filtered entries' | 163 | # filtered: 'Filtered entries' |
147 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
148 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
149 | list: | 167 | list: |
150 | # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' | 168 | # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' |
@@ -168,6 +186,7 @@ entry: | |||
168 | preview_picture_label: 'Are o imagine de previzualizare' | 186 | preview_picture_label: 'Are o imagine de previzualizare' |
169 | preview_picture_help: 'Previzualizare imagine' | 187 | preview_picture_help: 'Previzualizare imagine' |
170 | language_label: 'Limbă' | 188 | language_label: 'Limbă' |
189 | # http_status_label: 'HTTP status' | ||
171 | reading_time: | 190 | reading_time: |
172 | label: 'Timp de citire în minute' | 191 | label: 'Timp de citire în minute' |
173 | from: 'de la' | 192 | from: 'de la' |
@@ -209,6 +228,8 @@ entry: | |||
209 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
210 | form_new: | 229 | form_new: |
211 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
212 | edit: | 233 | edit: |
213 | # page_title: 'Edit an entry' | 234 | # page_title: 'Edit an entry' |
214 | # title_label: 'Title' | 235 | # title_label: 'Title' |
@@ -252,6 +273,9 @@ about: | |||
252 | howto: | 273 | howto: |
253 | page_title: 'Cum să' | 274 | page_title: 'Cum să' |
254 | # page_description: 'There are several ways to save an article:' | 275 | # page_description: 'There are several ways to save an article:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
255 | top_menu: | 279 | top_menu: |
256 | browser_addons: 'Add-On-uri de Browser' | 280 | browser_addons: 'Add-On-uri de Browser' |
257 | mobile_apps: 'Aplicații mobile' | 281 | mobile_apps: 'Aplicații mobile' |
@@ -261,6 +285,7 @@ howto: | |||
261 | browser_addons: | 285 | browser_addons: |
262 | firefox: 'Add-On standard de Firefox' | 286 | firefox: 'Add-On standard de Firefox' |
263 | chrome: 'Extensie Chrome' | 287 | chrome: 'Extensie Chrome' |
288 | opera: 'Extensie Opera' | ||
264 | mobile_apps: | 289 | mobile_apps: |
265 | android: | 290 | android: |
266 | via_f_droid: 'prin F-Droid' | 291 | via_f_droid: 'prin F-Droid' |
@@ -269,6 +294,33 @@ howto: | |||
269 | windows: 'prin Microsoft Store' | 294 | windows: 'prin Microsoft Store' |
270 | bookmarklet: | 295 | bookmarklet: |
271 | description: 'Drag & drop acest link în bara de bookmark-uri:' | 296 | description: 'Drag & drop acest link în bara de bookmark-uri:' |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
272 | 324 | ||
273 | quickstart: | 325 | quickstart: |
274 | # page_title: 'Quickstart' | 326 | # page_title: 'Quickstart' |
@@ -329,6 +381,9 @@ tag: | |||
329 | list: | 381 | list: |
330 | # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' | 382 | # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' |
331 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
332 | 387 | ||
333 | import: | 388 | import: |
334 | # page_title: 'Import' | 389 | # page_title: 'Import' |
@@ -362,6 +417,7 @@ import: | |||
362 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
363 | worker: | 418 | worker: |
364 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
365 | # firefox: | 421 | # firefox: |
366 | # page_title: 'Import > Firefox' | 422 | # page_title: 'Import > Firefox' |
367 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -374,6 +430,10 @@ import: | |||
374 | # page_title: 'Import > Instapaper' | 430 | # page_title: 'Import > Instapaper' |
375 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
376 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
377 | 437 | ||
378 | developer: | 438 | developer: |
379 | # page_title: 'Developer' | 439 | # page_title: 'Developer' |
@@ -444,7 +504,6 @@ user: | |||
444 | plain_password_label: '????' | 504 | plain_password_label: '????' |
445 | email_label: 'E-mail' | 505 | email_label: 'E-mail' |
446 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
447 | # locked_label: 'Locked' | ||
448 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
449 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
450 | # save: Save | 509 | # save: Save |
@@ -465,8 +524,10 @@ flashes: | |||
465 | rss_updated: 'Informație RSS actualizată' | 524 | rss_updated: 'Informație RSS actualizată' |
466 | # tagging_rules_updated: 'Tagging rules updated' | 525 | # tagging_rules_updated: 'Tagging rules updated' |
467 | # tagging_rules_deleted: 'Tagging rule deleted' | 526 | # tagging_rules_deleted: 'Tagging rule deleted' |
468 | # user_added: 'User "%username%" added' | ||
469 | # rss_token_updated: 'RSS token updated' | 527 | # rss_token_updated: 'RSS token updated' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
470 | entry: | 531 | entry: |
471 | notice: | 532 | notice: |
472 | # entry_already_saved: 'Entry already saved on %date%' | 533 | # entry_already_saved: 'Entry already saved on %date%' |
@@ -496,3 +557,8 @@ flashes: | |||
496 | notice: | 557 | notice: |
497 | # client_created: 'New client created.' | 558 | # client_created: 'New client created.' |
498 | # client_deleted: 'Client deleted' | 559 | # client_deleted: 'Client deleted' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml index 357aa2ae..ec21c014 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml | |||
@@ -70,7 +70,12 @@ config: | |||
70 | # 200_word: 'I read ~200 words per minute' | 70 | # 200_word: 'I read ~200 words per minute' |
71 | # 300_word: 'I read ~300 words per minute' | 71 | # 300_word: 'I read ~300 words per minute' |
72 | # 400_word: 'I read ~400 words per minute' | 72 | # 400_word: 'I read ~400 words per minute' |
73 | action_mark_as_read: | ||
74 | # label: 'Where do you to be redirected after mark an article as read?' | ||
75 | # redirect_homepage: 'To the homepage' | ||
76 | # redirect_current_page: 'To the current page' | ||
73 | # pocket_consumer_key_label: Consumer key for Pocket to import contents | 77 | # pocket_consumer_key_label: Consumer key for Pocket to import contents |
78 | # android_configuration: Configure your Android application | ||
74 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." | 79 | # help_theme: "wallabag is customizable. You can choose your prefered theme here." |
75 | # help_items_per_page: "You can change the number of articles displayed on each page." | 80 | # help_items_per_page: "You can change the number of articles displayed on each page." |
76 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." | 81 | # help_reading_speed: "wallabag calculates a reading time for each article. You can define here, thanks to this list, if you are a fast or a slow reader. wallabag will recalculate the reading time for each article." |
@@ -94,6 +99,18 @@ config: | |||
94 | email_label: 'E-posta' | 99 | email_label: 'E-posta' |
95 | twoFactorAuthentication_label: 'İki adımlı doğrulama' | 100 | twoFactorAuthentication_label: 'İki adımlı doğrulama' |
96 | # 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: | ||
103 | # title: Delete my account (a.k.a danger zone) | ||
104 | # description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out. | ||
105 | # confirm: Are you really sure? (THIS CAN'T BE UNDONE) | ||
106 | # button: Delete my account | ||
107 | reset: | ||
108 | # title: Reset area (a.k.a danger zone) | ||
109 | # description: By hiting buttons below you'll have ability to remove some informations from your account. Be aware that these actions are IRREVERSIBLE. | ||
110 | # annotations: Remove ALL annotations | ||
111 | # tags: Remove ALL tags | ||
112 | # entries: Remove ALL entries | ||
113 | # confirm: Are you really really sure? (THIS CAN'T BE UNDONE) | ||
97 | form_password: | 114 | form_password: |
98 | # description: "You can change your password here. Your new password should by at least 8 characters long." | 115 | # description: "You can change your password here. Your new password should by at least 8 characters long." |
99 | old_password_label: 'Eski şifre' | 116 | old_password_label: 'Eski şifre' |
@@ -103,6 +120,7 @@ config: | |||
103 | # if_label: 'if' | 120 | # if_label: 'if' |
104 | # then_tag_as_label: 'then tag as' | 121 | # then_tag_as_label: 'then tag as' |
105 | # delete_rule_label: 'delete' | 122 | # delete_rule_label: 'delete' |
123 | # edit_rule_label: 'edit' | ||
106 | rule_label: 'Kural' | 124 | rule_label: 'Kural' |
107 | tags_label: 'Etiketler' | 125 | tags_label: 'Etiketler' |
108 | faq: | 126 | faq: |
@@ -144,6 +162,7 @@ entry: | |||
144 | # archived: 'Archived entries' | 162 | # archived: 'Archived entries' |
145 | # filtered: 'Filtered entries' | 163 | # filtered: 'Filtered entries' |
146 | # filtered_tags: 'Filtered by tags:' | 164 | # filtered_tags: 'Filtered by tags:' |
165 | # filtered_search: 'Filtered by search:' | ||
147 | # untagged: 'Untagged entries' | 166 | # untagged: 'Untagged entries' |
148 | list: | 167 | list: |
149 | number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' | 168 | number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' |
@@ -167,6 +186,7 @@ entry: | |||
167 | preview_picture_label: 'Resim önizlemesi varsa' | 186 | preview_picture_label: 'Resim önizlemesi varsa' |
168 | preview_picture_help: 'Resim önizlemesi' | 187 | preview_picture_help: 'Resim önizlemesi' |
169 | language_label: 'Dil' | 188 | language_label: 'Dil' |
189 | # http_status_label: 'HTTP status' | ||
170 | reading_time: | 190 | reading_time: |
171 | label: 'Dakika cinsinden okuma süresi' | 191 | label: 'Dakika cinsinden okuma süresi' |
172 | from: 'başlangıç' | 192 | from: 'başlangıç' |
@@ -208,6 +228,8 @@ entry: | |||
208 | placeholder: 'http://website.com' | 228 | placeholder: 'http://website.com' |
209 | form_new: | 229 | form_new: |
210 | url_label: Url | 230 | url_label: Url |
231 | search: | ||
232 | # placeholder: 'What are you looking for?' | ||
211 | edit: | 233 | edit: |
212 | page_title: 'Makaleyi düzenle' | 234 | page_title: 'Makaleyi düzenle' |
213 | title_label: 'Başlık' | 235 | title_label: 'Başlık' |
@@ -251,6 +273,9 @@ about: | |||
251 | howto: | 273 | howto: |
252 | page_title: 'Yardım' | 274 | page_title: 'Yardım' |
253 | # page_description: 'There are several ways to save an article:' | 275 | # page_description: 'There are several ways to save an article:' |
276 | tab_menu: | ||
277 | # add_link: "Add a link" | ||
278 | # shortcuts: "Use shortcuts" | ||
254 | top_menu: | 279 | top_menu: |
255 | browser_addons: 'Tarayıcı eklentileri' | 280 | browser_addons: 'Tarayıcı eklentileri' |
256 | mobile_apps: 'Mobil uygulamalar' | 281 | mobile_apps: 'Mobil uygulamalar' |
@@ -260,6 +285,7 @@ howto: | |||
260 | browser_addons: | 285 | browser_addons: |
261 | firefox: 'Standart Firefox Eklentisi' | 286 | firefox: 'Standart Firefox Eklentisi' |
262 | chrome: 'Chrome Eklentisi' | 287 | chrome: 'Chrome Eklentisi' |
288 | opera: 'Opera Eklentisi' | ||
263 | mobile_apps: | 289 | mobile_apps: |
264 | android: | 290 | android: |
265 | # via_f_droid: 'via F-Droid' | 291 | # via_f_droid: 'via F-Droid' |
@@ -268,6 +294,33 @@ howto: | |||
268 | # windows: 'on the Microsoft Store' | 294 | # windows: 'on the Microsoft Store' |
269 | bookmarklet: | 295 | bookmarklet: |
270 | description: "Bu bağlantı ile yer imlerinizi sürükleyip bırakarak wallabag'e ekleyebilirsiniz:" | 296 | description: "Bu bağlantı ile yer imlerinizi sürükleyip bırakarak wallabag'e ekleyebilirsiniz:" |
297 | shortcuts: | ||
298 | # page_description: Here are the shortcuts available in wallabag. | ||
299 | # shortcut: Shortcut | ||
300 | # action: Action | ||
301 | # all_pages_title: Shortcuts available in all pages | ||
302 | # go_unread: Go to unread | ||
303 | # go_starred: Go to starred | ||
304 | # go_archive: Go to archive | ||
305 | # go_all: Go to all entries | ||
306 | # go_tags: Go to tags | ||
307 | # go_config: Go to config | ||
308 | # go_import: Go to import | ||
309 | # go_developers: Go to developers | ||
310 | # go_howto: Go to howto (this page!) | ||
311 | # go_logout: Logout | ||
312 | # list_title: Shortcuts available in listing pages | ||
313 | # search: Display the search form | ||
314 | # article_title: Shortcuts available in entry view | ||
315 | # open_original: Open original URL of the entry | ||
316 | # toggle_favorite: Toggle star status for the entry | ||
317 | # toggle_archive: Toggle read status for the entry | ||
318 | # delete: Delete the entry | ||
319 | # material_title: Shortcuts available with Material theme only | ||
320 | # add_link: Add a new link | ||
321 | # hide_form: Hide the current form (search or new link) | ||
322 | # arrows_navigation: Navigate through articles | ||
323 | # open_article: Display the selected entry | ||
271 | 324 | ||
272 | quickstart: | 325 | quickstart: |
273 | page_title: 'Hızlı başlangıç' | 326 | page_title: 'Hızlı başlangıç' |
@@ -328,6 +381,9 @@ tag: | |||
328 | list: | 381 | list: |
329 | number_on_the_page: '{0} Herhangi bir etiket yok.|{1} Burada bir adet etiket var.|]1,Inf[ Burada %count% adet etiket var.' | 382 | number_on_the_page: '{0} Herhangi bir etiket yok.|{1} Burada bir adet etiket var.|]1,Inf[ Burada %count% adet etiket var.' |
330 | # see_untagged_entries: 'See untagged entries' | 383 | # see_untagged_entries: 'See untagged entries' |
384 | new: | ||
385 | # add: 'Add' | ||
386 | # placeholder: 'You can add several tags, separated by a comma.' | ||
331 | 387 | ||
332 | import: | 388 | import: |
333 | page_title: 'İçe Aktar' | 389 | page_title: 'İçe Aktar' |
@@ -361,6 +417,7 @@ import: | |||
361 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' | 417 | # how_to: 'Please select your Readability export and click on the below button to upload and import it.' |
362 | worker: | 418 | worker: |
363 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" | 419 | # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" |
420 | # download_images_warning: "You enabled downloading images for your articles. Combined with classic import it can take ages to proceed (or maybe failed). We <strong>strongly recommend</strong> to enable asynchronous import to avoid errors." | ||
364 | firefox: | 421 | firefox: |
365 | page_title: 'İçe Aktar > Firefox' | 422 | page_title: 'İçe Aktar > Firefox' |
366 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." | 423 | # description: "This importer will import all your Firefox bookmarks. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file." |
@@ -373,6 +430,10 @@ import: | |||
373 | page_title: 'İçe Aktar > Instapaper' | 430 | page_title: 'İçe Aktar > Instapaper' |
374 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' | 431 | # description: 'This importer will import all your Instapaper articles. On the settings (https://www.instapaper.com/user) page, click on "Download .CSV file" in the "Export" section. A CSV file will be downloaded (like "instapaper-export.csv").' |
375 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' | 432 | # how_to: 'Please select your Instapaper export and click on the below button to upload and import it.' |
433 | pinboard: | ||
434 | # page_title: "Import > Pinboard" | ||
435 | # description: 'This importer will import all your Instapaper articles. On the backup (https://pinboard.in/settings/backup) page, click on "JSON" in the "Bookmarks" section. A JSON file will be downloaded (like "pinboard_export").' | ||
436 | # how_to: 'Please select your Pinboard export and click on the below button to upload and import it.' | ||
376 | 437 | ||
377 | developer: | 438 | developer: |
378 | # page_title: 'Developer' | 439 | # page_title: 'Developer' |
@@ -443,7 +504,6 @@ user: | |||
443 | plain_password_label: '????' | 504 | plain_password_label: '????' |
444 | email_label: 'E-posta' | 505 | email_label: 'E-posta' |
445 | # enabled_label: 'Enabled' | 506 | # enabled_label: 'Enabled' |
446 | # locked_label: 'Locked' | ||
447 | # last_login_label: 'Last login' | 507 | # last_login_label: 'Last login' |
448 | # twofactor_label: Two factor authentication | 508 | # twofactor_label: Two factor authentication |
449 | # save: Save | 509 | # save: Save |
@@ -464,8 +524,10 @@ flashes: | |||
464 | rss_updated: 'RSS bilgiler güncellendi' | 524 | rss_updated: 'RSS bilgiler güncellendi' |
465 | tagging_rules_updated: 'Tagging rules updated' | 525 | tagging_rules_updated: 'Tagging rules updated' |
466 | tagging_rules_deleted: 'Tagging rule deleted' | 526 | tagging_rules_deleted: 'Tagging rule deleted' |
467 | user_added: 'User "%username%" added' | ||
468 | rss_token_updated: 'RSS token updated' | 527 | rss_token_updated: 'RSS token updated' |
528 | # annotations_reset: Annotations reset | ||
529 | # tags_reset: Tags reset | ||
530 | # entries_reset: Entries reset | ||
469 | entry: | 531 | entry: |
470 | notice: | 532 | notice: |
471 | entry_already_saved: 'Entry already saved on %date%' | 533 | entry_already_saved: 'Entry already saved on %date%' |
@@ -495,3 +557,8 @@ flashes: | |||
495 | notice: | 557 | notice: |
496 | # client_created: 'New client created.' | 558 | # client_created: 'New client created.' |
497 | # client_deleted: 'Client deleted' | 559 | # client_deleted: 'Client deleted' |
560 | user: | ||
561 | notice: | ||
562 | # added: 'User "%username%" added' | ||
563 | # updated: 'User "%username%" updated' | ||
564 | # deleted: 'User "%username%" deleted' | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/base.html.twig b/src/Wallabag/CoreBundle/Resources/views/base.html.twig index a1a9a136..289458d4 100644 --- a/src/Wallabag/CoreBundle/Resources/views/base.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/base.html.twig | |||
@@ -41,6 +41,8 @@ | |||
41 | {% block css %} | 41 | {% block css %} |
42 | {% endblock %} | 42 | {% endblock %} |
43 | {% block scripts %} | 43 | {% block scripts %} |
44 | <script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script> | ||
45 | <script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script> | ||
44 | {% endblock %} | 46 | {% endblock %} |
45 | 47 | ||
46 | <title>{% block title %}{% endblock %} – wallabag</title> | 48 | <title>{% block title %}{% endblock %} – wallabag</title> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig index 98b0e119..3548f590 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig | |||
@@ -47,6 +47,14 @@ | |||
47 | 47 | ||
48 | <fieldset class="w500p inline"> | 48 | <fieldset class="w500p inline"> |
49 | <div class="row"> | 49 | <div class="row"> |
50 | {{ form_label(form.config.action_mark_as_read) }} | ||
51 | {{ form_errors(form.config.action_mark_as_read) }} | ||
52 | {{ form_widget(form.config.action_mark_as_read) }} | ||
53 | </div> | ||
54 | </fieldset> | ||
55 | |||
56 | <fieldset class="w500p inline"> | ||
57 | <div class="row"> | ||
50 | {{ form_label(form.config.language) }} | 58 | {{ form_label(form.config.language) }} |
51 | {{ form_errors(form.config.language) }} | 59 | {{ form_errors(form.config.language) }} |
52 | {{ form_widget(form.config.language) }} | 60 | {{ form_widget(form.config.language) }} |
@@ -71,6 +79,19 @@ | |||
71 | </a> | 79 | </a> |
72 | </fieldset> | 80 | </fieldset> |
73 | 81 | ||
82 | <fieldset class="w500p inline"> | ||
83 | <div class="row"> | ||
84 | <h3>{{ 'config.form_settings.android_configuration'|trans }}</h3> | ||
85 | <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}" >Touch here to prefill your Android application</a> | ||
86 | <br/> | ||
87 | <img id="androidQrcode" /> | ||
88 | <script> | ||
89 | const imgBase64 = jrQrcode.getQrBase64('wallabag://{{ app.user.username }}@{{ wallabag_url }}'); | ||
90 | document.getElementById('androidQrcode').src = imgBase64; | ||
91 | </script> | ||
92 | </div> | ||
93 | </fieldset> | ||
94 | |||
74 | {{ form_rest(form.config) }} | 95 | {{ form_rest(form.config) }} |
75 | </form> | 96 | </form> |
76 | 97 | ||
@@ -164,10 +185,41 @@ | |||
164 | </fieldset> | 185 | </fieldset> |
165 | {% endif %} | 186 | {% endif %} |
166 | 187 | ||
188 | <h2>{{ 'config.reset.title'|trans }}</h2> | ||
189 | <fieldset class="w500p inline"> | ||
190 | <p>{{ 'config.reset.description'|trans }}</p> | ||
191 | <ul> | ||
192 | <li> | ||
193 | <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
194 | {{ 'config.reset.annotations'|trans }} | ||
195 | </a> | ||
196 | </li> | ||
197 | <li> | ||
198 | <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
199 | {{ 'config.reset.tags'|trans }} | ||
200 | </a> | ||
201 | </li> | ||
202 | <li> | ||
203 | <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
204 | {{ 'config.reset.entries'|trans }} | ||
205 | </a> | ||
206 | </li> | ||
207 | </ul> | ||
208 | </fieldset> | ||
209 | |||
167 | {{ form_widget(form.user._token) }} | 210 | {{ form_widget(form.user._token) }} |
168 | {{ form_widget(form.user.save) }} | 211 | {{ form_widget(form.user.save) }} |
169 | </form> | 212 | </form> |
170 | 213 | ||
214 | {% if enabled_users > 1 %} | ||
215 | <h2>{{ 'config.form_user.delete.title'|trans }}</h2> | ||
216 | |||
217 | <p>{{ 'config.form_user.delete.description'|trans }}</p> | ||
218 | <a href="{{ path('delete_account') }}" onclick="return confirm('{{ 'config.form_user.delete.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red delete-account"> | ||
219 | {{ 'config.form_user.delete.button'|trans }} | ||
220 | </a> | ||
221 | {% endif %} | ||
222 | |||
171 | <h2>{{ 'config.tab_menu.password'|trans }}</h2> | 223 | <h2>{{ 'config.tab_menu.password'|trans }}</h2> |
172 | 224 | ||
173 | {{ form_start(form.pwd) }} | 225 | {{ form_start(form.pwd) }} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig index 56a0faac..a4a56e46 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig | |||
@@ -1,18 +1,23 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | 1 | {% extends "WallabagCoreBundle::layout.html.twig" %} |
2 | 2 | ||
3 | {% block title %} | 3 | {% block title %} |
4 | {% set currentTag = '' %} | 4 | {% set filter = '' %} |
5 | {% if tag is defined %} | 5 | {% if tag is defined %} |
6 | {% set currentTag = tag %} | 6 | {% set filter = tag %} |
7 | {% endif %} | 7 | {% endif %} |
8 | {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'currentTag': currentTag} %} | 8 | {% if searchTerm is defined and searchTerm is not empty %} |
9 | {% set filter = searchTerm %} | ||
10 | {% endif %} | ||
11 | {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'filter': filter} %} | ||
9 | {% endblock %} | 12 | {% endblock %} |
10 | 13 | ||
11 | {% block content %} | 14 | {% block content %} |
12 | 15 | ||
16 | {% set listMode = app.user.config.listMode %} | ||
13 | <div class="results"> | 17 | <div class="results"> |
14 | <div class="nb-results">{{ 'entry.list.number_on_the_page'|transchoice(entries.count) }}</div> | 18 | <div class="nb-results">{{ 'entry.list.number_on_the_page'|transchoice(entries.count) }}</div> |
15 | <div class="pagination"> | 19 | <div class="pagination"> |
20 | <a href="{{ path('switch_view_mode') }}"><i class="listMode-btn material-icons md-36">{% if listMode == 0 %}list{% else %}view_module{% endif %}</i></a> | ||
16 | <i class="btn-clickable download-btn material-icons md-36">file_download</i> | 21 | <i class="btn-clickable download-btn material-icons md-36">file_download</i> |
17 | <i class="btn-clickable filter-btn material-icons md-36">filter_list</i> | 22 | <i class="btn-clickable filter-btn material-icons md-36">filter_list</i> |
18 | {% if entries.getNbPages > 1 %} | 23 | {% if entries.getNbPages > 1 %} |
@@ -22,7 +27,7 @@ | |||
22 | </div> | 27 | </div> |
23 | 28 | ||
24 | {% for entry in entries %} | 29 | {% for entry in entries %} |
25 | <div id="entry-{{ entry.id|e }}" class="entry"> | 30 | <div id="entry-{{ entry.id|e }}" class="{% if listMode == 0 %}entry{% else %}listmode entry{% endif %}"> |
26 | <h2><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|raw }}">{{ entry.title|raw }}</a></h2> | 31 | <h2><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|raw }}">{{ entry.title|raw }}</a></h2> |
27 | 32 | ||
28 | {% set readingTime = entry.readingTime / app.user.config.readingSpeed %} | 33 | {% set readingTime = entry.readingTime / app.user.config.readingSpeed %} |
@@ -47,13 +52,13 @@ | |||
47 | <li><a title="{{ 'entry.list.delete'|trans }}" class="tool delete icon-trash icon" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.list.delete'|trans }}</span></a></li> | 52 | <li><a title="{{ 'entry.list.delete'|trans }}" class="tool delete icon-trash icon" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.list.delete'|trans }}</span></a></li> |
48 | <li><a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.list.original_article'|trans }} : {{ entry.title|e }}" class="tool link icon-link icon"><span>{{ entry.domainName|removeWww }}</span></a></li> | 53 | <li><a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.list.original_article'|trans }} : {{ entry.title|e }}" class="tool link icon-link icon"><span>{{ entry.domainName|removeWww }}</span></a></li> |
49 | </ul> | 54 | </ul> |
50 | {% if entry.previewPicture is null %} | 55 | {% if (entry.previewPicture is null or listMode == 1) %} |
51 | <ul class="card-entry-tags"> | 56 | <ul class="card-entry-tags"> |
52 | {% for tag in entry.tags %} | 57 | {% for tag in entry.tags %} |
53 | <li><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a></li> | 58 | <li><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a></li> |
54 | {% endfor %} | 59 | {% endfor %} |
55 | </ul> | 60 | </ul> |
56 | <p>{{ entry.content|striptags|slice(0, 300) }}…</p> | 61 | <p {% if listMode == 1 %}class="hide"{% endif %}>{{ entry.content|striptags|slice(0, 300) }}…</p> |
57 | {% else %} | 62 | {% else %} |
58 | <ul class="card-entry-labels"> | 63 | <ul class="card-entry-labels"> |
59 | {% for tag in entry.tags | slice(0, 3) %} | 64 | {% for tag in entry.tags | slice(0, 3) %} |
@@ -131,6 +136,13 @@ | |||
131 | </div> | 136 | </div> |
132 | </div> | 137 | </div> |
133 | 138 | ||
139 | <div id="filter-http-status" class="filter-group"> | ||
140 | {{ form_label(form.httpStatus) }} | ||
141 | <div class="input-field "> | ||
142 | {{ form_widget(form.httpStatus) }} | ||
143 | </div> | ||
144 | </div> | ||
145 | |||
134 | <div id="filter-reading-time" class="filter-group"> | 146 | <div id="filter-reading-time" class="filter-group"> |
135 | <div class=""> | 147 | <div class=""> |
136 | {{ form_label(form.readingTime) }} | 148 | {{ form_label(form.readingTime) }} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig index 950b3909..8ac2bc0b 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entry.html.twig | |||
@@ -11,7 +11,7 @@ | |||
11 | <div id="article_toolbar"> | 11 | <div id="article_toolbar"> |
12 | <ul class="links"> | 12 | <ul class="links"> |
13 | <li class="topPosF"><a href="#top" title="{{ 'entry.view.left_menu.back_to_top'|trans }}" class="tool top icon icon-arrow-up-thick"><span>{{ 'entry.view.left_menu.set_as_read'|trans }}</span></a></li> | 13 | <li class="topPosF"><a href="#top" title="{{ 'entry.view.left_menu.back_to_top'|trans }}" class="tool top icon icon-arrow-up-thick"><span>{{ 'entry.view.left_menu.set_as_read'|trans }}</span></a></li> |
14 | <li><a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|e }}" class="tool link icon icon-link"><span>{{ entry.domainName|removeWww }}</span></a></li> | 14 | <li><a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|e }}" class="tool link icon icon-link original"><span>{{ entry.domainName|removeWww }}</span></a></li> |
15 | <li><a title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}" class="tool icon icon-reload" href="{{ path('reload_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span></a></li> | 15 | <li><a title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}" class="tool icon icon-reload" href="{{ path('reload_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span></a></li> |
16 | 16 | ||
17 | {% set markAsReadLabel = 'entry.view.left_menu.set_as_unread' %} | 17 | {% set markAsReadLabel = 'entry.view.left_menu.set_as_unread' %} |
@@ -19,8 +19,8 @@ | |||
19 | {% set markAsReadLabel = 'entry.view.left_menu.set_as_read' %} | 19 | {% set markAsReadLabel = 'entry.view.left_menu.set_as_read' %} |
20 | {% endif %} | 20 | {% endif %} |
21 | 21 | ||
22 | <li><a title="{{ markAsReadLabel|trans }}" class="tool icon icon-check {% if entry.isArchived == 0 %}archive-off{% else %}archive{% endif %}" href="{{ path('archive_entry', { 'id': entry.id }) }}"><span>{{ markAsReadLabel|trans }}</span></a></li> | 22 | <li><a title="{{ markAsReadLabel|trans }}" class="tool icon icon-check {% if entry.isArchived == 0 %}archive-off{% else %}archive{% endif %} markasread" href="{{ path('archive_entry', { 'id': entry.id }) }}"><span>{{ markAsReadLabel|trans }}</span></a></li> |
23 | <li><a title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" class="tool icon icon-star {% if entry.isStarred == 0 %}fav-off{% else %}fav{% endif %}" href="{{ path('star_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span></a></li> | 23 | <li><a title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" class="tool icon icon-star {% if entry.isStarred == 0 %}fav-off{% else %}fav{% endif %} favorite" href="{{ path('star_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span></a></li> |
24 | <li><a id="nav-btn-add-tag" class="tool icon icon-price-tags" title="{{ 'entry.view.left_menu.add_a_tag'|trans }}"><span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span></a></li> | 24 | <li><a id="nav-btn-add-tag" class="tool icon icon-price-tags" title="{{ 'entry.view.left_menu.add_a_tag'|trans }}"><span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span></a></li> |
25 | <li><a title="{{ 'entry.view.left_menu.delete'|trans }}" class="tool delete icon icon-trash" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.delete'|trans }}</span></a></li> | 25 | <li><a title="{{ 'entry.view.left_menu.delete'|trans }}" class="tool delete icon icon-trash" href="{{ path('delete_entry', { 'id': entry.id }) }}"><span>{{ 'entry.view.left_menu.delete'|trans }}</span></a></li> |
26 | {% if craue_setting('share_public') %} | 26 | {% if craue_setting('share_public') %} |
@@ -31,6 +31,7 @@ | |||
31 | {% if craue_setting('share_mail') %}<li><a href="mailto:?subject={{ entry.title|url_encode }}&body={{ entry.url|url_encode }}%20via%20@wallabagapp" class="tool email icon icon-mail" title="Email"><span>Email</span></a></li>{% endif %} | 31 | {% if craue_setting('share_mail') %}<li><a href="mailto:?subject={{ entry.title|url_encode }}&body={{ entry.url|url_encode }}%20via%20@wallabagapp" class="tool email icon icon-mail" title="Email"><span>Email</span></a></li>{% endif %} |
32 | {% if craue_setting('share_shaarli') %}<li><a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}&tags={{ entry.tags|join(',')|url_encode }}" target="_blank" class="tool icon-image icon-image--shaarli" title="shaarli"><span>shaarli</span></a></li>{% endif %} | 32 | {% if craue_setting('share_shaarli') %}<li><a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}&tags={{ entry.tags|join(',')|url_encode }}" target="_blank" class="tool icon-image icon-image--shaarli" title="shaarli"><span>shaarli</span></a></li>{% endif %} |
33 | {% if craue_setting('share_diaspora') %}<li><a href="{{ craue_setting('diaspora_url') }}/bookmarklet?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}¬es=&v=1&noui=1&jump=doclose" target="_blank" class="tool diaspora icon-image icon-image--diaspora" title="diaspora"><span>diaspora</span></a></li>{% endif %} | 33 | {% if craue_setting('share_diaspora') %}<li><a href="{{ craue_setting('diaspora_url') }}/bookmarklet?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}¬es=&v=1&noui=1&jump=doclose" target="_blank" class="tool diaspora icon-image icon-image--diaspora" title="diaspora"><span>diaspora</span></a></li>{% endif %} |
34 | {% if craue_setting('share_unmark') %}<li><a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&title={{entry.title|url_encode}}&v=6" target="_blank" class="tool unmark icon-image icon-image--unmark" title="unmark"><span>unmark.it</span></a></li>{% endif %} | ||
34 | {% if craue_setting('carrot') %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="carrot"><span>Carrot</span></a></li>{% endif %} | 35 | {% if craue_setting('carrot') %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="carrot"><span>Carrot</span></a></li>{% endif %} |
35 | {% if craue_setting('show_printlink') %}<li><a title="{{ 'entry.view.left_menu.print'|trans }}" class="tool icon icon-print" href="javascript: window.print();"><span>{{ 'entry.view.left_menu.print'|trans }}</span></a></li>{% endif %} | 36 | {% if craue_setting('show_printlink') %}<li><a title="{{ 'entry.view.left_menu.print'|trans }}" class="tool icon icon-print" href="javascript: window.print();"><span>{{ 'entry.view.left_menu.print'|trans }}</span></a></li>{% endif %} |
36 | {% if craue_setting('export_epub') %}<li><a href="?epub&method=id&value={{ entry.id }}" title="Generate ePub file">EPUB</a></li>{% endif %} | 37 | {% if craue_setting('export_epub') %}<li><a href="?epub&method=id&value={{ entry.id }}" title="Generate ePub file">EPUB</a></li>{% endif %} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig new file mode 100644 index 00000000..20821b6d --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/search_form.html.twig | |||
@@ -0,0 +1,17 @@ | |||
1 | <form name="search" method="GET" action="{{ path('search')}}"> | ||
2 | <h2>{{ 'menu.left.search'|trans }}</h2> | ||
3 | <a href="javascript: void(null);" id="search-form-close" class="close-button--popup close-button">×</a> | ||
4 | {% if form_errors(form) %} | ||
5 | <span class="black-text">{{ form_errors(form) }}</span> | ||
6 | {% endif %} | ||
7 | |||
8 | {% if form_errors(form.term) %} | ||
9 | <span class="black-text">{{ form_errors(form.term) }}</span> | ||
10 | {% endif %} | ||
11 | |||
12 | <input type="hidden" name="currentRoute" value="{{ currentRoute }}" /> | ||
13 | |||
14 | {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'entry.search.placeholder'} }) }} | ||
15 | |||
16 | {{ form_rest(form) }} | ||
17 | </form> | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig index cd4ed3fa..07ff8e14 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig | |||
@@ -31,17 +31,11 @@ | |||
31 | <li class="menu all"><a href="{{ path('all') }}">{{ 'menu.left.all_articles'|trans }}</a></li> | 31 | <li class="menu all"><a href="{{ path('all') }}">{{ 'menu.left.all_articles'|trans }}</a></li> |
32 | <li class="menu tag"><a href="{{ path('tag') }}">{{ 'menu.left.tags'|trans }}</a></li> | 32 | <li class="menu tag"><a href="{{ path('tag') }}">{{ 'menu.left.tags'|trans }}</a></li> |
33 | <li class="menu new"><a href="{{ path('new') }}">{{ 'menu.left.save_link'|trans }}</a></li> | 33 | <li class="menu new"><a href="{{ path('new') }}">{{ 'menu.left.save_link'|trans }}</a></li> |
34 | <!--<li style="position: relative;"><a href="javascript: void(null);" id="search">{{ 'menu.left.search'|trans }}</a> | 34 | <li style="position: relative;"><a href="javascript: void(null);" id="search">{{ 'menu.left.search'|trans }}</a> |
35 | <div id="search-form" class="messages info popup-form"> | 35 | <div id="search-form" class="messages info popup-form"> |
36 | <form method="get" action="index.php"> | 36 | {{ render(controller("WallabagCoreBundle:Entry:searchForm", {'currentRoute': app.request.attributes.get('_route')})) }} |
37 | <h2>{{ 'menu.left.search'|trans }}</h2> | ||
38 | <a href="javascript: void(null);" id="search-form-close" class="close-button--popup close-button">×</a> | ||
39 | <input type="hidden" name="view" value="search"> | ||
40 | <input required placeholder="{{ 'menu.search_form.input_label'|trans }}" type="text" name="search" id="searchfield"><br> | ||
41 | <input id="submit-search" type="submit" value="{{ 'menu.left.search'|trans }}"> | ||
42 | </form> | ||
43 | </div> | 37 | </div> |
44 | </li>--> | 38 | </li> |
45 | <li class="menu config"><a href="{{ path('config') }}">{{ 'menu.left.config'|trans }}</a></li> | 39 | <li class="menu config"><a href="{{ path('config') }}">{{ 'menu.left.config'|trans }}</a></li> |
46 | {% if is_granted('ROLE_SUPER_ADMIN') %} | 40 | {% if is_granted('ROLE_SUPER_ADMIN') %} |
47 | <li class="menu users"><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li> | 41 | <li class="menu users"><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig index 92cabdd9..654c1d2d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig | |||
@@ -6,8 +6,10 @@ | |||
6 | {{ 'entry.page_titles.archived'|trans }} | 6 | {{ 'entry.page_titles.archived'|trans }} |
7 | {% elseif currentRoute == 'all' %} | 7 | {% elseif currentRoute == 'all' %} |
8 | {{ 'entry.page_titles.filtered'|trans }} | 8 | {{ 'entry.page_titles.filtered'|trans }} |
9 | {% elseif currentRoute == 'search' %} | ||
10 | {{ 'entry.page_titles.filtered_search'|trans }} {{ filter }} | ||
9 | {% elseif currentRoute == 'tag_entries' %} | 11 | {% elseif currentRoute == 'tag_entries' %} |
10 | {{ 'entry.page_titles.filtered_tags'|trans }} {{ currentTag }} | 12 | {{ 'entry.page_titles.filtered_tags'|trans }} {{ filter }} |
11 | {% elseif currentRoute == 'untagged' %} | 13 | {% elseif currentRoute == 'untagged' %} |
12 | {{ 'entry.page_titles.untagged'|trans }} | 14 | {{ 'entry.page_titles.untagged'|trans }} |
13 | {% else %} | 15 | {% else %} |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig index 288bb54f..16ecaa97 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig | |||
@@ -2,7 +2,15 @@ | |||
2 | <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/"> | 2 | <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/"> |
3 | <channel> | 3 | <channel> |
4 | <title>wallabag — {{type}} feed</title> | 4 | <title>wallabag — {{type}} feed</title> |
5 | <link>{{ url('unread') }}</link> | 5 | <link>{{ url(type) }}</link> |
6 | <link rel="self" href="{{ app.request.uri }}"/> | ||
7 | {% if entries.hasPreviousPage -%} | ||
8 | <link rel="previous" href="{{ url }}?page={{ entries.previousPage }}"/> | ||
9 | {% endif -%} | ||
10 | {% if entries.hasNextPage -%} | ||
11 | <link rel="next" href="{{ url }}?page={{ entries.nextPage }}"/> | ||
12 | {% endif -%} | ||
13 | <link rel="last" href="{{ url }}?page={{ entries.nbPages }}"/> | ||
6 | <pubDate>{{ "now"|date('D, d M Y H:i:s') }}</pubDate> | 14 | <pubDate>{{ "now"|date('D, d M Y H:i:s') }}</pubDate> |
7 | <generator>wallabag</generator> | 15 | <generator>wallabag</generator> |
8 | <description>wallabag {{type}} elements</description> | 16 | <description>wallabag {{type}} elements</description> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig index 67a10190..231f9bdf 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/howto.html.twig | |||
@@ -7,38 +7,186 @@ | |||
7 | <div class="row"> | 7 | <div class="row"> |
8 | <div class="col s12"> | 8 | <div class="col s12"> |
9 | <div class="card-panel settings"> | 9 | <div class="card-panel settings"> |
10 | <p>{{ 'howto.page_description'|trans }}</p> | ||
11 | 10 | ||
12 | <div class="row"> | 11 | <div class="row"> |
13 | 12 | <div class="div_tabs col s12"> | |
14 | <div class="col s12"> | 13 | <ul class="tabs"> |
15 | <a href="{{ path('new') }}">{{ 'howto.form.description'|trans }}</a> | 14 | <li class="tab col s12 m6 l3"><a class="active" href="#set1">{{ 'howto.tab_menu.add_link'|trans }}</a></li> |
16 | </div> | 15 | <li class="tab col s12 m6 l3"><a href="#set2">{{ 'howto.tab_menu.shortcuts'|trans }}</a></li> |
17 | |||
18 | <div class="col s12"> | ||
19 | <h5>{{ 'howto.top_menu.browser_addons'|trans }}</h5> | ||
20 | <ul> | ||
21 | <li><a href="{{ addonsUrl.firefox }}" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li> | ||
22 | <li><a href="{{ addonsUrl.chrome }}" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li> | ||
23 | </ul> | 16 | </ul> |
24 | </div> | 17 | </div> |
25 | 18 | ||
26 | <div class="col s12"> | 19 | <div id="set1" class="col s12"> |
27 | <h5>{{ 'howto.top_menu.mobile_apps'|trans }}</h5> | 20 | <p>{{ 'howto.page_description'|trans }}</p> |
28 | <ul> | 21 | |
29 | <li>Android: <a href="{{ addonsUrl.f_droid }}" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="{{ addonsUrl.google_play }}" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li> | 22 | <div class="row"> |
30 | <li>iOS: <a href="{{ addonsUrl.ios }}" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li> | ||
31 | <li>Windows Phone: <a href="{{ addonsUrl.windows }}" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li> | ||
32 | </ul> | ||
33 | </div> | ||
34 | 23 | ||
35 | <div class="col s12"> | 24 | <div class="col s12"> |
36 | <h5>{{ 'howto.top_menu.bookmarklet'|trans }}</h5> | 25 | <a href="{{ path('new') }}">{{ 'howto.form.description'|trans }}</a> |
37 | {{ 'howto.bookmarklet.description'|trans }} | 26 | </div> |
38 | {% include '@WallabagCore/themes/common/Static/_bookmarklet.html.twig' %} | 27 | |
28 | <div class="col s12"> | ||
29 | <h5>{{ 'howto.top_menu.browser_addons'|trans }}</h5> | ||
30 | <ul> | ||
31 | <li><a href="{{ addonsUrl.firefox }}" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li> | ||
32 | <li><a href="{{ addonsUrl.chrome }}" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li> | ||
33 | <li><a href="{{ addonsUrl.opera }}" target="_blank">{{ 'howto.browser_addons.opera'|trans }}</a></li> | ||
34 | </ul> | ||
35 | </div> | ||
36 | |||
37 | <div class="col s12"> | ||
38 | <h5>{{ 'howto.top_menu.mobile_apps'|trans }}</h5> | ||
39 | <ul> | ||
40 | <li>Android: <a href="{{ addonsUrl.f_droid }}" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="{{ addonsUrl.google_play }}" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li> | ||
41 | <li>iOS: <a href="{{ addonsUrl.ios }}" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li> | ||
42 | <li>Windows Phone: <a href="{{ addonsUrl.windows }}" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li> | ||
43 | </ul> | ||
44 | </div> | ||
45 | |||
46 | <div class="col s12"> | ||
47 | <h5>{{ 'howto.top_menu.bookmarklet'|trans }}</h5> | ||
48 | {{ 'howto.bookmarklet.description'|trans }} | ||
49 | {% include '@WallabagCore/themes/common/Static/_bookmarklet.html.twig' %} | ||
50 | </div> | ||
51 | |||
52 | </div> | ||
39 | </div> | 53 | </div> |
40 | 54 | ||
41 | </div> | 55 | <div id="set2" class="col s12"> |
56 | <p>{{ 'howto.shortcuts.page_description'|trans }}</p> | ||
57 | |||
58 | <h5>{{ 'howto.shortcuts.all_pages_title'|trans }}</h5> | ||
59 | |||
60 | <table class="bordered"> | ||
61 | <thead> | ||
62 | <tr> | ||
63 | <th>{{ 'howto.shortcuts.shortcut'|trans }}</th> | ||
64 | <th>{{ 'howto.shortcuts.action'|trans }}</th> | ||
65 | </tr> | ||
66 | </thead> | ||
67 | |||
68 | <tbody> | ||
69 | <tr> | ||
70 | <td><code>g u</code></td> | ||
71 | <td>{{ 'howto.shortcuts.go_unread'|trans }}</td> | ||
72 | </tr> | ||
73 | <tr> | ||
74 | <td><code>g s</code></td> | ||
75 | <td>{{ 'howto.shortcuts.go_starred'|trans }}</td> | ||
76 | </tr> | ||
77 | <tr> | ||
78 | <td><code>g r</code></td> | ||
79 | <td>{{ 'howto.shortcuts.go_archive'|trans }}</td> | ||
80 | </tr> | ||
81 | <tr> | ||
82 | <td><code>g a</code></td> | ||
83 | <td>{{ 'howto.shortcuts.go_all'|trans }}</td> | ||
84 | </tr> | ||
85 | <tr> | ||
86 | <td><code>g t</code></td> | ||
87 | <td>{{ 'howto.shortcuts.go_tags'|trans }}</td> | ||
88 | </tr> | ||
89 | <tr> | ||
90 | <td><code>g c</code></td> | ||
91 | <td>{{ 'howto.shortcuts.go_config'|trans }}</td> | ||
92 | </tr> | ||
93 | <tr> | ||
94 | <td><code>g i</code></td> | ||
95 | <td>{{ 'howto.shortcuts.go_import'|trans }}</td> | ||
96 | </tr> | ||
97 | <tr> | ||
98 | <td><code>g d</code></td> | ||
99 | <td>{{ 'howto.shortcuts.go_developers'|trans }}</td> | ||
100 | </tr> | ||
101 | <tr> | ||
102 | <td><code>?</code></td> | ||
103 | <td>{{ 'howto.shortcuts.go_howto'|trans }}</td> | ||
104 | </tr> | ||
105 | <tr> | ||
106 | <td><code>g l</code></td> | ||
107 | <td>{{ 'howto.shortcuts.go_logout'|trans }}</td> | ||
108 | </tr> | ||
109 | </tbody> | ||
110 | </table> | ||
111 | |||
112 | <h5>{{ 'howto.shortcuts.list_title'|trans }}</h5> | ||
113 | |||
114 | <table class="bordered"> | ||
115 | <thead> | ||
116 | <tr> | ||
117 | <th>{{ 'howto.shortcuts.shortcut'|trans }}</th> | ||
118 | <th>{{ 'howto.shortcuts.action'|trans }}</th> | ||
119 | </tr> | ||
120 | </thead> | ||
121 | |||
122 | <tbody> | ||
123 | <tr> | ||
124 | <td><code>s</code></td> | ||
125 | <td>{{ 'howto.shortcuts.search'|trans }}</td> | ||
126 | </tr> | ||
127 | </tbody> | ||
128 | </table> | ||
129 | |||
130 | <h5>{{ 'howto.shortcuts.article_title'|trans }}</h5> | ||
131 | |||
132 | <table class="bordered"> | ||
133 | <thead> | ||
134 | <tr> | ||
135 | <th>{{ 'howto.shortcuts.shortcut'|trans }}</th> | ||
136 | <th>{{ 'howto.shortcuts.action'|trans }}</th> | ||
137 | </tr> | ||
138 | </thead> | ||
139 | |||
140 | <tbody> | ||
141 | <tr> | ||
142 | <td><code>o</code></td> | ||
143 | <td>{{ 'howto.shortcuts.open_original'|trans }}</td> | ||
144 | </tr> | ||
145 | <tr> | ||
146 | <td><code>f</code></td> | ||
147 | <td>{{ 'howto.shortcuts.toggle_favorite'|trans }}</td> | ||
148 | </tr> | ||
149 | <tr> | ||
150 | <td><code>a</code></td> | ||
151 | <td>{{ 'howto.shortcuts.toggle_archive'|trans }}</td> | ||
152 | </tr> | ||
153 | <tr> | ||
154 | <td><code>del</code></td> | ||
155 | <td>{{ 'howto.shortcuts.delete'|trans }}</td> | ||
156 | </tr> | ||
157 | </tbody> | ||
158 | </table> | ||
159 | |||
160 | <h5>{{ 'howto.shortcuts.material_title'|trans }}</h5> | ||
161 | |||
162 | <table class="bordered"> | ||
163 | <thead> | ||
164 | <tr> | ||
165 | <th>{{ 'howto.shortcuts.shortcut'|trans }}</th> | ||
166 | <th>{{ 'howto.shortcuts.action'|trans }}</th> | ||
167 | </tr> | ||
168 | </thead> | ||
169 | |||
170 | <tbody> | ||
171 | <tr> | ||
172 | <td><code>g n</code></td> | ||
173 | <td>{{ 'howto.shortcuts.add_link'|trans }}</td> | ||
174 | </tr> | ||
175 | <tr> | ||
176 | <td><code>esc</code></td> | ||
177 | <td>{{ 'howto.shortcuts.hide_form'|trans }}</td> | ||
178 | </tr> | ||
179 | <tr> | ||
180 | <td><code>← →</code></td> | ||
181 | <td>{{ 'howto.shortcuts.arrows_navigation'|trans }}</td> | ||
182 | </tr> | ||
183 | <tr> | ||
184 | <td><code>enter</code></td> | ||
185 | <td>{{ 'howto.shortcuts.open_article'|trans }}</td> | ||
186 | </tr> | ||
187 | </tbody> | ||
188 | </table> | ||
189 | </div> | ||
42 | 190 | ||
43 | </div> | 191 | </div> |
44 | </div> | 192 | </div> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig index c8a303a6..b7a48551 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Static/quickstart.html.twig | |||
@@ -15,7 +15,7 @@ | |||
15 | <li class="col l4 m6 s12"> | 15 | <li class="col l4 m6 s12"> |
16 | <div class="card teal darken-1"> | 16 | <div class="card teal darken-1"> |
17 | <div class="card-content white-text"> | 17 | <div class="card-content white-text"> |
18 | <span class="card-title">{{ 'quickstart.configure.title'|trans }}</span> | 18 | <span class="card-title white-text">{{ 'quickstart.configure.title'|trans }}</span> |
19 | <p>{{ 'quickstart.configure.description'|trans }}</p> | 19 | <p>{{ 'quickstart.configure.description'|trans }}</p> |
20 | </div> | 20 | </div> |
21 | <div class="card-action"> | 21 | <div class="card-action"> |
@@ -31,7 +31,7 @@ | |||
31 | <li class="col l4 m6 s12"> | 31 | <li class="col l4 m6 s12"> |
32 | <div class="card green darken-1"> | 32 | <div class="card green darken-1"> |
33 | <div class="card-content white-text"> | 33 | <div class="card-content white-text"> |
34 | <span class="card-title">{{ 'quickstart.first_steps.title'|trans }}</span> | 34 | <span class="card-title white-text">{{ 'quickstart.first_steps.title'|trans }}</span> |
35 | <p>{{ 'quickstart.first_steps.description'|trans }}</p> | 35 | <p>{{ 'quickstart.first_steps.description'|trans }}</p> |
36 | </div> | 36 | </div> |
37 | <div class="card-action"> | 37 | <div class="card-action"> |
@@ -46,7 +46,7 @@ | |||
46 | <li class="col l4 m6 s12"> | 46 | <li class="col l4 m6 s12"> |
47 | <div class="card light-green darken-1"> | 47 | <div class="card light-green darken-1"> |
48 | <div class="card-content white-text"> | 48 | <div class="card-content white-text"> |
49 | <span class="card-title">{{ 'quickstart.migrate.title'|trans }}</span> | 49 | <span class="card-title white-text">{{ 'quickstart.migrate.title'|trans }}</span> |
50 | <p>{{ 'quickstart.migrate.description'|trans }}</p> | 50 | <p>{{ 'quickstart.migrate.description'|trans }}</p> |
51 | </div> | 51 | </div> |
52 | <div class="card-action"> | 52 | <div class="card-action"> |
@@ -63,7 +63,7 @@ | |||
63 | <li class="col l4 m6 s12"> | 63 | <li class="col l4 m6 s12"> |
64 | <div class="card blue darken-1"> | 64 | <div class="card blue darken-1"> |
65 | <div class="card-content white-text"> | 65 | <div class="card-content white-text"> |
66 | <span class="card-title">{{ 'quickstart.developer.title'|trans }}</span> | 66 | <span class="card-title white-text">{{ 'quickstart.developer.title'|trans }}</span> |
67 | <p>{{ 'quickstart.developer.description'|trans }}</p> | 67 | <p>{{ 'quickstart.developer.description'|trans }}</p> |
68 | </div> | 68 | </div> |
69 | <div class="card-action"> | 69 | <div class="card-action"> |
@@ -79,7 +79,7 @@ | |||
79 | <li class="col l4 m6 s12"> | 79 | <li class="col l4 m6 s12"> |
80 | <div class="card light-blue darken-1"> | 80 | <div class="card light-blue darken-1"> |
81 | <div class="card-content white-text"> | 81 | <div class="card-content white-text"> |
82 | <span class="card-title">{{ 'quickstart.docs.title'|trans }}</span> | 82 | <span class="card-title white-text">{{ 'quickstart.docs.title'|trans }}</span> |
83 | <p>{{ 'quickstart.docs.description'|trans }}</p> | 83 | <p>{{ 'quickstart.docs.description'|trans }}</p> |
84 | </div> | 84 | </div> |
85 | <div class="card-action"> | 85 | <div class="card-action"> |
@@ -95,7 +95,7 @@ | |||
95 | <li class="col l4 m6 s12"> | 95 | <li class="col l4 m6 s12"> |
96 | <div class="card cyan darken-1"> | 96 | <div class="card cyan darken-1"> |
97 | <div class="card-content white-text"> | 97 | <div class="card-content white-text"> |
98 | <span class="card-title">{{ 'quickstart.support.title'|trans }}</span> | 98 | <span class="card-title white-text">{{ 'quickstart.support.title'|trans }}</span> |
99 | <p>{{ 'quickstart.support.description'|trans }}</p> | 99 | <p>{{ 'quickstart.support.description'|trans }}</p> |
100 | </div> | 100 | </div> |
101 | <div class="card-action"> | 101 | <div class="card-action"> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig index 9f67217b..5d411fdd 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig | |||
@@ -66,6 +66,14 @@ | |||
66 | </div> | 66 | </div> |
67 | </div> | 67 | </div> |
68 | 68 | ||
69 | <div class="row"> | ||
70 | <div class="input-field col s12"> | ||
71 | {{ form_label(form.config.action_mark_as_read) }} | ||
72 | {{ form_errors(form.config.action_mark_as_read) }} | ||
73 | {{ form_widget(form.config.action_mark_as_read) }} | ||
74 | </div> | ||
75 | </div> | ||
76 | |||
69 | <div class="row"> | 77 | <div class="row"> |
70 | <div class="input-field col s11"> | 78 | <div class="input-field col s11"> |
71 | {{ form_label(form.config.language) }} | 79 | {{ form_label(form.config.language) }} |
@@ -96,6 +104,18 @@ | |||
96 | </div> | 104 | </div> |
97 | </div> | 105 | </div> |
98 | 106 | ||
107 | <div class="row"> | ||
108 | <div class="input-field col s12"> | ||
109 | <h5>{{ 'config.form_settings.android_configuration'|trans }}</h5> | ||
110 | <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}" class="waves-effect waves-light btn hide-on-large-only">Touch here to prefill your Android application</a> | ||
111 | <img id="androidQrcode" class="hide-on-med-and-down" /> | ||
112 | </div> | ||
113 | <script> | ||
114 | const imgBase64 = jrQrcode.getQrBase64('wallabag://{{ app.user.username }}@{{ wallabag_url }}'); | ||
115 | document.getElementById('androidQrcode').src = imgBase64; | ||
116 | </script> | ||
117 | </div> | ||
118 | |||
99 | {{ form_widget(form.config.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} | 119 | {{ form_widget(form.config.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} |
100 | {{ form_rest(form.config) }} | 120 | {{ form_rest(form.config) }} |
101 | </form> | 121 | </form> |
@@ -197,6 +217,34 @@ | |||
197 | {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} | 217 | {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} |
198 | {{ form_widget(form.user._token) }} | 218 | {{ form_widget(form.user._token) }} |
199 | </form> | 219 | </form> |
220 | |||
221 | <br /><hr /><br /> | ||
222 | |||
223 | <div class="row"> | ||
224 | <h5>{{ 'config.reset.title'|trans }}</h5> | ||
225 | <p>{{ 'config.reset.description'|trans }}</p> | ||
226 | <a href="{{ path('config_reset', { type: 'annotations'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
227 | {{ 'config.reset.annotations'|trans }} | ||
228 | </a> | ||
229 | <a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
230 | {{ 'config.reset.tags'|trans }} | ||
231 | </a> | ||
232 | <a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red"> | ||
233 | {{ 'config.reset.entries'|trans }} | ||
234 | </a> | ||
235 | </div> | ||
236 | |||
237 | {% if enabled_users > 1 %} | ||
238 | <br /><hr /><br /> | ||
239 | |||
240 | <div class="row"> | ||
241 | <h5>{{ 'config.form_user.delete.title'|trans }}</h5> | ||
242 | <p>{{ 'config.form_user.delete.description'|trans }}</p> | ||
243 | <a href="{{ path('delete_account') }}" onclick="return confirm('{{ 'config.form_user.delete.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red delete-account"> | ||
244 | {{ 'config.form_user.delete.button'|trans }} | ||
245 | </a> | ||
246 | </div> | ||
247 | {% endif %} | ||
200 | </div> | 248 | </div> |
201 | 249 | ||
202 | <div id="set4" class="col s12"> | 250 | <div id="set4" class="col s12"> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_actions.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_actions.html.twig index 56442116..d278da1b 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_actions.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_actions.html.twig | |||
@@ -1,8 +1,6 @@ | |||
1 | <div class="card-action"> | 1 | <div class="card-action"> |
2 | <span class="reading-time grey-text"> | 2 | <span class="reading-time grey-text"> |
3 | <i class="material-icons" title="{{ 'entry.list.reading_time'|trans }}">timer</i> | 3 | {% include "@WallabagCore/themes/material/Entry/_reading_time.html.twig" with {'entry': entry} only %} |
4 | {{ entry.readingTime / app.user.config.readingSpeed|round }} min | ||
5 | |||
6 | <i class="material-icons hide-on-med-and-down" title="{{ 'entry.view.created_at'|trans }}">today</i> | 4 | <i class="material-icons hide-on-med-and-down" title="{{ 'entry.view.created_at'|trans }}">today</i> |
7 | <span class="hide-on-med-and-down"> {{ entry.createdAt|date('Y-m-d') }}</span> | 5 | <span class="hide-on-med-and-down"> {{ entry.createdAt|date('Y-m-d') }}</span> |
8 | </span> | 6 | </span> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_list.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_list.html.twig new file mode 100644 index 00000000..bb9b64ce --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_card_list.html.twig | |||
@@ -0,0 +1,18 @@ | |||
1 | <div class="card"> | ||
2 | <div class="card-stacked"> | ||
3 | <div class="card-content"> | ||
4 | <span class="card-title dot-ellipsis dot-resize-update"> | ||
5 | <a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title | raw | striptags }}"> | ||
6 | {{ entry.title| striptags | truncate(120, true, '…') | raw }} | ||
7 | </a> | ||
8 | </span> | ||
9 | <ul class="tools-list right"> | ||
10 | <li> | ||
11 | <a title="{{ 'entry.list.toogle_as_read'|trans }}" class="tool grey-text" href="{{ path('archive_entry', { 'id': entry.id }) }}"><i class="material-icons">{% if entry.isArchived == 0 %}done{% else %}redo{% endif %}</i></a> | ||
12 | <a title="{{ 'entry.list.toogle_as_star'|trans }}" class="tool grey-text" href="{{ path('star_entry', { 'id': entry.id }) }}"><i class="material-icons">{% if entry.isStarred == 0 %}star_border{% else %}star{% endif %}</i></a> | ||
13 | <a title="{{ 'entry.list.delete'|trans }}" class="tool grey-text delete" href="{{ path('delete_entry', { 'id': entry.id }) }}"><i class="material-icons">delete</i></a> | ||
14 | </li> | ||
15 | </ul> | ||
16 | </div> | ||
17 | </div> | ||
18 | </div> | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_reading_time.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_reading_time.html.twig new file mode 100644 index 00000000..1a932a9f --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/_reading_time.html.twig | |||
@@ -0,0 +1,7 @@ | |||
1 | {% set readingTime = entry.readingTime / app.user.config.readingSpeed %} | ||
2 | <i class="material-icons">timer</i> | ||
3 | {% if readingTime > 0 %} | ||
4 | {{ 'entry.list.reading_time_minutes_short'|trans({'%readingTime%': readingTime|round}) }} | ||
5 | {% else %} | ||
6 | {{ 'entry.list.reading_time_less_one_minute_short'|trans|raw }} | ||
7 | {% endif %} | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig index c610c8d2..5fca53ae 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig | |||
@@ -1,17 +1,22 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | 1 | {% extends "WallabagCoreBundle::layout.html.twig" %} |
2 | 2 | ||
3 | {% block title %} | 3 | {% block title %} |
4 | {% set currentTag = '' %} | 4 | {% set filter = '' %} |
5 | {% if tag is defined %} | 5 | {% if tag is defined %} |
6 | {% set currentTag = tag %} | 6 | {% set filter = tag %} |
7 | {% endif %} | ||
8 | {% if searchTerm is defined and searchTerm is not empty %} | ||
9 | {% set filter = searchTerm %} | ||
7 | {% endif %} | 10 | {% endif %} |
8 | {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'currentTag': currentTag} %} | 11 | {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'filter': filter} %} |
9 | {% endblock %} | 12 | {% endblock %} |
10 | 13 | ||
11 | {% block content %} | 14 | {% block content %} |
15 | {% set listMode = app.user.config.listMode %} | ||
12 | <div class="results clearfix"> | 16 | <div class="results clearfix"> |
13 | <div class="nb-results left"> | 17 | <div class="nb-results left"> |
14 | {{ 'entry.list.number_on_the_page'|transchoice(entries.count) }} | 18 | {{ 'entry.list.number_on_the_page'|transchoice(entries.count) }} |
19 | <a href="{{ path('switch_view_mode') }}"><i class="material-icons">{% if listMode == 0 %}view_list{% else %}view_module{% endif %}</i></a> | ||
15 | </div> | 20 | </div> |
16 | {% if entries.getNbPages > 1 %} | 21 | {% if entries.getNbPages > 1 %} |
17 | {{ pagerfanta(entries, 'twitter_bootstrap_translated', {'proximity': 1}) }} | 22 | {{ pagerfanta(entries, 'twitter_bootstrap_translated', {'proximity': 1}) }} |
@@ -21,8 +26,10 @@ | |||
21 | <br /> | 26 | <br /> |
22 | <ul class="row data"> | 27 | <ul class="row data"> |
23 | {% for entry in entries %} | 28 | {% for entry in entries %} |
24 | <li id="entry-{{ entry.id|e }}" class="col l3 m6 s12"> | 29 | <li id="entry-{{ entry.id|e }}" class="col {% if listMode == 0 %}l3 m6{% endif %} s12"> |
25 | {% if entry.previewPicture is null %} | 30 | {% if listMode == 1 %} |
31 | {% include "@WallabagCore/themes/material/Entry/_card_list.html.twig" with {'entry': entry} only %} | ||
32 | {% elseif entry.previewPicture is null %} | ||
26 | {% include "@WallabagCore/themes/material/Entry/_card_no_preview.html.twig" with {'entry': entry} only %} | 33 | {% include "@WallabagCore/themes/material/Entry/_card_no_preview.html.twig" with {'entry': entry} only %} |
27 | {% elseif not entry.previewPicture is null and entry.mimetype starts with 'image/' %} | 34 | {% elseif not entry.previewPicture is null and entry.mimetype starts with 'image/' %} |
28 | {% include "@WallabagCore/themes/material/Entry/_card_full_image.html.twig" with {'entry': entry} only %} | 35 | {% include "@WallabagCore/themes/material/Entry/_card_full_image.html.twig" with {'entry': entry} only %} |
@@ -104,6 +111,14 @@ | |||
104 | </div> | 111 | </div> |
105 | 112 | ||
106 | <div class="col s12"> | 113 | <div class="col s12"> |
114 | {{ form_label(form.httpStatus) }} | ||
115 | </div> | ||
116 | |||
117 | <div class="input-field col s12"> | ||
118 | {{ form_widget(form.httpStatus) }} | ||
119 | </div> | ||
120 | |||
121 | <div class="col s12"> | ||
107 | {{ form_label(form.readingTime) }} | 122 | {{ form_label(form.readingTime) }} |
108 | </div> | 123 | </div> |
109 | <div class="input-field col s6"> | 124 | <div class="input-field col s6"> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig index 5635a01c..a99bc4ea 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entry.html.twig | |||
@@ -46,14 +46,14 @@ | |||
46 | </li> | 46 | </li> |
47 | 47 | ||
48 | <li class="bold border-bottom hide-on-med-and-down"> | 48 | <li class="bold border-bottom hide-on-med-and-down"> |
49 | <a class="waves-effect collapsible-header" href="{{ entry.url|e }}"> | 49 | <a class="waves-effect collapsible-header original" href="{{ entry.url|e }}" target="_blank"> |
50 | <i class="material-icons small">link</i> | 50 | <i class="material-icons small">link</i> |
51 | <span>{{ 'entry.view.left_menu.view_original_article'|trans }}</span> | 51 | <span>{{ 'entry.view.left_menu.view_original_article'|trans }}</span> |
52 | </a> | 52 | </a> |
53 | <div class="collapsible-body"></div> | 53 | <div class="collapsible-body"></div> |
54 | </li> | 54 | </li> |
55 | 55 | ||
56 | <li class="bold hide-on-med-and-down"> | 56 | <li class="bold"> |
57 | <a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}" href="{{ path('reload_entry', { 'id': entry.id }) }}" id="reload"> | 57 | <a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.re_fetch_content'|trans }}" href="{{ path('reload_entry', { 'id': entry.id }) }}" id="reload"> |
58 | <i class="material-icons small">autorenew</i> | 58 | <i class="material-icons small">autorenew</i> |
59 | <span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span> | 59 | <span>{{ 'entry.view.left_menu.re_fetch_content'|trans }}</span> |
@@ -67,7 +67,7 @@ | |||
67 | {% endif %} | 67 | {% endif %} |
68 | 68 | ||
69 | <li class="bold hide-on-med-and-down"> | 69 | <li class="bold hide-on-med-and-down"> |
70 | <a class="waves-effect collapsible-header" title="{{ markAsReadLabel|trans }}" href="{{ path('archive_entry', { 'id': entry.id }) }}" id="markAsRead"> | 70 | <a class="waves-effect collapsible-header markasread" title="{{ markAsReadLabel|trans }}" href="{{ path('archive_entry', { 'id': entry.id }) }}" id="markAsRead"> |
71 | <i class="material-icons small">{% if entry.isArchived == 0 %}done{% else %}redo{% endif %}</i> | 71 | <i class="material-icons small">{% if entry.isArchived == 0 %}done{% else %}redo{% endif %}</i> |
72 | <span>{{ markAsReadLabel|trans }}</span> | 72 | <span>{{ markAsReadLabel|trans }}</span> |
73 | </a> | 73 | </a> |
@@ -75,21 +75,21 @@ | |||
75 | </li> | 75 | </li> |
76 | 76 | ||
77 | <li class="bold hide-on-med-and-down"> | 77 | <li class="bold hide-on-med-and-down"> |
78 | <a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', { 'id': entry.id }) }}" id="setFav"> | 78 | <a class="waves-effect collapsible-header favorite" title="{{ 'entry.view.left_menu.set_as_starred'|trans }}" href="{{ path('star_entry', { 'id': entry.id }) }}" id="setFav"> |
79 | <i class="material-icons spall">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> | 79 | <i class="material-icons spall">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i> |
80 | <span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span> | 80 | <span>{{ 'entry.view.left_menu.set_as_starred'|trans }}</span> |
81 | </a> | 81 | </a> |
82 | <div class="collapsible-body"></div> | 82 | <div class="collapsible-body"></div> |
83 | </li> | 83 | </li> |
84 | <li class="bold border-bottom hide-on-med-and-down"> | 84 | <li class="bold border-bottom"> |
85 | <a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.delete'|trans }}" href="{{ path('delete_entry', { 'id': entry.id }) }}"> | 85 | <a class="waves-effect collapsible-header delete" title="{{ 'entry.view.left_menu.delete'|trans }}" href="{{ path('delete_entry', { 'id': entry.id }) }}"> |
86 | <i class="material-icons small">delete</i> | 86 | <i class="material-icons small">delete</i> |
87 | <span>{{ 'entry.view.left_menu.delete'|trans }}</span> | 87 | <span>{{ 'entry.view.left_menu.delete'|trans }}</span> |
88 | </a> | 88 | </a> |
89 | <div class="collapsible-body"></div> | 89 | <div class="collapsible-body"></div> |
90 | </li> | 90 | </li> |
91 | 91 | ||
92 | <li class="bold border-bottom hide-on-med-and-down"> | 92 | <li class="bold border-bottom"> |
93 | <a class="waves-effect collapsible-header" id="nav-btn-add-tag"> | 93 | <a class="waves-effect collapsible-header" id="nav-btn-add-tag"> |
94 | <i class="material-icons small">label_outline</i> | 94 | <i class="material-icons small">label_outline</i> |
95 | <span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span> | 95 | <span>{{ 'entry.view.left_menu.add_a_tag'|trans }}</span> |
@@ -139,6 +139,14 @@ | |||
139 | </a> | 139 | </a> |
140 | </li> | 140 | </li> |
141 | {% endif %} | 141 | {% endif %} |
142 | {% if craue_setting('share_unmark') %} | ||
143 | <li> | ||
144 | <a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&title={{entry.title|url_encode}}&v=6" target="_blank"> | ||
145 | <i class="tool icon-image icon-image--unmark" title="unmark"></i> | ||
146 | <span>unmark.it</span> | ||
147 | </a> | ||
148 | </li> | ||
149 | {% endif %} | ||
142 | {% if craue_setting('carrot') %} | 150 | {% if craue_setting('carrot') %} |
143 | <li> | 151 | <li> |
144 | <a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" target="_blank" title="carrot"> | 152 | <a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" target="_blank" title="carrot"> |
@@ -186,14 +194,6 @@ | |||
186 | </div> | 194 | </div> |
187 | </li> | 195 | </li> |
188 | 196 | ||
189 | <li class="bold hide-on-large-only"> | ||
190 | <a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.delete'|trans }}" href="{{ path('delete_entry', { 'id': entry.id }) }}"> | ||
191 | <i class="material-icons small">delete</i> | ||
192 | <span>{{ 'entry.view.left_menu.delete'|trans }}</span> | ||
193 | </a> | ||
194 | <div class="collapsible-body"></div> | ||
195 | </li> | ||
196 | |||
197 | <li class="bold"> | 197 | <li class="bold"> |
198 | <a class="waves-effect collapsible-header" href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&body={{ entry.url|url_encode }}" title="{{ 'entry.view.left_menu.problem.description'|trans }}"> | 198 | <a class="waves-effect collapsible-header" href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&body={{ entry.url|url_encode }}" title="{{ 'entry.view.left_menu.problem.description'|trans }}"> |
199 | <i class="material-icons small">error</i> | 199 | <i class="material-icons small">error</i> |
@@ -214,13 +214,7 @@ | |||
214 | <aside> | 214 | <aside> |
215 | <ul class="tools"> | 215 | <ul class="tools"> |
216 | <li> | 216 | <li> |
217 | {% set readingTime = entry.readingTime / app.user.config.readingSpeed %} | 217 | {% include "@WallabagCore/themes/material/Entry/_reading_time.html.twig" with {'entry': entry} only %} |
218 | <i class="material-icons">timer</i> | ||
219 | {% if readingTime > 0 %} | ||
220 | {{ 'entry.list.reading_time_minutes_short'|trans({'%readingTime%': readingTime|round}) }} | ||
221 | {% else %} | ||
222 | {{ 'entry.list.reading_time_less_one_minute_short'|trans|raw }} | ||
223 | {% endif %} | ||
224 | </li> | 218 | </li> |
225 | <li> | 219 | <li> |
226 | <i class="material-icons" title="{{ 'entry.view.created_at'|trans }}">today</i> | 220 | <i class="material-icons" title="{{ 'entry.view.created_at'|trans }}">today</i> |
@@ -257,6 +251,17 @@ | |||
257 | <article> | 251 | <article> |
258 | {{ entry.content | raw }} | 252 | {{ entry.content | raw }} |
259 | </article> | 253 | </article> |
254 | |||
255 | <div class="fixed-action-btn horizontal click-to-toggle hide-on-large-only"> | ||
256 | <a class="btn-floating btn-large"> | ||
257 | <i class="material-icons">menu</i> | ||
258 | </a> | ||
259 | <ul> | ||
260 | <li><a class="btn-floating" href="{{ path('archive_entry', { 'id': entry.id }) }}"><i class="material-icons">done</i></a></li> | ||
261 | <li><a class="btn-floating" href="{{ path('star_entry', { 'id': entry.id }) }}"><i class="material-icons">star_outline</i></a></li> | ||
262 | <li><a class="btn-floating" href="{{ path('delete_entry', { 'id': entry.id }) }}"><i class="material-icons">delete</i></a></li> | ||
263 | </ul> | ||
264 | </div> | ||
260 | </div> | 265 | </div> |
261 | 266 | ||
262 | <script id="annotationroutes" type="application/json"> | 267 | <script id="annotationroutes" type="application/json"> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig new file mode 100644 index 00000000..f25de94d --- /dev/null +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/search_form.html.twig | |||
@@ -0,0 +1,15 @@ | |||
1 | <form name="search" method="GET" action="{{ path('search')}}"> | ||
2 | {% if form_errors(form) %} | ||
3 | <span class="black-text">{{ form_errors(form) }}</span> | ||
4 | {% endif %} | ||
5 | |||
6 | {% if form_errors(form.term) %} | ||
7 | <span class="black-text">{{ form_errors(form.term) }}</span> | ||
8 | {% endif %} | ||
9 | |||
10 | <input type="hidden" name="currentRoute" value="{{ currentRoute }}" /> | ||
11 | |||
12 | {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'entry.search.placeholder'} }) }} | ||
13 | |||
14 | {{ form_rest(form) }} | ||
15 | </form> | ||
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig index 6e552560..b702c4b6 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/new_form.html.twig | |||
@@ -9,5 +9,6 @@ | |||
9 | 9 | ||
10 | {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }} | 10 | {{ form_widget(form.label, { 'attr': {'autocomplete': 'off'} }) }} |
11 | 11 | ||
12 | {{ form_rest(form) }} | 12 | {{ form_widget(form.add, {'attr': {'class': 'btn waves-effect waves-light hide-on-large-only'}}) }} |
13 | {{ form_widget(form._token) }} | ||
13 | </form> | 14 | </form> |
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig index f1ef01df..e0d36738 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig | |||
@@ -19,8 +19,6 @@ | |||
19 | Materialize.toast('{{ flashMessage|trans }}', 4000); | 19 | Materialize.toast('{{ flashMessage|trans }}', 4000); |
20 | </script> | 20 | </script> |
21 | {% endfor %} | 21 | {% endfor %} |
22 | |||
23 | {{ render(controller("WallabagImportBundle:Import:checkQueue")) }} | ||
24 | {% endblock %} | 22 | {% endblock %} |
25 | 23 | ||
26 | {% block menu %} | 24 | {% block menu %} |
@@ -82,37 +80,33 @@ | |||
82 | {% block title %} | 80 | {% block title %} |
83 | {% endblock %} | 81 | {% endblock %} |
84 | </div> | 82 | </div> |
85 | <div class="input-field nav-panel-buttom"> | 83 | <ul class="input-field nav-panel-buttom"> |
86 | <ul> | 84 | <li class="bold"> |
87 | <li class="bold"> | 85 | <a class="waves-effect tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.add_new_entry'|trans }}" href="{{ path('new') }}" id="nav-btn-add"> |
88 | <a class="waves-effect tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.add_new_entry'|trans }}" href="{{ path('new') }}" id="nav-btn-add"> | 86 | <i class="material-icons">add</i> |
89 | <i class="material-icons">add</i> | 87 | </a> |
90 | </a> | 88 | </li> |
91 | </li> | 89 | <li> |
92 | <!--<li> | 90 | <a class="waves-effect tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.search'|trans }}" href="javascript: void(null);" id="nav-btn-search"> |
93 | <a title="{{ 'menu.top.search'|trans }}" class="waves-effect" href="javascript: void(null);" id="nav-btn-search"> | 91 | <i class="material-icons">search</i> |
94 | <i class="material-icons">search</i> | 92 | </a> |
95 | </a> | 93 | </li> |
96 | </li>--> | 94 | <li id="button_filters"> |
97 | <li id="button_filters"> | 95 | <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.filter_entries'|trans }}" href="#" data-activates="filters"> |
98 | <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.filter_entries'|trans }}" href="#" data-activates="filters"> | 96 | <i class="material-icons">filter_list</i> |
99 | <i class="material-icons">filter_list</i> | 97 | </a> |
100 | </a> | 98 | </li> |
101 | </li> | 99 | <li id="button_export"> |
102 | <li id="button_export"> | 100 | <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.export'|trans }}" href="#" data-activates="export"> |
103 | <a class="nav-panel-menu button-collapse-right tooltipped" data-position="bottom" data-delay="50" data-tooltip="{{ 'menu.top.export'|trans }}" href="#" data-activates="export"> | 101 | <i class="material-icons">file_download</i> |
104 | <i class="material-icons">file_download</i> | 102 | </a> |
105 | </a> | 103 | </li> |
106 | </li> | 104 | </ul> |
107 | </ul> | 105 | <div class="input-field nav-panel-search" style="display: none"> |
106 | {{ render(controller("WallabagCoreBundle:Entry:searchForm", {'currentRoute': app.request.attributes.get('_route')})) }} | ||
107 | <label for="search" class="active"><i class="material-icons search">search</i></label> | ||
108 | <i class="material-icons close">clear</i> | ||
108 | </div> | 109 | </div> |
109 | <form method="get" action="index.php"> | ||
110 | <div class="input-field nav-panel-search" style="display: none"> | ||
111 | <input name="search" id="searchfield" type="search" required placeholder="{{ 'menu.search_form.input_label'|trans }}"> | ||
112 | <label for="search"><i class="material-icons search">search</i></label> | ||
113 | <i class="material-icons close">clear</i> | ||
114 | </div> | ||
115 | </form> | ||
116 | <div class="input-field nav-panel-add" style="display: none"> | 110 | <div class="input-field nav-panel-add" style="display: none"> |
117 | {{ render(controller("WallabagCoreBundle:Entry:addEntryForm")) }} | 111 | {{ render(controller("WallabagCoreBundle:Entry:addEntryForm")) }} |
118 | <label for="add" class="active"><i class="material-icons add">add</i></label> | 112 | <label for="add" class="active"><i class="material-icons add">add</i></label> |
diff --git a/src/Wallabag/CoreBundle/Tools/Utils.php b/src/Wallabag/CoreBundle/Tools/Utils.php index 4561f39f..eba21c02 100644 --- a/src/Wallabag/CoreBundle/Tools/Utils.php +++ b/src/Wallabag/CoreBundle/Tools/Utils.php | |||
@@ -29,6 +29,6 @@ class Utils | |||
29 | */ | 29 | */ |
30 | public static function getReadingTime($text) | 30 | public static function getReadingTime($text) |
31 | { | 31 | { |
32 | return floor(str_word_count(strip_tags($text)) / 200); | 32 | return floor(count(preg_split('~[^\p{L}\p{N}\']+~u', strip_tags($text))) / 200); |
33 | } | 33 | } |
34 | } | 34 | } |
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php index d1325338..28d01715 100644 --- a/src/Wallabag/ImportBundle/Command/ImportCommand.php +++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php | |||
@@ -14,10 +14,10 @@ class ImportCommand extends ContainerAwareCommand | |||
14 | { | 14 | { |
15 | $this | 15 | $this |
16 | ->setName('wallabag:import') | 16 | ->setName('wallabag:import') |
17 | ->setDescription('Import entries from a JSON export from a wallabag v1 instance') | 17 | ->setDescription('Import entries from a JSON export') |
18 | ->addArgument('userId', InputArgument::REQUIRED, 'User ID to populate') | 18 | ->addArgument('userId', InputArgument::REQUIRED, 'User ID to populate') |
19 | ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file') | 19 | ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file') |
20 | ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: wallabag v1, v2, firefox or chrome', 'v1') | 20 | ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, readability, firefox or chrome', 'v1') |
21 | ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false) | 21 | ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false) |
22 | ; | 22 | ; |
23 | } | 23 | } |
@@ -42,32 +42,36 @@ class ImportCommand extends ContainerAwareCommand | |||
42 | 42 | ||
43 | switch ($input->getOption('importer')) { | 43 | switch ($input->getOption('importer')) { |
44 | case 'v2': | 44 | case 'v2': |
45 | $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v2.import'); | 45 | $import = $this->getContainer()->get('wallabag_import.wallabag_v2.import'); |
46 | break; | 46 | break; |
47 | case 'firefox': | 47 | case 'firefox': |
48 | $wallabag = $this->getContainer()->get('wallabag_import.firefox.import'); | 48 | $import = $this->getContainer()->get('wallabag_import.firefox.import'); |
49 | break; | 49 | break; |
50 | case 'chrome': | 50 | case 'chrome': |
51 | $wallabag = $this->getContainer()->get('wallabag_import.chrome.import'); | 51 | $import = $this->getContainer()->get('wallabag_import.chrome.import'); |
52 | break; | ||
53 | case 'readability': | ||
54 | $import = $this->getContainer()->get('wallabag_import.readability.import'); | ||
52 | break; | 55 | break; |
53 | case 'instapaper': | 56 | case 'instapaper': |
54 | $wallabag = $this->getContainer()->get('wallabag_import.instapaper.import'); | 57 | $import = $this->getContainer()->get('wallabag_import.instapaper.import'); |
55 | break; | 58 | break; |
56 | case 'v1': | 59 | case 'pinboard': |
57 | default: | 60 | $import = $this->getContainer()->get('wallabag_import.pinboard.import'); |
58 | $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); | ||
59 | break; | 61 | break; |
62 | default: | ||
63 | $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); | ||
60 | } | 64 | } |
61 | 65 | ||
62 | $wallabag->setMarkAsRead($input->getOption('markAsRead')); | 66 | $import->setMarkAsRead($input->getOption('markAsRead')); |
63 | $wallabag->setUser($user); | 67 | $import->setUser($user); |
64 | 68 | ||
65 | $res = $wallabag | 69 | $res = $import |
66 | ->setFilepath($input->getArgument('filepath')) | 70 | ->setFilepath($input->getArgument('filepath')) |
67 | ->import(); | 71 | ->import(); |
68 | 72 | ||
69 | if (true === $res) { | 73 | if (true === $res) { |
70 | $summary = $wallabag->getSummary(); | 74 | $summary = $import->getSummary(); |
71 | $output->writeln('<info>'.$summary['imported'].' imported</info>'); | 75 | $output->writeln('<info>'.$summary['imported'].' imported</info>'); |
72 | $output->writeln('<comment>'.$summary['skipped'].' already saved</comment>'); | 76 | $output->writeln('<comment>'.$summary['skipped'].' already saved</comment>'); |
73 | } | 77 | } |
diff --git a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php index c2c11f11..2d06af44 100644 --- a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php +++ b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php | |||
@@ -17,7 +17,7 @@ class RedisWorkerCommand extends ContainerAwareCommand | |||
17 | $this | 17 | $this |
18 | ->setName('wallabag:import:redis-worker') | 18 | ->setName('wallabag:import:redis-worker') |
19 | ->setDescription('Launch Redis worker') | 19 | ->setDescription('Launch Redis worker') |
20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket, readability, firefox, chrome or instapaper') | 20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket, readability, pinboard, firefox, chrome or instapaper') |
21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) | 21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) |
22 | ; | 22 | ; |
23 | } | 23 | } |
@@ -36,7 +36,7 @@ class RedisWorkerCommand extends ContainerAwareCommand | |||
36 | $worker = new QueueWorker( | 36 | $worker = new QueueWorker( |
37 | $this->getContainer()->get('wallabag_import.queue.redis.'.$serviceName), | 37 | $this->getContainer()->get('wallabag_import.queue.redis.'.$serviceName), |
38 | $this->getContainer()->get('wallabag_import.consumer.redis.'.$serviceName), | 38 | $this->getContainer()->get('wallabag_import.consumer.redis.'.$serviceName), |
39 | $input->getOption('maxIterations') | 39 | (int) $input->getOption('maxIterations') |
40 | ); | 40 | ); |
41 | 41 | ||
42 | $worker->start(); | 42 | $worker->start(); |
diff --git a/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php b/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php index b893ea29..fc175f67 100644 --- a/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php +++ b/src/Wallabag/ImportBundle/Consumer/AbstractConsumer.php | |||
@@ -9,19 +9,23 @@ use Wallabag\CoreBundle\Entity\Entry; | |||
9 | use Wallabag\CoreBundle\Entity\Tag; | 9 | use Wallabag\CoreBundle\Entity\Tag; |
10 | use Psr\Log\LoggerInterface; | 10 | use Psr\Log\LoggerInterface; |
11 | use Psr\Log\NullLogger; | 11 | use Psr\Log\NullLogger; |
12 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||
13 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
12 | 14 | ||
13 | abstract class AbstractConsumer | 15 | abstract class AbstractConsumer |
14 | { | 16 | { |
15 | protected $em; | 17 | protected $em; |
16 | protected $userRepository; | 18 | protected $userRepository; |
17 | protected $import; | 19 | protected $import; |
20 | protected $eventDispatcher; | ||
18 | protected $logger; | 21 | protected $logger; |
19 | 22 | ||
20 | public function __construct(EntityManager $em, UserRepository $userRepository, AbstractImport $import, LoggerInterface $logger = null) | 23 | public function __construct(EntityManager $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger = null) |
21 | { | 24 | { |
22 | $this->em = $em; | 25 | $this->em = $em; |
23 | $this->userRepository = $userRepository; | 26 | $this->userRepository = $userRepository; |
24 | $this->import = $import; | 27 | $this->import = $import; |
28 | $this->eventDispatcher = $eventDispatcher; | ||
25 | $this->logger = $logger ?: new NullLogger(); | 29 | $this->logger = $logger ?: new NullLogger(); |
26 | } | 30 | } |
27 | 31 | ||
@@ -59,6 +63,9 @@ abstract class AbstractConsumer | |||
59 | try { | 63 | try { |
60 | $this->em->flush(); | 64 | $this->em->flush(); |
61 | 65 | ||
66 | // entry saved, dispatch event about it! | ||
67 | $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
68 | |||
62 | // clear only affected entities | 69 | // clear only affected entities |
63 | $this->em->clear(Entry::class); | 70 | $this->em->clear(Entry::class); |
64 | $this->em->clear(Tag::class); | 71 | $this->em->clear(Tag::class); |
diff --git a/src/Wallabag/ImportBundle/Controller/BrowserController.php b/src/Wallabag/ImportBundle/Controller/BrowserController.php index 144a4880..e119098f 100644 --- a/src/Wallabag/ImportBundle/Controller/BrowserController.php +++ b/src/Wallabag/ImportBundle/Controller/BrowserController.php | |||
@@ -39,7 +39,7 @@ abstract class BrowserController extends Controller | |||
39 | $wallabag = $this->getImportService(); | 39 | $wallabag = $this->getImportService(); |
40 | $wallabag->setUser($this->getUser()); | 40 | $wallabag->setUser($this->getUser()); |
41 | 41 | ||
42 | if ($form->isValid()) { | 42 | if ($form->isSubmitted() && $form->isValid()) { |
43 | $file = $form->get('file')->getData(); | 43 | $file = $form->get('file')->getData(); |
44 | $markAsRead = $form->get('mark_as_read')->getData(); | 44 | $markAsRead = $form->get('mark_as_read')->getData(); |
45 | $name = $this->getUser()->getId().'.json'; | 45 | $name = $this->getUser()->getId().'.json'; |
diff --git a/src/Wallabag/ImportBundle/Controller/ImportController.php b/src/Wallabag/ImportBundle/Controller/ImportController.php index 15de75ff..237c748e 100644 --- a/src/Wallabag/ImportBundle/Controller/ImportController.php +++ b/src/Wallabag/ImportBundle/Controller/ImportController.php | |||
@@ -42,6 +42,7 @@ class ImportController extends Controller | |||
42 | + $this->getTotalMessageInRabbitQueue('firefox') | 42 | + $this->getTotalMessageInRabbitQueue('firefox') |
43 | + $this->getTotalMessageInRabbitQueue('chrome') | 43 | + $this->getTotalMessageInRabbitQueue('chrome') |
44 | + $this->getTotalMessageInRabbitQueue('instapaper') | 44 | + $this->getTotalMessageInRabbitQueue('instapaper') |
45 | + $this->getTotalMessageInRabbitQueue('pinboard') | ||
45 | ; | 46 | ; |
46 | } catch (\Exception $e) { | 47 | } catch (\Exception $e) { |
47 | $rabbitNotInstalled = true; | 48 | $rabbitNotInstalled = true; |
@@ -57,6 +58,7 @@ class ImportController extends Controller | |||
57 | + $redis->llen('wallabag.import.firefox') | 58 | + $redis->llen('wallabag.import.firefox') |
58 | + $redis->llen('wallabag.import.chrome') | 59 | + $redis->llen('wallabag.import.chrome') |
59 | + $redis->llen('wallabag.import.instapaper') | 60 | + $redis->llen('wallabag.import.instapaper') |
61 | + $redis->llen('wallabag.import.pinboard') | ||
60 | ; | 62 | ; |
61 | } catch (\Exception $e) { | 63 | } catch (\Exception $e) { |
62 | $redisNotInstalled = true; | 64 | $redisNotInstalled = true; |
diff --git a/src/Wallabag/ImportBundle/Controller/InstapaperController.php b/src/Wallabag/ImportBundle/Controller/InstapaperController.php index c3fc8a39..0251acb9 100644 --- a/src/Wallabag/ImportBundle/Controller/InstapaperController.php +++ b/src/Wallabag/ImportBundle/Controller/InstapaperController.php | |||
@@ -26,7 +26,7 @@ class InstapaperController extends Controller | |||
26 | $instapaper->setProducer($this->get('wallabag_import.producer.redis.instapaper')); | 26 | $instapaper->setProducer($this->get('wallabag_import.producer.redis.instapaper')); |
27 | } | 27 | } |
28 | 28 | ||
29 | if ($form->isValid()) { | 29 | if ($form->isSubmitted() && $form->isValid()) { |
30 | $file = $form->get('file')->getData(); | 30 | $file = $form->get('file')->getData(); |
31 | $markAsRead = $form->get('mark_as_read')->getData(); | 31 | $markAsRead = $form->get('mark_as_read')->getData(); |
32 | $name = 'instapaper_'.$this->getUser()->getId().'.csv'; | 32 | $name = 'instapaper_'.$this->getUser()->getId().'.csv'; |
diff --git a/src/Wallabag/ImportBundle/Controller/PinboardController.php b/src/Wallabag/ImportBundle/Controller/PinboardController.php new file mode 100644 index 00000000..d0ad8aa8 --- /dev/null +++ b/src/Wallabag/ImportBundle/Controller/PinboardController.php | |||
@@ -0,0 +1,77 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Controller; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Wallabag\ImportBundle\Form\Type\UploadImportType; | ||
9 | |||
10 | class PinboardController extends Controller | ||
11 | { | ||
12 | /** | ||
13 | * @Route("/pinboard", name="import_pinboard") | ||
14 | */ | ||
15 | public function indexAction(Request $request) | ||
16 | { | ||
17 | $form = $this->createForm(UploadImportType::class); | ||
18 | $form->handleRequest($request); | ||
19 | |||
20 | $pinboard = $this->get('wallabag_import.pinboard.import'); | ||
21 | $pinboard->setUser($this->getUser()); | ||
22 | |||
23 | if ($this->get('craue_config')->get('import_with_rabbitmq')) { | ||
24 | $pinboard->setProducer($this->get('old_sound_rabbit_mq.import_pinboard_producer')); | ||
25 | } elseif ($this->get('craue_config')->get('import_with_redis')) { | ||
26 | $pinboard->setProducer($this->get('wallabag_import.producer.redis.pinboard')); | ||
27 | } | ||
28 | |||
29 | if ($form->isSubmitted() && $form->isValid()) { | ||
30 | $file = $form->get('file')->getData(); | ||
31 | $markAsRead = $form->get('mark_as_read')->getData(); | ||
32 | $name = 'pinboard_'.$this->getUser()->getId().'.json'; | ||
33 | |||
34 | if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) { | ||
35 | $res = $pinboard | ||
36 | ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name) | ||
37 | ->setMarkAsRead($markAsRead) | ||
38 | ->import(); | ||
39 | |||
40 | $message = 'flashes.import.notice.failed'; | ||
41 | |||
42 | if (true === $res) { | ||
43 | $summary = $pinboard->getSummary(); | ||
44 | $message = $this->get('translator')->trans('flashes.import.notice.summary', [ | ||
45 | '%imported%' => $summary['imported'], | ||
46 | '%skipped%' => $summary['skipped'], | ||
47 | ]); | ||
48 | |||
49 | if (0 < $summary['queued']) { | ||
50 | $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ | ||
51 | '%queued%' => $summary['queued'], | ||
52 | ]); | ||
53 | } | ||
54 | |||
55 | unlink($this->getParameter('wallabag_import.resource_dir').'/'.$name); | ||
56 | } | ||
57 | |||
58 | $this->get('session')->getFlashBag()->add( | ||
59 | 'notice', | ||
60 | $message | ||
61 | ); | ||
62 | |||
63 | return $this->redirect($this->generateUrl('homepage')); | ||
64 | } else { | ||
65 | $this->get('session')->getFlashBag()->add( | ||
66 | 'notice', | ||
67 | 'flashes.import.notice.failed_on_file' | ||
68 | ); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | return $this->render('WallabagImportBundle:Pinboard:index.html.twig', [ | ||
73 | 'form' => $form->createView(), | ||
74 | 'import' => $pinboard, | ||
75 | ]); | ||
76 | } | ||
77 | } | ||
diff --git a/src/Wallabag/ImportBundle/Controller/ReadabilityController.php b/src/Wallabag/ImportBundle/Controller/ReadabilityController.php index d00e22c2..aa732ddd 100644 --- a/src/Wallabag/ImportBundle/Controller/ReadabilityController.php +++ b/src/Wallabag/ImportBundle/Controller/ReadabilityController.php | |||
@@ -26,7 +26,7 @@ class ReadabilityController extends Controller | |||
26 | $readability->setProducer($this->get('wallabag_import.producer.redis.readability')); | 26 | $readability->setProducer($this->get('wallabag_import.producer.redis.readability')); |
27 | } | 27 | } |
28 | 28 | ||
29 | if ($form->isValid()) { | 29 | if ($form->isSubmitted() && $form->isValid()) { |
30 | $file = $form->get('file')->getData(); | 30 | $file = $form->get('file')->getData(); |
31 | $markAsRead = $form->get('mark_as_read')->getData(); | 31 | $markAsRead = $form->get('mark_as_read')->getData(); |
32 | $name = 'readability_'.$this->getUser()->getId().'.json'; | 32 | $name = 'readability_'.$this->getUser()->getId().'.json'; |
diff --git a/src/Wallabag/ImportBundle/Controller/WallabagController.php b/src/Wallabag/ImportBundle/Controller/WallabagController.php index 9c0cde80..e81c1ca9 100644 --- a/src/Wallabag/ImportBundle/Controller/WallabagController.php +++ b/src/Wallabag/ImportBundle/Controller/WallabagController.php | |||
@@ -40,7 +40,7 @@ abstract class WallabagController extends Controller | |||
40 | $wallabag = $this->getImportService(); | 40 | $wallabag = $this->getImportService(); |
41 | $wallabag->setUser($this->getUser()); | 41 | $wallabag->setUser($this->getUser()); |
42 | 42 | ||
43 | if ($form->isValid()) { | 43 | if ($form->isSubmitted() && $form->isValid()) { |
44 | $file = $form->get('file')->getData(); | 44 | $file = $form->get('file')->getData(); |
45 | $markAsRead = $form->get('mark_as_read')->getData(); | 45 | $markAsRead = $form->get('mark_as_read')->getData(); |
46 | $name = $this->getUser()->getId().'.json'; | 46 | $name = $this->getUser()->getId().'.json'; |
diff --git a/src/Wallabag/ImportBundle/Import/AbstractImport.php b/src/Wallabag/ImportBundle/Import/AbstractImport.php index 764b390a..1d4a6e27 100644 --- a/src/Wallabag/ImportBundle/Import/AbstractImport.php +++ b/src/Wallabag/ImportBundle/Import/AbstractImport.php | |||
@@ -10,12 +10,15 @@ use Wallabag\CoreBundle\Entity\Entry; | |||
10 | use Wallabag\CoreBundle\Entity\Tag; | 10 | use Wallabag\CoreBundle\Entity\Tag; |
11 | use Wallabag\UserBundle\Entity\User; | 11 | use Wallabag\UserBundle\Entity\User; |
12 | use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface; | 12 | use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface; |
13 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||
14 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
13 | 15 | ||
14 | abstract class AbstractImport implements ImportInterface | 16 | abstract class AbstractImport implements ImportInterface |
15 | { | 17 | { |
16 | protected $em; | 18 | protected $em; |
17 | protected $logger; | 19 | protected $logger; |
18 | protected $contentProxy; | 20 | protected $contentProxy; |
21 | protected $eventDispatcher; | ||
19 | protected $producer; | 22 | protected $producer; |
20 | protected $user; | 23 | protected $user; |
21 | protected $markAsRead; | 24 | protected $markAsRead; |
@@ -23,11 +26,12 @@ abstract class AbstractImport implements ImportInterface | |||
23 | protected $importedEntries = 0; | 26 | protected $importedEntries = 0; |
24 | protected $queuedEntries = 0; | 27 | protected $queuedEntries = 0; |
25 | 28 | ||
26 | public function __construct(EntityManager $em, ContentProxy $contentProxy) | 29 | public function __construct(EntityManager $em, ContentProxy $contentProxy, EventDispatcherInterface $eventDispatcher) |
27 | { | 30 | { |
28 | $this->em = $em; | 31 | $this->em = $em; |
29 | $this->logger = new NullLogger(); | 32 | $this->logger = new NullLogger(); |
30 | $this->contentProxy = $contentProxy; | 33 | $this->contentProxy = $contentProxy; |
34 | $this->eventDispatcher = $eventDispatcher; | ||
31 | } | 35 | } |
32 | 36 | ||
33 | public function setLogger(LoggerInterface $logger) | 37 | public function setLogger(LoggerInterface $logger) |
@@ -104,6 +108,7 @@ abstract class AbstractImport implements ImportInterface | |||
104 | protected function parseEntries($entries) | 108 | protected function parseEntries($entries) |
105 | { | 109 | { |
106 | $i = 1; | 110 | $i = 1; |
111 | $entryToBeFlushed = []; | ||
107 | 112 | ||
108 | foreach ($entries as $importedEntry) { | 113 | foreach ($entries as $importedEntry) { |
109 | if ($this->markAsRead) { | 114 | if ($this->markAsRead) { |
@@ -116,10 +121,21 @@ abstract class AbstractImport implements ImportInterface | |||
116 | continue; | 121 | continue; |
117 | } | 122 | } |
118 | 123 | ||
124 | // store each entry to be flushed so we can trigger the entry.saved event for each of them | ||
125 | // entry.saved needs the entry to be persisted in db because it needs it id to generate | ||
126 | // images (at least) | ||
127 | $entryToBeFlushed[] = $entry; | ||
128 | |||
119 | // flush every 20 entries | 129 | // flush every 20 entries |
120 | if (($i % 20) === 0) { | 130 | if (($i % 20) === 0) { |
121 | $this->em->flush(); | 131 | $this->em->flush(); |
122 | 132 | ||
133 | foreach ($entryToBeFlushed as $entry) { | ||
134 | $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
135 | } | ||
136 | |||
137 | $entryToBeFlushed = []; | ||
138 | |||
123 | // clear only affected entities | 139 | // clear only affected entities |
124 | $this->em->clear(Entry::class); | 140 | $this->em->clear(Entry::class); |
125 | $this->em->clear(Tag::class); | 141 | $this->em->clear(Tag::class); |
@@ -128,6 +144,12 @@ abstract class AbstractImport implements ImportInterface | |||
128 | } | 144 | } |
129 | 145 | ||
130 | $this->em->flush(); | 146 | $this->em->flush(); |
147 | |||
148 | if (!empty($entryToBeFlushed)) { | ||
149 | foreach ($entryToBeFlushed as $entry) { | ||
150 | $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
151 | } | ||
152 | } | ||
131 | } | 153 | } |
132 | 154 | ||
133 | /** | 155 | /** |
diff --git a/src/Wallabag/ImportBundle/Import/BrowserImport.php b/src/Wallabag/ImportBundle/Import/BrowserImport.php index 2ca1683b..8bf7d92e 100644 --- a/src/Wallabag/ImportBundle/Import/BrowserImport.php +++ b/src/Wallabag/ImportBundle/Import/BrowserImport.php | |||
@@ -5,6 +5,7 @@ namespace Wallabag\ImportBundle\Import; | |||
5 | use Wallabag\CoreBundle\Entity\Entry; | 5 | use Wallabag\CoreBundle\Entity\Entry; |
6 | use Wallabag\UserBundle\Entity\User; | 6 | use Wallabag\UserBundle\Entity\User; |
7 | use Wallabag\CoreBundle\Helper\ContentProxy; | 7 | use Wallabag\CoreBundle\Helper\ContentProxy; |
8 | use Wallabag\CoreBundle\Event\EntrySavedEvent; | ||
8 | 9 | ||
9 | abstract class BrowserImport extends AbstractImport | 10 | abstract class BrowserImport extends AbstractImport |
10 | { | 11 | { |
@@ -81,6 +82,7 @@ abstract class BrowserImport extends AbstractImport | |||
81 | protected function parseEntries($entries) | 82 | protected function parseEntries($entries) |
82 | { | 83 | { |
83 | $i = 1; | 84 | $i = 1; |
85 | $entryToBeFlushed = []; | ||
84 | 86 | ||
85 | foreach ($entries as $importedEntry) { | 87 | foreach ($entries as $importedEntry) { |
86 | if ((array) $importedEntry !== $importedEntry) { | 88 | if ((array) $importedEntry !== $importedEntry) { |
@@ -93,14 +95,29 @@ abstract class BrowserImport extends AbstractImport | |||
93 | continue; | 95 | continue; |
94 | } | 96 | } |
95 | 97 | ||
98 | // @see AbstractImport | ||
99 | $entryToBeFlushed[] = $entry; | ||
100 | |||
96 | // flush every 20 entries | 101 | // flush every 20 entries |
97 | if (($i % 20) === 0) { | 102 | if (($i % 20) === 0) { |
98 | $this->em->flush(); | 103 | $this->em->flush(); |
104 | |||
105 | foreach ($entryToBeFlushed as $entry) { | ||
106 | $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
107 | } | ||
108 | |||
109 | $entryToBeFlushed = []; | ||
99 | } | 110 | } |
100 | ++$i; | 111 | ++$i; |
101 | } | 112 | } |
102 | 113 | ||
103 | $this->em->flush(); | 114 | $this->em->flush(); |
115 | |||
116 | if (!empty($entryToBeFlushed)) { | ||
117 | foreach ($entryToBeFlushed as $entry) { | ||
118 | $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry)); | ||
119 | } | ||
120 | } | ||
104 | } | 121 | } |
105 | 122 | ||
106 | /** | 123 | /** |
diff --git a/src/Wallabag/ImportBundle/Import/ChromeImport.php b/src/Wallabag/ImportBundle/Import/ChromeImport.php index d7620bcb..2667890f 100644 --- a/src/Wallabag/ImportBundle/Import/ChromeImport.php +++ b/src/Wallabag/ImportBundle/Import/ChromeImport.php | |||
@@ -37,9 +37,10 @@ class ChromeImport extends BrowserImport | |||
37 | { | 37 | { |
38 | $data = [ | 38 | $data = [ |
39 | 'title' => $entry['name'], | 39 | 'title' => $entry['name'], |
40 | 'html' => '', | 40 | 'html' => false, |
41 | 'url' => $entry['url'], | 41 | 'url' => $entry['url'], |
42 | 'is_archived' => $this->markAsRead, | 42 | 'is_archived' => (int) $this->markAsRead, |
43 | 'is_starred' => false, | ||
43 | 'tags' => '', | 44 | 'tags' => '', |
44 | 'created_at' => substr($entry['date_added'], 0, 10), | 45 | 'created_at' => substr($entry['date_added'], 0, 10), |
45 | ]; | 46 | ]; |
diff --git a/src/Wallabag/ImportBundle/Import/FirefoxImport.php b/src/Wallabag/ImportBundle/Import/FirefoxImport.php index e010f5a4..c50c69b3 100644 --- a/src/Wallabag/ImportBundle/Import/FirefoxImport.php +++ b/src/Wallabag/ImportBundle/Import/FirefoxImport.php | |||
@@ -37,9 +37,10 @@ class FirefoxImport extends BrowserImport | |||
37 | { | 37 | { |
38 | $data = [ | 38 | $data = [ |
39 | 'title' => $entry['title'], | 39 | 'title' => $entry['title'], |
40 | 'html' => '', | 40 | 'html' => false, |
41 | 'url' => $entry['uri'], | 41 | 'url' => $entry['uri'], |
42 | 'is_archived' => $this->markAsRead, | 42 | 'is_archived' => (int) $this->markAsRead, |
43 | 'is_starred' => false, | ||
43 | 'tags' => '', | 44 | 'tags' => '', |
44 | 'created_at' => substr($entry['dateAdded'], 0, 10), | 45 | 'created_at' => substr($entry['dateAdded'], 0, 10), |
45 | ]; | 46 | ]; |
diff --git a/src/Wallabag/ImportBundle/Import/InstapaperImport.php b/src/Wallabag/ImportBundle/Import/InstapaperImport.php index cf4c785c..70a53f1a 100644 --- a/src/Wallabag/ImportBundle/Import/InstapaperImport.php +++ b/src/Wallabag/ImportBundle/Import/InstapaperImport.php | |||
@@ -74,8 +74,7 @@ class InstapaperImport extends AbstractImport | |||
74 | 'status' => $data[3], | 74 | 'status' => $data[3], |
75 | 'is_archived' => $data[3] === 'Archive' || $data[3] === 'Starred', | 75 | 'is_archived' => $data[3] === 'Archive' || $data[3] === 'Starred', |
76 | 'is_starred' => $data[3] === 'Starred', | 76 | 'is_starred' => $data[3] === 'Starred', |
77 | 'content_type' => '', | 77 | 'html' => false, |
78 | 'language' => '', | ||
79 | ]; | 78 | ]; |
80 | } | 79 | } |
81 | fclose($handle); | 80 | fclose($handle); |
diff --git a/src/Wallabag/ImportBundle/Import/PinboardImport.php b/src/Wallabag/ImportBundle/Import/PinboardImport.php new file mode 100644 index 00000000..d9865534 --- /dev/null +++ b/src/Wallabag/ImportBundle/Import/PinboardImport.php | |||
@@ -0,0 +1,141 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Import; | ||
4 | |||
5 | use Wallabag\CoreBundle\Entity\Entry; | ||
6 | |||
7 | class PinboardImport extends AbstractImport | ||
8 | { | ||
9 | private $filepath; | ||
10 | |||
11 | /** | ||
12 | * {@inheritdoc} | ||
13 | */ | ||
14 | public function getName() | ||
15 | { | ||
16 | return 'Pinboard'; | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * {@inheritdoc} | ||
21 | */ | ||
22 | public function getUrl() | ||
23 | { | ||
24 | return 'import_pinboard'; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * {@inheritdoc} | ||
29 | */ | ||
30 | public function getDescription() | ||
31 | { | ||
32 | return 'import.pinboard.description'; | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * Set file path to the json file. | ||
37 | * | ||
38 | * @param string $filepath | ||
39 | */ | ||
40 | public function setFilepath($filepath) | ||
41 | { | ||
42 | $this->filepath = $filepath; | ||
43 | |||
44 | return $this; | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * {@inheritdoc} | ||
49 | */ | ||
50 | public function import() | ||
51 | { | ||
52 | if (!$this->user) { | ||
53 | $this->logger->error('PinboardImport: user is not defined'); | ||
54 | |||
55 | return false; | ||
56 | } | ||
57 | |||
58 | if (!file_exists($this->filepath) || !is_readable($this->filepath)) { | ||
59 | $this->logger->error('PinboardImport: unable to read file', ['filepath' => $this->filepath]); | ||
60 | |||
61 | return false; | ||
62 | } | ||
63 | |||
64 | $data = json_decode(file_get_contents($this->filepath), true); | ||
65 | |||
66 | if (empty($data)) { | ||
67 | $this->logger->error('PinboardImport: no entries in imported file'); | ||
68 | |||
69 | return false; | ||
70 | } | ||
71 | |||
72 | if ($this->producer) { | ||
73 | $this->parseEntriesForProducer($data); | ||
74 | |||
75 | return true; | ||
76 | } | ||
77 | |||
78 | $this->parseEntries($data); | ||
79 | |||
80 | return true; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * {@inheritdoc} | ||
85 | */ | ||
86 | public function parseEntry(array $importedEntry) | ||
87 | { | ||
88 | $existingEntry = $this->em | ||
89 | ->getRepository('WallabagCoreBundle:Entry') | ||
90 | ->findByUrlAndUserId($importedEntry['href'], $this->user->getId()); | ||
91 | |||
92 | if (false !== $existingEntry) { | ||
93 | ++$this->skippedEntries; | ||
94 | |||
95 | return; | ||
96 | } | ||
97 | |||
98 | $data = [ | ||
99 | 'title' => $importedEntry['description'], | ||
100 | 'url' => $importedEntry['href'], | ||
101 | 'is_archived' => ('no' === $importedEntry['toread']) || $this->markAsRead, | ||
102 | 'is_starred' => false, | ||
103 | 'created_at' => $importedEntry['time'], | ||
104 | 'tags' => explode(' ', $importedEntry['tags']), | ||
105 | ]; | ||
106 | |||
107 | $entry = new Entry($this->user); | ||
108 | $entry->setUrl($data['url']); | ||
109 | $entry->setTitle($data['title']); | ||
110 | |||
111 | // update entry with content (in case fetching failed, the given entry will be return) | ||
112 | $entry = $this->fetchContent($entry, $data['url'], $data); | ||
113 | |||
114 | if (!empty($data['tags'])) { | ||
115 | $this->contentProxy->assignTagsToEntry( | ||
116 | $entry, | ||
117 | $data['tags'], | ||
118 | $this->em->getUnitOfWork()->getScheduledEntityInsertions() | ||
119 | ); | ||
120 | } | ||
121 | |||
122 | $entry->setArchived($data['is_archived']); | ||
123 | $entry->setStarred($data['is_starred']); | ||
124 | $entry->setCreatedAt(new \DateTime($data['created_at'])); | ||
125 | |||
126 | $this->em->persist($entry); | ||
127 | ++$this->importedEntries; | ||
128 | |||
129 | return $entry; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * {@inheritdoc} | ||
134 | */ | ||
135 | protected function setEntryAsRead(array $importedEntry) | ||
136 | { | ||
137 | $importedEntry['toread'] = 'no'; | ||
138 | |||
139 | return $importedEntry; | ||
140 | } | ||
141 | } | ||
diff --git a/src/Wallabag/ImportBundle/Import/PocketImport.php b/src/Wallabag/ImportBundle/Import/PocketImport.php index 327e2500..33093480 100644 --- a/src/Wallabag/ImportBundle/Import/PocketImport.php +++ b/src/Wallabag/ImportBundle/Import/PocketImport.php | |||
@@ -2,8 +2,6 @@ | |||
2 | 2 | ||
3 | namespace Wallabag\ImportBundle\Import; | 3 | namespace Wallabag\ImportBundle\Import; |
4 | 4 | ||
5 | use Psr\Log\NullLogger; | ||
6 | use Doctrine\ORM\EntityManager; | ||
7 | use GuzzleHttp\Client; | 5 | use GuzzleHttp\Client; |
8 | use GuzzleHttp\Exception\RequestException; | 6 | use GuzzleHttp\Exception\RequestException; |
9 | use Wallabag\CoreBundle\Entity\Entry; | 7 | use Wallabag\CoreBundle\Entity\Entry; |
@@ -16,13 +14,6 @@ class PocketImport extends AbstractImport | |||
16 | 14 | ||
17 | const NB_ELEMENTS = 5000; | 15 | const NB_ELEMENTS = 5000; |
18 | 16 | ||
19 | public function __construct(EntityManager $em, ContentProxy $contentProxy) | ||
20 | { | ||
21 | $this->em = $em; | ||
22 | $this->contentProxy = $contentProxy; | ||
23 | $this->logger = new NullLogger(); | ||
24 | } | ||
25 | |||
26 | /** | 17 | /** |
27 | * Only used for test purpose. | 18 | * Only used for test purpose. |
28 | * | 19 | * |
diff --git a/src/Wallabag/ImportBundle/Import/ReadabilityImport.php b/src/Wallabag/ImportBundle/Import/ReadabilityImport.php index b8c0f777..de320d23 100644 --- a/src/Wallabag/ImportBundle/Import/ReadabilityImport.php +++ b/src/Wallabag/ImportBundle/Import/ReadabilityImport.php | |||
@@ -98,11 +98,10 @@ class ReadabilityImport extends AbstractImport | |||
98 | $data = [ | 98 | $data = [ |
99 | 'title' => $importedEntry['article__title'], | 99 | 'title' => $importedEntry['article__title'], |
100 | 'url' => $importedEntry['article__url'], | 100 | 'url' => $importedEntry['article__url'], |
101 | 'content_type' => '', | ||
102 | 'language' => '', | ||
103 | 'is_archived' => $importedEntry['archive'] || $this->markAsRead, | 101 | 'is_archived' => $importedEntry['archive'] || $this->markAsRead, |
104 | 'is_starred' => $importedEntry['favorite'], | 102 | 'is_starred' => $importedEntry['favorite'], |
105 | 'created_at' => $importedEntry['date_added'], | 103 | 'created_at' => $importedEntry['date_added'], |
104 | 'html' => false, | ||
106 | ]; | 105 | ]; |
107 | 106 | ||
108 | $entry = new Entry($this->user); | 107 | $entry = new Entry($this->user); |
diff --git a/src/Wallabag/ImportBundle/Import/WallabagV1Import.php b/src/Wallabag/ImportBundle/Import/WallabagV1Import.php index 4f001062..59e3ce02 100644 --- a/src/Wallabag/ImportBundle/Import/WallabagV1Import.php +++ b/src/Wallabag/ImportBundle/Import/WallabagV1Import.php | |||
@@ -37,8 +37,6 @@ class WallabagV1Import extends WallabagImport | |||
37 | 'title' => $entry['title'], | 37 | 'title' => $entry['title'], |
38 | 'html' => $entry['content'], | 38 | 'html' => $entry['content'], |
39 | 'url' => $entry['url'], | 39 | 'url' => $entry['url'], |
40 | 'content_type' => '', | ||
41 | 'language' => '', | ||
42 | 'is_archived' => $entry['is_read'] || $this->markAsRead, | 40 | 'is_archived' => $entry['is_read'] || $this->markAsRead, |
43 | 'is_starred' => $entry['is_fav'], | 41 | 'is_starred' => $entry['is_fav'], |
44 | 'tags' => '', | 42 | 'tags' => '', |
diff --git a/src/Wallabag/ImportBundle/Import/WallabagV2Import.php b/src/Wallabag/ImportBundle/Import/WallabagV2Import.php index 37c8ca14..d2a89d79 100644 --- a/src/Wallabag/ImportBundle/Import/WallabagV2Import.php +++ b/src/Wallabag/ImportBundle/Import/WallabagV2Import.php | |||
@@ -36,7 +36,8 @@ class WallabagV2Import extends WallabagImport | |||
36 | return [ | 36 | return [ |
37 | 'html' => $entry['content'], | 37 | 'html' => $entry['content'], |
38 | 'content_type' => $entry['mimetype'], | 38 | 'content_type' => $entry['mimetype'], |
39 | 'is_archived' => ($entry['is_archived'] || $this->markAsRead), | 39 | 'is_archived' => (int) ($entry['is_archived'] || $this->markAsRead), |
40 | 'is_starred' => false, | ||
40 | ] + $entry; | 41 | ] + $entry; |
41 | } | 42 | } |
42 | 43 | ||
diff --git a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml index 70b8a0d4..e9ecb846 100644 --- a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml +++ b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml | |||
@@ -6,6 +6,7 @@ services: | |||
6 | - "@doctrine.orm.entity_manager" | 6 | - "@doctrine.orm.entity_manager" |
7 | - "@wallabag_user.user_repository" | 7 | - "@wallabag_user.user_repository" |
8 | - "@wallabag_import.pocket.import" | 8 | - "@wallabag_import.pocket.import" |
9 | - "@event_dispatcher" | ||
9 | - "@logger" | 10 | - "@logger" |
10 | wallabag_import.consumer.amqp.readability: | 11 | wallabag_import.consumer.amqp.readability: |
11 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 12 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -13,6 +14,7 @@ services: | |||
13 | - "@doctrine.orm.entity_manager" | 14 | - "@doctrine.orm.entity_manager" |
14 | - "@wallabag_user.user_repository" | 15 | - "@wallabag_user.user_repository" |
15 | - "@wallabag_import.readability.import" | 16 | - "@wallabag_import.readability.import" |
17 | - "@event_dispatcher" | ||
16 | - "@logger" | 18 | - "@logger" |
17 | wallabag_import.consumer.amqp.instapaper: | 19 | wallabag_import.consumer.amqp.instapaper: |
18 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 20 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -20,6 +22,15 @@ services: | |||
20 | - "@doctrine.orm.entity_manager" | 22 | - "@doctrine.orm.entity_manager" |
21 | - "@wallabag_user.user_repository" | 23 | - "@wallabag_user.user_repository" |
22 | - "@wallabag_import.instapaper.import" | 24 | - "@wallabag_import.instapaper.import" |
25 | - "@event_dispatcher" | ||
26 | - "@logger" | ||
27 | wallabag_import.consumer.amqp.pinboard: | ||
28 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | ||
29 | arguments: | ||
30 | - "@doctrine.orm.entity_manager" | ||
31 | - "@wallabag_user.user_repository" | ||
32 | - "@wallabag_import.pinboard.import" | ||
33 | - "@event_dispatcher" | ||
23 | - "@logger" | 34 | - "@logger" |
24 | wallabag_import.consumer.amqp.wallabag_v1: | 35 | wallabag_import.consumer.amqp.wallabag_v1: |
25 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 36 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -27,6 +38,7 @@ services: | |||
27 | - "@doctrine.orm.entity_manager" | 38 | - "@doctrine.orm.entity_manager" |
28 | - "@wallabag_user.user_repository" | 39 | - "@wallabag_user.user_repository" |
29 | - "@wallabag_import.wallabag_v1.import" | 40 | - "@wallabag_import.wallabag_v1.import" |
41 | - "@event_dispatcher" | ||
30 | - "@logger" | 42 | - "@logger" |
31 | wallabag_import.consumer.amqp.wallabag_v2: | 43 | wallabag_import.consumer.amqp.wallabag_v2: |
32 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 44 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -34,6 +46,7 @@ services: | |||
34 | - "@doctrine.orm.entity_manager" | 46 | - "@doctrine.orm.entity_manager" |
35 | - "@wallabag_user.user_repository" | 47 | - "@wallabag_user.user_repository" |
36 | - "@wallabag_import.wallabag_v2.import" | 48 | - "@wallabag_import.wallabag_v2.import" |
49 | - "@event_dispatcher" | ||
37 | - "@logger" | 50 | - "@logger" |
38 | wallabag_import.consumer.amqp.firefox: | 51 | wallabag_import.consumer.amqp.firefox: |
39 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 52 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -41,6 +54,7 @@ services: | |||
41 | - "@doctrine.orm.entity_manager" | 54 | - "@doctrine.orm.entity_manager" |
42 | - "@wallabag_user.user_repository" | 55 | - "@wallabag_user.user_repository" |
43 | - "@wallabag_import.firefox.import" | 56 | - "@wallabag_import.firefox.import" |
57 | - "@event_dispatcher" | ||
44 | - "@logger" | 58 | - "@logger" |
45 | wallabag_import.consumer.amqp.chrome: | 59 | wallabag_import.consumer.amqp.chrome: |
46 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 60 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
@@ -48,4 +62,5 @@ services: | |||
48 | - "@doctrine.orm.entity_manager" | 62 | - "@doctrine.orm.entity_manager" |
49 | - "@wallabag_user.user_repository" | 63 | - "@wallabag_user.user_repository" |
50 | - "@wallabag_import.chrome.import" | 64 | - "@wallabag_import.chrome.import" |
65 | - "@event_dispatcher" | ||
51 | - "@logger" | 66 | - "@logger" |
diff --git a/src/Wallabag/ImportBundle/Resources/config/redis.yml b/src/Wallabag/ImportBundle/Resources/config/redis.yml index 0a81e1b5..091cdba0 100644 --- a/src/Wallabag/ImportBundle/Resources/config/redis.yml +++ b/src/Wallabag/ImportBundle/Resources/config/redis.yml | |||
@@ -18,6 +18,7 @@ services: | |||
18 | - "@doctrine.orm.entity_manager" | 18 | - "@doctrine.orm.entity_manager" |
19 | - "@wallabag_user.user_repository" | 19 | - "@wallabag_user.user_repository" |
20 | - "@wallabag_import.readability.import" | 20 | - "@wallabag_import.readability.import" |
21 | - "@event_dispatcher" | ||
21 | - "@logger" | 22 | - "@logger" |
22 | 23 | ||
23 | # instapaper | 24 | # instapaper |
@@ -38,6 +39,28 @@ services: | |||
38 | - "@doctrine.orm.entity_manager" | 39 | - "@doctrine.orm.entity_manager" |
39 | - "@wallabag_user.user_repository" | 40 | - "@wallabag_user.user_repository" |
40 | - "@wallabag_import.instapaper.import" | 41 | - "@wallabag_import.instapaper.import" |
42 | - "@event_dispatcher" | ||
43 | - "@logger" | ||
44 | |||
45 | # pinboard | ||
46 | wallabag_import.queue.redis.pinboard: | ||
47 | class: Simpleue\Queue\RedisQueue | ||
48 | arguments: | ||
49 | - "@wallabag_core.redis.client" | ||
50 | - "wallabag.import.pinboard" | ||
51 | |||
52 | wallabag_import.producer.redis.pinboard: | ||
53 | class: Wallabag\ImportBundle\Redis\Producer | ||
54 | arguments: | ||
55 | - "@wallabag_import.queue.redis.pinboard" | ||
56 | |||
57 | wallabag_import.consumer.redis.pinboard: | ||
58 | class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer | ||
59 | arguments: | ||
60 | - "@doctrine.orm.entity_manager" | ||
61 | - "@wallabag_user.user_repository" | ||
62 | - "@wallabag_import.pinboard.import" | ||
63 | - "@event_dispatcher" | ||
41 | - "@logger" | 64 | - "@logger" |
42 | 65 | ||
43 | 66 | ||
@@ -58,6 +81,7 @@ services: | |||
58 | - "@doctrine.orm.entity_manager" | 81 | - "@doctrine.orm.entity_manager" |
59 | - "@wallabag_user.user_repository" | 82 | - "@wallabag_user.user_repository" |
60 | - "@wallabag_import.pocket.import" | 83 | - "@wallabag_import.pocket.import" |
84 | - "@event_dispatcher" | ||
61 | - "@logger" | 85 | - "@logger" |
62 | 86 | ||
63 | # wallabag v1 | 87 | # wallabag v1 |
@@ -78,6 +102,7 @@ services: | |||
78 | - "@doctrine.orm.entity_manager" | 102 | - "@doctrine.orm.entity_manager" |
79 | - "@wallabag_user.user_repository" | 103 | - "@wallabag_user.user_repository" |
80 | - "@wallabag_import.wallabag_v1.import" | 104 | - "@wallabag_import.wallabag_v1.import" |
105 | - "@event_dispatcher" | ||
81 | - "@logger" | 106 | - "@logger" |
82 | 107 | ||
83 | # wallabag v2 | 108 | # wallabag v2 |
@@ -98,6 +123,7 @@ services: | |||
98 | - "@doctrine.orm.entity_manager" | 123 | - "@doctrine.orm.entity_manager" |
99 | - "@wallabag_user.user_repository" | 124 | - "@wallabag_user.user_repository" |
100 | - "@wallabag_import.wallabag_v2.import" | 125 | - "@wallabag_import.wallabag_v2.import" |
126 | - "@event_dispatcher" | ||
101 | - "@logger" | 127 | - "@logger" |
102 | 128 | ||
103 | # firefox | 129 | # firefox |
@@ -118,6 +144,7 @@ services: | |||
118 | - "@doctrine.orm.entity_manager" | 144 | - "@doctrine.orm.entity_manager" |
119 | - "@wallabag_user.user_repository" | 145 | - "@wallabag_user.user_repository" |
120 | - "@wallabag_import.firefox.import" | 146 | - "@wallabag_import.firefox.import" |
147 | - "@event_dispatcher" | ||
121 | - "@logger" | 148 | - "@logger" |
122 | 149 | ||
123 | # chrome | 150 | # chrome |
@@ -138,4 +165,5 @@ services: | |||
138 | - "@doctrine.orm.entity_manager" | 165 | - "@doctrine.orm.entity_manager" |
139 | - "@wallabag_user.user_repository" | 166 | - "@wallabag_user.user_repository" |
140 | - "@wallabag_import.chrome.import" | 167 | - "@wallabag_import.chrome.import" |
168 | - "@event_dispatcher" | ||
141 | - "@logger" | 169 | - "@logger" |
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml index d600be0f..c4fe3f92 100644 --- a/src/Wallabag/ImportBundle/Resources/config/services.yml +++ b/src/Wallabag/ImportBundle/Resources/config/services.yml | |||
@@ -20,6 +20,7 @@ services: | |||
20 | arguments: | 20 | arguments: |
21 | - "@doctrine.orm.entity_manager" | 21 | - "@doctrine.orm.entity_manager" |
22 | - "@wallabag_core.content_proxy" | 22 | - "@wallabag_core.content_proxy" |
23 | - "@event_dispatcher" | ||
23 | calls: | 24 | calls: |
24 | - [ setClient, [ "@wallabag_import.pocket.client" ] ] | 25 | - [ setClient, [ "@wallabag_import.pocket.client" ] ] |
25 | - [ setLogger, [ "@logger" ]] | 26 | - [ setLogger, [ "@logger" ]] |
@@ -31,6 +32,7 @@ services: | |||
31 | arguments: | 32 | arguments: |
32 | - "@doctrine.orm.entity_manager" | 33 | - "@doctrine.orm.entity_manager" |
33 | - "@wallabag_core.content_proxy" | 34 | - "@wallabag_core.content_proxy" |
35 | - "@event_dispatcher" | ||
34 | calls: | 36 | calls: |
35 | - [ setLogger, [ "@logger" ]] | 37 | - [ setLogger, [ "@logger" ]] |
36 | tags: | 38 | tags: |
@@ -41,6 +43,7 @@ services: | |||
41 | arguments: | 43 | arguments: |
42 | - "@doctrine.orm.entity_manager" | 44 | - "@doctrine.orm.entity_manager" |
43 | - "@wallabag_core.content_proxy" | 45 | - "@wallabag_core.content_proxy" |
46 | - "@event_dispatcher" | ||
44 | calls: | 47 | calls: |
45 | - [ setLogger, [ "@logger" ]] | 48 | - [ setLogger, [ "@logger" ]] |
46 | tags: | 49 | tags: |
@@ -51,6 +54,7 @@ services: | |||
51 | arguments: | 54 | arguments: |
52 | - "@doctrine.orm.entity_manager" | 55 | - "@doctrine.orm.entity_manager" |
53 | - "@wallabag_core.content_proxy" | 56 | - "@wallabag_core.content_proxy" |
57 | - "@event_dispatcher" | ||
54 | calls: | 58 | calls: |
55 | - [ setLogger, [ "@logger" ]] | 59 | - [ setLogger, [ "@logger" ]] |
56 | tags: | 60 | tags: |
@@ -61,16 +65,29 @@ services: | |||
61 | arguments: | 65 | arguments: |
62 | - "@doctrine.orm.entity_manager" | 66 | - "@doctrine.orm.entity_manager" |
63 | - "@wallabag_core.content_proxy" | 67 | - "@wallabag_core.content_proxy" |
68 | - "@event_dispatcher" | ||
64 | calls: | 69 | calls: |
65 | - [ setLogger, [ "@logger" ]] | 70 | - [ setLogger, [ "@logger" ]] |
66 | tags: | 71 | tags: |
67 | - { name: wallabag_import.import, alias: instapaper } | 72 | - { name: wallabag_import.import, alias: instapaper } |
68 | 73 | ||
74 | wallabag_import.pinboard.import: | ||
75 | class: Wallabag\ImportBundle\Import\PinboardImport | ||
76 | arguments: | ||
77 | - "@doctrine.orm.entity_manager" | ||
78 | - "@wallabag_core.content_proxy" | ||
79 | - "@event_dispatcher" | ||
80 | calls: | ||
81 | - [ setLogger, [ "@logger" ]] | ||
82 | tags: | ||
83 | - { name: wallabag_import.import, alias: pinboard } | ||
84 | |||
69 | wallabag_import.firefox.import: | 85 | wallabag_import.firefox.import: |
70 | class: Wallabag\ImportBundle\Import\FirefoxImport | 86 | class: Wallabag\ImportBundle\Import\FirefoxImport |
71 | arguments: | 87 | arguments: |
72 | - "@doctrine.orm.entity_manager" | 88 | - "@doctrine.orm.entity_manager" |
73 | - "@wallabag_core.content_proxy" | 89 | - "@wallabag_core.content_proxy" |
90 | - "@event_dispatcher" | ||
74 | calls: | 91 | calls: |
75 | - [ setLogger, [ "@logger" ]] | 92 | - [ setLogger, [ "@logger" ]] |
76 | tags: | 93 | tags: |
@@ -80,6 +97,7 @@ services: | |||
80 | arguments: | 97 | arguments: |
81 | - "@doctrine.orm.entity_manager" | 98 | - "@doctrine.orm.entity_manager" |
82 | - "@wallabag_core.content_proxy" | 99 | - "@wallabag_core.content_proxy" |
100 | - "@event_dispatcher" | ||
83 | calls: | 101 | calls: |
84 | - [ setLogger, [ "@logger" ]] | 102 | - [ setLogger, [ "@logger" ]] |
85 | tags: | 103 | tags: |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig index ead828c6..93b08540 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig | |||
@@ -6,6 +6,8 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} | ||
10 | |||
9 | <div class="row"> | 11 | <div class="row"> |
10 | <blockquote>{{ import.description|trans|raw }}</blockquote> | 12 | <blockquote>{{ import.description|trans|raw }}</blockquote> |
11 | <p>{{ 'import.chrome.how_to'|trans }}</p> | 13 | <p>{{ 'import.chrome.how_to'|trans }}</p> |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig index f975da3f..ced3f008 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig | |||
@@ -6,6 +6,8 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} | ||
10 | |||
9 | <div class="row"> | 11 | <div class="row"> |
10 | <blockquote>{{ import.description|trans|raw }}</blockquote> | 12 | <blockquote>{{ import.description|trans|raw }}</blockquote> |
11 | <p>{{ 'import.firefox.how_to'|trans }}</p> | 13 | <p>{{ 'import.firefox.how_to'|trans }}</p> |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/_workerEnabled.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig index 2390a41f..48bbcfe7 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Import/_workerEnabled.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Import/_information.html.twig | |||
@@ -1,8 +1,15 @@ | |||
1 | {% set redis = craue_setting('import_with_redis') %} | 1 | {% set redis = craue_setting('import_with_redis') %} |
2 | {% set rabbit = craue_setting('import_with_rabbitmq') %} | 2 | {% set rabbit = craue_setting('import_with_rabbitmq') %} |
3 | {% set downloadImages = craue_setting('download_images_enabled') %} | ||
3 | 4 | ||
4 | {% if redis or rabbit %} | 5 | {% if redis or rabbit %} |
5 | <div class="card-panel yellow darken-1 black-text"> | 6 | <div class="card-panel yellow darken-1 black-text"> |
6 | {{ 'import.worker.enabled'|trans }} <strong>{% if rabbit %}RabbitMQ{% elseif redis %}Redis{% endif %}</strong> | 7 | {{ 'import.worker.enabled'|trans }} <strong>{% if rabbit %}RabbitMQ{% elseif redis %}Redis{% endif %}</strong> |
7 | </div> | 8 | </div> |
8 | {% endif %} | 9 | {% endif %} |
10 | |||
11 | {% if not redis and not rabbit and downloadImages %} | ||
12 | <div class="card-panel orange darken-1 black-text"> | ||
13 | {{ 'import.worker.download_images_warning'|trans|raw }} | ||
14 | </div> | ||
15 | {% endif %} | ||
diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig index 6ea5e0f4..b79a1470 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig | |||
@@ -2,10 +2,18 @@ | |||
2 | 2 | ||
3 | {% block title %}{{ 'import.page_title'|trans }}{% endblock %} | 3 | {% block title %}{{ 'import.page_title'|trans }}{% endblock %} |
4 | 4 | ||
5 | {% block messages %} | ||
6 | {{ render(controller("WallabagImportBundle:Import:checkQueue")) }} | ||
7 | |||
8 | {{ parent() }} | ||
9 | {% endblock %} | ||
10 | |||
5 | {% block content %} | 11 | {% block content %} |
6 | <div class="row"> | 12 | <div class="row"> |
7 | <div class="col s12"> | 13 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 14 | <div class="card-panel settings"> |
15 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} | ||
16 | |||
9 | {{ 'import.page_description'|trans }} | 17 | {{ 'import.page_description'|trans }} |
10 | <ul> | 18 | <ul> |
11 | {% for import in imports %} | 19 | {% for import in imports %} |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig index 5789361f..28165d19 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Instapaper/index.html.twig | |||
@@ -6,7 +6,7 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_workerEnabled.html.twig' %} | 9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} |
10 | 10 | ||
11 | <div class="row"> | 11 | <div class="row"> |
12 | <blockquote>{{ import.description|trans }}</blockquote> | 12 | <blockquote>{{ import.description|trans }}</blockquote> |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig new file mode 100644 index 00000000..43f196ad --- /dev/null +++ b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig | |||
@@ -0,0 +1,45 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{{ 'import.pinboard.page_title'|trans }}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} | ||
10 | |||
11 | <div class="row"> | ||
12 | <blockquote>{{ import.description|trans }}</blockquote> | ||
13 | <p>{{ 'import.pinboard.how_to'|trans }}</p> | ||
14 | |||
15 | <div class="col s12"> | ||
16 | {{ form_start(form, {'method': 'POST'}) }} | ||
17 | {{ form_errors(form) }} | ||
18 | <div class="row"> | ||
19 | <div class="file-field input-field col s12"> | ||
20 | {{ form_errors(form.file) }} | ||
21 | <div class="btn"> | ||
22 | <span>{{ form.file.vars.label|trans }}</span> | ||
23 | {{ form_widget(form.file) }} | ||
24 | </div> | ||
25 | <div class="file-path-wrapper"> | ||
26 | <input class="file-path validate" type="text"> | ||
27 | </div> | ||
28 | </div> | ||
29 | <div class="input-field col s6 with-checkbox"> | ||
30 | <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6> | ||
31 | {{ form_widget(form.mark_as_read) }} | ||
32 | {{ form_label(form.mark_as_read) }} | ||
33 | </div> | ||
34 | </div> | ||
35 | |||
36 | {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} | ||
37 | |||
38 | {{ form_rest(form) }} | ||
39 | </form> | ||
40 | </div> | ||
41 | </div> | ||
42 | </div> | ||
43 | </div> | ||
44 | </div> | ||
45 | {% endblock %} | ||
diff --git a/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig index 6195fa07..536e3d1a 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig | |||
@@ -6,7 +6,7 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_workerEnabled.html.twig' %} | 9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} |
10 | 10 | ||
11 | {% if not has_consumer_key %} | 11 | {% if not has_consumer_key %} |
12 | <div class="card-panel red white-text"> | 12 | <div class="card-panel red white-text"> |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig index 74653b0f..737b0adf 100644 --- a/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig | |||
@@ -6,7 +6,7 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_workerEnabled.html.twig' %} | 9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} |
10 | 10 | ||
11 | <div class="row"> | 11 | <div class="row"> |
12 | <blockquote>{{ import.description|trans }}</blockquote> | 12 | <blockquote>{{ import.description|trans }}</blockquote> |
diff --git a/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig index 0b19bc34..974b2c73 100644 --- a/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig +++ b/src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig | |||
@@ -6,7 +6,7 @@ | |||
6 | <div class="row"> | 6 | <div class="row"> |
7 | <div class="col s12"> | 7 | <div class="col s12"> |
8 | <div class="card-panel settings"> | 8 | <div class="card-panel settings"> |
9 | {% include 'WallabagImportBundle:Import:_workerEnabled.html.twig' %} | 9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} |
10 | 10 | ||
11 | <div class="row"> | 11 | <div class="row"> |
12 | <blockquote>{{ import.description|trans }}</blockquote> | 12 | <blockquote>{{ import.description|trans }}</blockquote> |
diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index d98ae76a..3a167de7 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php | |||
@@ -11,6 +11,7 @@ use JMS\Serializer\Annotation\ExclusionPolicy; | |||
11 | use JMS\Serializer\Annotation\Expose; | 11 | use JMS\Serializer\Annotation\Expose; |
12 | use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; | 12 | use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; |
13 | use Symfony\Component\Security\Core\User\UserInterface; | 13 | use Symfony\Component\Security\Core\User\UserInterface; |
14 | use Wallabag\ApiBundle\Entity\Client; | ||
14 | use Wallabag\CoreBundle\Entity\Config; | 15 | use Wallabag\CoreBundle\Entity\Config; |
15 | use Wallabag\CoreBundle\Entity\Entry; | 16 | use Wallabag\CoreBundle\Entity\Entry; |
16 | 17 | ||
@@ -84,6 +85,11 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
84 | */ | 85 | */ |
85 | private $trusted; | 86 | private $trusted; |
86 | 87 | ||
88 | /** | ||
89 | * @ORM\OneToMany(targetEntity="Wallabag\ApiBundle\Entity\Client", mappedBy="user", cascade={"remove"}) | ||
90 | */ | ||
91 | protected $clients; | ||
92 | |||
87 | public function __construct() | 93 | public function __construct() |
88 | { | 94 | { |
89 | parent::__construct(); | 95 | parent::__construct(); |
@@ -240,4 +246,24 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
240 | 246 | ||
241 | return false; | 247 | return false; |
242 | } | 248 | } |
249 | |||
250 | /** | ||
251 | * @param Client $client | ||
252 | * | ||
253 | * @return User | ||
254 | */ | ||
255 | public function addClient(Client $client) | ||
256 | { | ||
257 | $this->clients[] = $client; | ||
258 | |||
259 | return $this; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * @return ArrayCollection<Entry> | ||
264 | */ | ||
265 | public function getClients() | ||
266 | { | ||
267 | return $this->clients; | ||
268 | } | ||
243 | } | 269 | } |
diff --git a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php index 8e2f04e9..0bdd1cae 100644 --- a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php +++ b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php | |||
@@ -21,8 +21,10 @@ class CreateConfigListener implements EventSubscriberInterface | |||
21 | private $rssLimit; | 21 | private $rssLimit; |
22 | private $language; | 22 | private $language; |
23 | private $readingSpeed; | 23 | private $readingSpeed; |
24 | private $actionMarkAsRead; | ||
25 | private $listMode; | ||
24 | 26 | ||
25 | public function __construct(EntityManager $em, $theme, $itemsOnPage, $rssLimit, $language, $readingSpeed) | 27 | public function __construct(EntityManager $em, $theme, $itemsOnPage, $rssLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode) |
26 | { | 28 | { |
27 | $this->em = $em; | 29 | $this->em = $em; |
28 | $this->theme = $theme; | 30 | $this->theme = $theme; |
@@ -30,6 +32,8 @@ class CreateConfigListener implements EventSubscriberInterface | |||
30 | $this->rssLimit = $rssLimit; | 32 | $this->rssLimit = $rssLimit; |
31 | $this->language = $language; | 33 | $this->language = $language; |
32 | $this->readingSpeed = $readingSpeed; | 34 | $this->readingSpeed = $readingSpeed; |
35 | $this->actionMarkAsRead = $actionMarkAsRead; | ||
36 | $this->listMode = $listMode; | ||
33 | } | 37 | } |
34 | 38 | ||
35 | public static function getSubscribedEvents() | 39 | public static function getSubscribedEvents() |
@@ -51,6 +55,8 @@ class CreateConfigListener implements EventSubscriberInterface | |||
51 | $config->setRssLimit($this->rssLimit); | 55 | $config->setRssLimit($this->rssLimit); |
52 | $config->setLanguage($this->language); | 56 | $config->setLanguage($this->language); |
53 | $config->setReadingSpeed($this->readingSpeed); | 57 | $config->setReadingSpeed($this->readingSpeed); |
58 | $config->setActionMarkAsRead($this->actionMarkAsRead); | ||
59 | $config->setListMode($this->listMode); | ||
54 | 60 | ||
55 | $this->em->persist($config); | 61 | $this->em->persist($config); |
56 | $this->em->flush(); | 62 | $this->em->flush(); |
diff --git a/src/Wallabag/UserBundle/Form/UserType.php b/src/Wallabag/UserBundle/Form/UserType.php index cfa67793..d8cdbaf9 100644 --- a/src/Wallabag/UserBundle/Form/UserType.php +++ b/src/Wallabag/UserBundle/Form/UserType.php | |||
@@ -35,10 +35,6 @@ class UserType extends AbstractType | |||
35 | 'required' => false, | 35 | 'required' => false, |
36 | 'label' => 'user.form.enabled_label', | 36 | 'label' => 'user.form.enabled_label', |
37 | ]) | 37 | ]) |
38 | ->add('locked', CheckboxType::class, [ | ||
39 | 'required' => false, | ||
40 | 'label' => 'user.form.locked_label', | ||
41 | ]) | ||
42 | ->add('twoFactorAuthentication', CheckboxType::class, [ | 38 | ->add('twoFactorAuthentication', CheckboxType::class, [ |
43 | 'required' => false, | 39 | 'required' => false, |
44 | 'label' => 'user.form.twofactor_label', | 40 | 'label' => 'user.form.twofactor_label', |
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index 009c4881..f913f52d 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php | |||
@@ -38,4 +38,18 @@ class UserRepository extends EntityRepository | |||
38 | ->getQuery() | 38 | ->getQuery() |
39 | ->getSingleResult(); | 39 | ->getSingleResult(); |
40 | } | 40 | } |
41 | |||
42 | /** | ||
43 | * Count how many users are enabled. | ||
44 | * | ||
45 | * @return int | ||
46 | */ | ||
47 | public function getSumEnabledUsers() | ||
48 | { | ||
49 | return $this->createQueryBuilder('u') | ||
50 | ->select('count(u)') | ||
51 | ->andWhere('u.enabled = true') | ||
52 | ->getQuery() | ||
53 | ->getSingleScalarResult(); | ||
54 | } | ||
41 | } | 55 | } |
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index a8ee721b..72f6f12c 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml | |||
@@ -22,7 +22,7 @@ services: | |||
22 | arguments: | 22 | arguments: |
23 | - WallabagUserBundle:User | 23 | - WallabagUserBundle:User |
24 | 24 | ||
25 | wallabag_user.create_config: | 25 | wallabag_user.listener.create_config: |
26 | class: Wallabag\UserBundle\EventListener\CreateConfigListener | 26 | class: Wallabag\UserBundle\EventListener\CreateConfigListener |
27 | arguments: | 27 | arguments: |
28 | - "@doctrine.orm.entity_manager" | 28 | - "@doctrine.orm.entity_manager" |
@@ -31,5 +31,7 @@ services: | |||
31 | - "%wallabag_core.rss_limit%" | 31 | - "%wallabag_core.rss_limit%" |
32 | - "%wallabag_core.language%" | 32 | - "%wallabag_core.language%" |
33 | - "%wallabag_core.reading_speed%" | 33 | - "%wallabag_core.reading_speed%" |
34 | - "%wallabag_core.action_mark_as_read%" | ||
35 | - "%wallabag_core.list_mode%" | ||
34 | tags: | 36 | tags: |
35 | - { name: kernel.event_subscriber } | 37 | - { name: kernel.event_subscriber } |
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.de.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.de.yml new file mode 100644 index 00000000..4efaaab4 --- /dev/null +++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.de.yml | |||
@@ -0,0 +1,11 @@ | |||
1 | # Two factor mail | ||
2 | auth_code: | ||
3 | on: 'an' | ||
4 | mailer: | ||
5 | subject: 'wallabag Authentifizierungcode' | ||
6 | body: | ||
7 | hello: "Hi %user%," | ||
8 | first_para: "da du die Zwei-Faktor-Authentifizierung in deinem wallabag Konto aktiviert hast, und du dich gerade von einem neuen Gerät (Computer, Handy, etc.) anmeldest, senden wir dir einen Code, um deinen Zugriff zu prüfen." | ||
9 | second_para: "Hier ist der Code:" | ||
10 | support: "Bitte zögere nicht, Kontakt mit uns aufzunehmen falls du ein Problem hast:" | ||
11 | signature: "Das wallabag Team" | ||
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml index 85f2ea9c..ee0a27d5 100644 --- a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml +++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.en.yml | |||
@@ -2,7 +2,7 @@ | |||
2 | auth_code: | 2 | auth_code: |
3 | on: 'on' | 3 | on: 'on' |
4 | mailer: | 4 | mailer: |
5 | subject: 'Wallabag authentication Code' | 5 | subject: 'wallabag authentication code' |
6 | body: | 6 | body: |
7 | hello: "Hi %user%," | 7 | hello: "Hi %user%," |
8 | first_para: "Since you enable two factor authentication on your wallabag account and you just logged in from a new device (computer, phone, etc.), we send you a code to validate your connection." | 8 | first_para: "Since you enable two factor authentication on your wallabag account and you just logged in from a new device (computer, phone, etc.), we send you a code to validate your connection." |
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig index 67843f20..3ffd15f5 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig | |||
@@ -47,14 +47,6 @@ | |||
47 | </div> | 47 | </div> |
48 | </div> | 48 | </div> |
49 | 49 | ||
50 | <div class="row"> | ||
51 | <div class="input-field col s12"> | ||
52 | {{ form_widget(edit_form.locked) }} | ||
53 | {{ form_label(edit_form.locked) }} | ||
54 | {{ form_errors(edit_form.locked) }} | ||
55 | </div> | ||
56 | </div> | ||
57 | |||
58 | {% if twofactor_auth %} | 50 | {% if twofactor_auth %} |
59 | <div class="row"> | 51 | <div class="row"> |
60 | <div class="input-field col s12"> | 52 | <div class="input-field col s12"> |
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig index 996bdb1a..daba29e4 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig | |||
@@ -17,7 +17,6 @@ | |||
17 | <th>{{ 'user.form.username_label'|trans }}</th> | 17 | <th>{{ 'user.form.username_label'|trans }}</th> |
18 | <th>{{ 'user.form.email_label'|trans }}</th> | 18 | <th>{{ 'user.form.email_label'|trans }}</th> |
19 | <th>{{ 'user.form.last_login_label'|trans }}</th> | 19 | <th>{{ 'user.form.last_login_label'|trans }}</th> |
20 | <th>{{ 'user.form.locked_label'|trans }}</th> | ||
21 | <th>{{ 'user.list.actions'|trans }}</th> | 20 | <th>{{ 'user.list.actions'|trans }}</th> |
22 | </tr> | 21 | </tr> |
23 | </thead> | 22 | </thead> |
@@ -27,7 +26,6 @@ | |||
27 | <td>{{ user.username }}</td> | 26 | <td>{{ user.username }}</td> |
28 | <td>{{ user.email }}</td> | 27 | <td>{{ user.email }}</td> |
29 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> | 28 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> |
30 | <td>{% if user.locked %}{{ 'user.list.yes'|trans }}{% else %}{{ 'user.list.no'|trans }}{% endif %}</td> | ||
31 | <td> | 29 | <td> |
32 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> | 30 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> |
33 | </td> | 31 | </td> |
diff --git a/src/Wallabag/UserBundle/Resources/views/Resetting/checkEmail.html.twig b/src/Wallabag/UserBundle/Resources/views/Resetting/check_email.html.twig index 66cbdc28..e9d46dcc 100644 --- a/src/Wallabag/UserBundle/Resources/views/Resetting/checkEmail.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Resetting/check_email.html.twig | |||
@@ -5,7 +5,7 @@ | |||
5 | {% block fos_user_content %} | 5 | {% block fos_user_content %} |
6 | <div class="card-content"> | 6 | <div class="card-content"> |
7 | <div class="row"> | 7 | <div class="row"> |
8 | {{ 'resetting.check_email'|trans({'%email%': email}) }} | 8 | <p>{{ 'resetting.check_email'|trans({'%tokenLifetime%': tokenLifetime}) }}</p> |
9 | </div> | 9 | </div> |
10 | </div> | 10 | </div> |
11 | {% endblock fos_user_content %} | 11 | {% endblock fos_user_content %} |
diff --git a/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig index 3731f13b..5d1f22b7 100644 --- a/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/TwoFactor/email_auth_code.html.twig | |||
@@ -74,7 +74,7 @@ | |||
74 | 74 | ||
75 | <table cellpadding="0" cellspacing="0" border="0" align="center" id="card"> | 75 | <table cellpadding="0" cellspacing="0" border="0" align="center" id="card"> |
76 | <tr> | 76 | <tr> |
77 | <td style="padding: 20px;" width="96px" valign="top"><img class="image_fix" src="{{ asset('bundles/wallabagcore/themes/material/img/logo-other_themes.png') }}" alt="logo" title="{{ wallabag_url }}" style="width: 96px; height: 96px;" /></td> | 77 | <td style="padding: 20px;" width="96px" valign="top"><img class="image_fix" src="{{ absolute_url(asset('bundles/wallabagcore/themes/_global/img/logo-other_themes.png')) }}" alt="logo" title="{{ wallabag_url }}" style="width: 96px; height: 96px;" /></td> |
78 | <td style="padding: 20px; padding-left: 0;" valign="top" id="cell_desc"> | 78 | <td style="padding: 20px; padding-left: 0;" valign="top" id="cell_desc"> |
79 | <h1>wallabag</h1> | 79 | <h1>wallabag</h1> |
80 | <h5>{{ "auth_code.on"|trans({}, 'wallabag_user') }} {{ wallabag_url }}</h5> | 80 | <h5>{{ "auth_code.on"|trans({}, 'wallabag_user') }} {{ wallabag_url }}</h5> |