aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorJeremy Benoist <jeremy.benoist@gmail.com>2016-11-03 16:41:29 +0100
committerJeremy Benoist <jeremy.benoist@gmail.com>2016-11-03 16:41:29 +0100
commit5a619812ca3eb05a82a023ccdaee13501eb8d45f (patch)
treea1541999a3e13f9bb8b45d3a61320ee61aa4eb3c /src
parentda4136557963018287cae61226e9006c3c741747 (diff)
parent84795d015b3c7e1af48a3dda3cb33cf080b66e8f (diff)
downloadwallabag-5a619812ca3eb05a82a023ccdaee13501eb8d45f.tar.gz
wallabag-5a619812ca3eb05a82a023ccdaee13501eb8d45f.tar.zst
wallabag-5a619812ca3eb05a82a023ccdaee13501eb8d45f.zip
Merge remote-tracking branch 'origin/master' into 2.2
Diffstat (limited to 'src')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php374
-rw-r--r--src/Wallabag/ApiBundle/Controller/TagRestController.php171
-rw-r--r--src/Wallabag/ApiBundle/Controller/WallabagRestController.php641
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing_rest.yml18
-rw-r--r--src/Wallabag/CoreBundle/Controller/ExportController.php23
-rw-r--r--src/Wallabag/CoreBundle/Controller/TagController.php1
-rw-r--r--src/Wallabag/CoreBundle/Helper/EntriesExport.php7
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml725
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml491
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/validators.fr.yml10
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/validators.pt.yml6
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig24
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_title.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig24
-rw-r--r--src/Wallabag/ImportBundle/Command/ImportCommand.php3
-rw-r--r--src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php10
-rw-r--r--src/Wallabag/UserBundle/Resources/config/services.yml3
-rw-r--r--src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml8
29 files changed, 1507 insertions, 1067 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
new file mode 100644
index 00000000..b3622c62
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -0,0 +1,374 @@
1<?php
2
3namespace Wallabag\ApiBundle\Controller;
4
5use Hateoas\Configuration\Route;
6use Hateoas\Representation\Factory\PagerfantaFactory;
7use Nelmio\ApiDocBundle\Annotation\ApiDoc;
8use Symfony\Component\HttpFoundation\Request;
9use Symfony\Component\HttpFoundation\JsonResponse;
10use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
11use Wallabag\CoreBundle\Entity\Entry;
12use Wallabag\CoreBundle\Entity\Tag;
13use Wallabag\CoreBundle\Event\EntrySavedEvent;
14use Wallabag\CoreBundle\Event\EntryDeletedEvent;
15
16class EntryRestController extends WallabagRestController
17{
18 /**
19 * Check if an entry exist by url.
20 *
21 * @ApiDoc(
22 * parameters={
23 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
24 * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"}
25 * }
26 * )
27 *
28 * @return JsonResponse
29 */
30 public function getEntriesExistsAction(Request $request)
31 {
32 $this->validateAuthentication();
33
34 $urls = $request->query->get('urls', []);
35
36 // handle multiple urls first
37 if (!empty($urls)) {
38 $results = [];
39 foreach ($urls as $url) {
40 $res = $this->getDoctrine()
41 ->getRepository('WallabagCoreBundle:Entry')
42 ->findByUrlAndUserId($url, $this->getUser()->getId());
43
44 $results[$url] = false === $res ? false : true;
45 }
46
47 $json = $this->get('serializer')->serialize($results, 'json');
48
49 return (new JsonResponse())->setJson($json);
50 }
51
52 // let's see if it is a simple url?
53 $url = $request->query->get('url', '');
54
55 if (empty($url)) {
56 throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
57 }
58
59 $res = $this->getDoctrine()
60 ->getRepository('WallabagCoreBundle:Entry')
61 ->findByUrlAndUserId($url, $this->getUser()->getId());
62
63 $exists = false === $res ? false : true;
64
65 $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
66
67 return (new JsonResponse())->setJson($json);
68 }
69
70 /**
71 * Retrieve all entries. It could be filtered by many options.
72 *
73 * @ApiDoc(
74 * parameters={
75 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
76 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
77 * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
78 * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
79 * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
80 * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
81 * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
82 * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
83 * }
84 * )
85 *
86 * @return JsonResponse
87 */
88 public function getEntriesAction(Request $request)
89 {
90 $this->validateAuthentication();
91
92 $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
93 $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
94 $sort = $request->query->get('sort', 'created');
95 $order = $request->query->get('order', 'desc');
96 $page = (int) $request->query->get('page', 1);
97 $perPage = (int) $request->query->get('perPage', 30);
98 $tags = $request->query->get('tags', '');
99 $since = $request->query->get('since', 0);
100
101 $pager = $this->getDoctrine()
102 ->getRepository('WallabagCoreBundle:Entry')
103 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
104
105 $pager->setCurrentPage($page);
106 $pager->setMaxPerPage($perPage);
107
108 $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
109 $paginatedCollection = $pagerfantaFactory->createRepresentation(
110 $pager,
111 new Route(
112 'api_get_entries',
113 [
114 'archive' => $isArchived,
115 'starred' => $isStarred,
116 'sort' => $sort,
117 'order' => $order,
118 'page' => $page,
119 'perPage' => $perPage,
120 'tags' => $tags,
121 'since' => $since,
122 ],
123 UrlGeneratorInterface::ABSOLUTE_URL
124 )
125 );
126
127 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
128
129 return (new JsonResponse())->setJson($json);
130 }
131
132 /**
133 * Retrieve a single entry.
134 *
135 * @ApiDoc(
136 * requirements={
137 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
138 * }
139 * )
140 *
141 * @return JsonResponse
142 */
143 public function getEntryAction(Entry $entry)
144 {
145 $this->validateAuthentication();
146 $this->validateUserAccess($entry->getUser()->getId());
147
148 $json = $this->get('serializer')->serialize($entry, 'json');
149
150 return (new JsonResponse())->setJson($json);
151 }
152
153 /**
154 * Create an entry.
155 *
156 * @ApiDoc(
157 * parameters={
158 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
159 * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
160 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
161 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
162 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
163 * }
164 * )
165 *
166 * @return JsonResponse
167 */
168 public function postEntriesAction(Request $request)
169 {
170 $this->validateAuthentication();
171
172 $url = $request->request->get('url');
173 $title = $request->request->get('title');
174 $isArchived = $request->request->get('archive');
175 $isStarred = $request->request->get('starred');
176
177 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
178
179 if (false === $entry) {
180 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
181 new Entry($this->getUser()),
182 $url
183 );
184 }
185
186 if (!is_null($title)) {
187 $entry->setTitle($title);
188 }
189
190 $tags = $request->request->get('tags', '');
191 if (!empty($tags)) {
192 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
193 }
194
195 if (!is_null($isStarred)) {
196 $entry->setStarred((bool) $isStarred);
197 }
198
199 if (!is_null($isArchived)) {
200 $entry->setArchived((bool) $isArchived);
201 }
202
203 $em = $this->getDoctrine()->getManager();
204 $em->persist($entry);
205 $em->flush();
206
207 // entry saved, dispatch event about it!
208 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
209
210 $json = $this->get('serializer')->serialize($entry, 'json');
211
212 return (new JsonResponse())->setJson($json);
213 }
214
215 /**
216 * Change several properties of an entry.
217 *
218 * @ApiDoc(
219 * requirements={
220 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
221 * },
222 * parameters={
223 * {"name"="title", "dataType"="string", "required"=false},
224 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
225 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
226 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
227 * }
228 * )
229 *
230 * @return JsonResponse
231 */
232 public function patchEntriesAction(Entry $entry, Request $request)
233 {
234 $this->validateAuthentication();
235 $this->validateUserAccess($entry->getUser()->getId());
236
237 $title = $request->request->get('title');
238 $isArchived = $request->request->get('archive');
239 $isStarred = $request->request->get('starred');
240
241 if (!is_null($title)) {
242 $entry->setTitle($title);
243 }
244
245 if (!is_null($isArchived)) {
246 $entry->setArchived((bool) $isArchived);
247 }
248
249 if (!is_null($isStarred)) {
250 $entry->setStarred((bool) $isStarred);
251 }
252
253 $tags = $request->request->get('tags', '');
254 if (!empty($tags)) {
255 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
256 }
257
258 $em = $this->getDoctrine()->getManager();
259 $em->flush();
260
261 $json = $this->get('serializer')->serialize($entry, 'json');
262
263 return (new JsonResponse())->setJson($json);
264 }
265
266 /**
267 * Delete **permanently** an entry.
268 *
269 * @ApiDoc(
270 * requirements={
271 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
272 * }
273 * )
274 *
275 * @return JsonResponse
276 */
277 public function deleteEntriesAction(Entry $entry)
278 {
279 $this->validateAuthentication();
280 $this->validateUserAccess($entry->getUser()->getId());
281
282 $em = $this->getDoctrine()->getManager();
283 $em->remove($entry);
284 $em->flush();
285
286 // entry deleted, dispatch event about it!
287 $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
288
289 $json = $this->get('serializer')->serialize($entry, 'json');
290
291 return (new JsonResponse())->setJson($json);
292 }
293
294 /**
295 * Retrieve all tags for an entry.
296 *
297 * @ApiDoc(
298 * requirements={
299 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
300 * }
301 * )
302 *
303 * @return JsonResponse
304 */
305 public function getEntriesTagsAction(Entry $entry)
306 {
307 $this->validateAuthentication();
308 $this->validateUserAccess($entry->getUser()->getId());
309
310 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
311
312 return (new JsonResponse())->setJson($json);
313 }
314
315 /**
316 * Add one or more tags to an entry.
317 *
318 * @ApiDoc(
319 * requirements={
320 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
321 * },
322 * parameters={
323 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
324 * }
325 * )
326 *
327 * @return JsonResponse
328 */
329 public function postEntriesTagsAction(Request $request, Entry $entry)
330 {
331 $this->validateAuthentication();
332 $this->validateUserAccess($entry->getUser()->getId());
333
334 $tags = $request->request->get('tags', '');
335 if (!empty($tags)) {
336 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
337 }
338
339 $em = $this->getDoctrine()->getManager();
340 $em->persist($entry);
341 $em->flush();
342
343 $json = $this->get('serializer')->serialize($entry, 'json');
344
345 return (new JsonResponse())->setJson($json);
346 }
347
348 /**
349 * Permanently remove one tag for an entry.
350 *
351 * @ApiDoc(
352 * requirements={
353 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
354 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
355 * }
356 * )
357 *
358 * @return JsonResponse
359 */
360 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
361 {
362 $this->validateAuthentication();
363 $this->validateUserAccess($entry->getUser()->getId());
364
365 $entry->removeTag($tag);
366 $em = $this->getDoctrine()->getManager();
367 $em->persist($entry);
368 $em->flush();
369
370 $json = $this->get('serializer')->serialize($entry, 'json');
371
372 return (new JsonResponse())->setJson($json);
373 }
374}
diff --git a/src/Wallabag/ApiBundle/Controller/TagRestController.php b/src/Wallabag/ApiBundle/Controller/TagRestController.php
new file mode 100644
index 00000000..4e7ddc66
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Controller/TagRestController.php
@@ -0,0 +1,171 @@
1<?php
2
3namespace Wallabag\ApiBundle\Controller;
4
5use Nelmio\ApiDocBundle\Annotation\ApiDoc;
6use Symfony\Component\HttpFoundation\Request;
7use Symfony\Component\HttpFoundation\JsonResponse;
8use Wallabag\CoreBundle\Entity\Entry;
9use Wallabag\CoreBundle\Entity\Tag;
10
11class TagRestController extends WallabagRestController
12{
13 /**
14 * Retrieve all tags.
15 *
16 * @ApiDoc()
17 *
18 * @return JsonResponse
19 */
20 public function getTagsAction()
21 {
22 $this->validateAuthentication();
23
24 $tags = $this->getDoctrine()
25 ->getRepository('WallabagCoreBundle:Tag')
26 ->findAllTags($this->getUser()->getId());
27
28 $json = $this->get('serializer')->serialize($tags, 'json');
29
30 return (new JsonResponse())->setJson($json);
31 }
32
33 /**
34 * Permanently remove one tag from **every** entry.
35 *
36 * @ApiDoc(
37 * requirements={
38 * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
39 * }
40 * )
41 *
42 * @return JsonResponse
43 */
44 public function deleteTagLabelAction(Request $request)
45 {
46 $this->validateAuthentication();
47 $label = $request->request->get('tag', '');
48
49 $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
50
51 if (empty($tag)) {
52 throw $this->createNotFoundException('Tag not found');
53 }
54
55 $this->getDoctrine()
56 ->getRepository('WallabagCoreBundle:Entry')
57 ->removeTag($this->getUser()->getId(), $tag);
58
59 $this->cleanOrphanTag($tag);
60
61 $json = $this->get('serializer')->serialize($tag, 'json');
62
63 return (new JsonResponse())->setJson($json);
64 }
65
66 /**
67 * Permanently remove some tags from **every** entry.
68 *
69 * @ApiDoc(
70 * requirements={
71 * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
72 * }
73 * )
74 *
75 * @return JsonResponse
76 */
77 public function deleteTagsLabelAction(Request $request)
78 {
79 $this->validateAuthentication();
80
81 $tagsLabels = $request->request->get('tags', '');
82
83 $tags = [];
84
85 foreach (explode(',', $tagsLabels) as $tagLabel) {
86 $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
87
88 if (!empty($tagEntity)) {
89 $tags[] = $tagEntity;
90 }
91 }
92
93 if (empty($tags)) {
94 throw $this->createNotFoundException('Tags not found');
95 }
96
97 $this->getDoctrine()
98 ->getRepository('WallabagCoreBundle:Entry')
99 ->removeTags($this->getUser()->getId(), $tags);
100
101 $this->cleanOrphanTag($tags);
102
103 $json = $this->get('serializer')->serialize($tags, 'json');
104
105 return (new JsonResponse())->setJson($json);
106 }
107
108 /**
109 * Permanently remove one tag from **every** entry.
110 *
111 * @ApiDoc(
112 * requirements={
113 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
114 * }
115 * )
116 *
117 * @return JsonResponse
118 */
119 public function deleteTagAction(Tag $tag)
120 {
121 $this->validateAuthentication();
122
123 $this->getDoctrine()
124 ->getRepository('WallabagCoreBundle:Entry')
125 ->removeTag($this->getUser()->getId(), $tag);
126
127 $this->cleanOrphanTag($tag);
128
129 $json = $this->get('serializer')->serialize($tag, 'json');
130
131 return (new JsonResponse())->setJson($json);
132 }
133
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.
152 *
153 * @param Tag|array $tags
154 */
155 private function cleanOrphanTag($tags)
156 {
157 if (!is_array($tags)) {
158 $tags = [$tags];
159 }
160
161 $em = $this->getDoctrine()->getManager();
162
163 foreach ($tags as $tag) {
164 if (count($tag->getEntries()) === 0) {
165 $em->remove($tag);
166 }
167 }
168
169 $em->flush();
170 }
171}
diff --git a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
index 50652b77..544c1ea9 100644
--- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
@@ -3,627 +3,11 @@
3namespace Wallabag\ApiBundle\Controller; 3namespace Wallabag\ApiBundle\Controller;
4 4
5use FOS\RestBundle\Controller\FOSRestController; 5use FOS\RestBundle\Controller\FOSRestController;
6use Hateoas\Configuration\Route as HateoasRoute;
7use Hateoas\Representation\Factory\PagerfantaFactory;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
10use Symfony\Component\HttpFoundation\Request;
11use Symfony\Component\HttpFoundation\JsonResponse;
12use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
13use Symfony\Component\Security\Core\Exception\AccessDeniedException; 6use Symfony\Component\Security\Core\Exception\AccessDeniedException;
14use Wallabag\CoreBundle\Entity\Entry; 7use Wallabag\CoreBundle\Entity\Entry;
15use Wallabag\CoreBundle\Entity\Tag;
16use Wallabag\AnnotationBundle\Entity\Annotation;
17use Wallabag\CoreBundle\Event\EntrySavedEvent;
18use Wallabag\CoreBundle\Event\EntryDeletedEvent;
19 8
20class WallabagRestController extends FOSRestController 9class WallabagRestController extends FOSRestController
21{ 10{
22 private function validateAuthentication()
23 {
24 if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
25 throw new AccessDeniedException();
26 }
27 }
28
29 /**
30 * Check if an entry exist by url.
31 *
32 * @ApiDoc(
33 * parameters={
34 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
35 * {"name"="urls", "dataType"="string", "required"=false, "format"="An array of urls (?urls[]=http...&urls[]=http...)", "description"="Urls (as an array) to check if it exists"}
36 * }
37 * )
38 *
39 * @return JsonResponse
40 */
41 public function getEntriesExistsAction(Request $request)
42 {
43 $this->validateAuthentication();
44
45 $urls = $request->query->get('urls', []);
46
47 // handle multiple urls first
48 if (!empty($urls)) {
49 $results = [];
50 foreach ($urls as $url) {
51 $res = $this->getDoctrine()
52 ->getRepository('WallabagCoreBundle:Entry')
53 ->findByUrlAndUserId($url, $this->getUser()->getId());
54
55 $results[$url] = false === $res ? false : true;
56 }
57
58 $json = $this->get('serializer')->serialize($results, 'json');
59
60 return (new JsonResponse())->setJson($json);
61 }
62
63 // let's see if it is a simple url?
64 $url = $request->query->get('url', '');
65
66 if (empty($url)) {
67 throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
68 }
69
70 $res = $this->getDoctrine()
71 ->getRepository('WallabagCoreBundle:Entry')
72 ->findByUrlAndUserId($url, $this->getUser()->getId());
73
74 $exists = false === $res ? false : true;
75
76 $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
77
78 return (new JsonResponse())->setJson($json);
79 }
80
81 /**
82 * Retrieve all entries. It could be filtered by many options.
83 *
84 * @ApiDoc(
85 * parameters={
86 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
87 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
88 * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
89 * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
90 * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
91 * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
92 * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
93 * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
94 * }
95 * )
96 *
97 * @return JsonResponse
98 */
99 public function getEntriesAction(Request $request)
100 {
101 $this->validateAuthentication();
102
103 $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
104 $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
105 $sort = $request->query->get('sort', 'created');
106 $order = $request->query->get('order', 'desc');
107 $page = (int) $request->query->get('page', 1);
108 $perPage = (int) $request->query->get('perPage', 30);
109 $tags = $request->query->get('tags', '');
110 $since = $request->query->get('since', 0);
111
112 $pager = $this->getDoctrine()
113 ->getRepository('WallabagCoreBundle:Entry')
114 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
115
116 $pager->setCurrentPage($page);
117 $pager->setMaxPerPage($perPage);
118
119 $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
120 $paginatedCollection = $pagerfantaFactory->createRepresentation(
121 $pager,
122 new HateoasRoute(
123 'api_get_entries',
124 [
125 'archive' => $isArchived,
126 'starred' => $isStarred,
127 'sort' => $sort,
128 'order' => $order,
129 'page' => $page,
130 'perPage' => $perPage,
131 'tags' => $tags,
132 'since' => $since,
133 ],
134 UrlGeneratorInterface::ABSOLUTE_URL
135 )
136 );
137
138 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
139
140 return (new JsonResponse())->setJson($json);
141 }
142
143 /**
144 * Retrieve a single entry.
145 *
146 * @ApiDoc(
147 * requirements={
148 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
149 * }
150 * )
151 *
152 * @return JsonResponse
153 */
154 public function getEntryAction(Entry $entry)
155 {
156 $this->validateAuthentication();
157 $this->validateUserAccess($entry->getUser()->getId());
158
159 $json = $this->get('serializer')->serialize($entry, 'json');
160
161 return (new JsonResponse())->setJson($json);
162 }
163
164 /**
165 * Retrieve a single entry as a predefined format.
166 *
167 * @ApiDoc(
168 * requirements={
169 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
170 * }
171 * )
172 *
173 * @return Response
174 */
175 public function getEntryExportAction(Entry $entry, Request $request)
176 {
177 $this->validateAuthentication();
178 $this->validateUserAccess($entry->getUser()->getId());
179
180 return $this->get('wallabag_core.helper.entries_export')
181 ->setEntries($entry)
182 ->updateTitle('entry')
183 ->exportAs($request->attributes->get('_format'));
184 }
185
186 /**
187 * Create an entry.
188 *
189 * @ApiDoc(
190 * parameters={
191 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
192 * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
193 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
194 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
195 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
196 * }
197 * )
198 *
199 * @return JsonResponse
200 */
201 public function postEntriesAction(Request $request)
202 {
203 $this->validateAuthentication();
204
205 $url = $request->request->get('url');
206 $title = $request->request->get('title');
207 $isArchived = $request->request->get('archive');
208 $isStarred = $request->request->get('starred');
209
210 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
211
212 if (false === $entry) {
213 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
214 new Entry($this->getUser()),
215 $url
216 );
217 }
218
219 if (!is_null($title)) {
220 $entry->setTitle($title);
221 }
222
223 $tags = $request->request->get('tags', '');
224 if (!empty($tags)) {
225 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
226 }
227
228 if (!is_null($isStarred)) {
229 $entry->setStarred((bool) $isStarred);
230 }
231
232 if (!is_null($isArchived)) {
233 $entry->setArchived((bool) $isArchived);
234 }
235
236 $em = $this->getDoctrine()->getManager();
237 $em->persist($entry);
238 $em->flush();
239
240 // entry saved, dispatch event about it!
241 $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
242
243 $json = $this->get('serializer')->serialize($entry, 'json');
244
245 return (new JsonResponse())->setJson($json);
246 }
247
248 /**
249 * Change several properties of an entry.
250 *
251 * @ApiDoc(
252 * requirements={
253 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
254 * },
255 * parameters={
256 * {"name"="title", "dataType"="string", "required"=false},
257 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
258 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
259 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
260 * }
261 * )
262 *
263 * @return JsonResponse
264 */
265 public function patchEntriesAction(Entry $entry, Request $request)
266 {
267 $this->validateAuthentication();
268 $this->validateUserAccess($entry->getUser()->getId());
269
270 $title = $request->request->get('title');
271 $isArchived = $request->request->get('archive');
272 $isStarred = $request->request->get('starred');
273
274 if (!is_null($title)) {
275 $entry->setTitle($title);
276 }
277
278 if (!is_null($isArchived)) {
279 $entry->setArchived((bool) $isArchived);
280 }
281
282 if (!is_null($isStarred)) {
283 $entry->setStarred((bool) $isStarred);
284 }
285
286 $tags = $request->request->get('tags', '');
287 if (!empty($tags)) {
288 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
289 }
290
291 $em = $this->getDoctrine()->getManager();
292 $em->flush();
293
294 $json = $this->get('serializer')->serialize($entry, 'json');
295
296 return (new JsonResponse())->setJson($json);
297 }
298
299 /**
300 * Delete **permanently** an entry.
301 *
302 * @ApiDoc(
303 * requirements={
304 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
305 * }
306 * )
307 *
308 * @return JsonResponse
309 */
310 public function deleteEntriesAction(Entry $entry)
311 {
312 $this->validateAuthentication();
313 $this->validateUserAccess($entry->getUser()->getId());
314
315 // entry deleted, dispatch event about it!
316 $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
317
318 $em = $this->getDoctrine()->getManager();
319 $em->remove($entry);
320 $em->flush();
321
322 $json = $this->get('serializer')->serialize($entry, 'json');
323
324 return (new JsonResponse())->setJson($json);
325 }
326
327 /**
328 * Retrieve all tags for an entry.
329 *
330 * @ApiDoc(
331 * requirements={
332 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
333 * }
334 * )
335 *
336 * @return JsonResponse
337 */
338 public function getEntriesTagsAction(Entry $entry)
339 {
340 $this->validateAuthentication();
341 $this->validateUserAccess($entry->getUser()->getId());
342
343 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
344
345 return (new JsonResponse())->setJson($json);
346 }
347
348 /**
349 * Add one or more tags to an entry.
350 *
351 * @ApiDoc(
352 * requirements={
353 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
354 * },
355 * parameters={
356 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
357 * }
358 * )
359 *
360 * @return JsonResponse
361 */
362 public function postEntriesTagsAction(Request $request, Entry $entry)
363 {
364 $this->validateAuthentication();
365 $this->validateUserAccess($entry->getUser()->getId());
366
367 $tags = $request->request->get('tags', '');
368 if (!empty($tags)) {
369 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
370 }
371
372 $em = $this->getDoctrine()->getManager();
373 $em->persist($entry);
374 $em->flush();
375
376 $json = $this->get('serializer')->serialize($entry, 'json');
377
378 return (new JsonResponse())->setJson($json);
379 }
380
381 /**
382 * Permanently remove one tag for an entry.
383 *
384 * @ApiDoc(
385 * requirements={
386 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
387 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
388 * }
389 * )
390 *
391 * @return JsonResponse
392 */
393 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
394 {
395 $this->validateAuthentication();
396 $this->validateUserAccess($entry->getUser()->getId());
397
398 $entry->removeTag($tag);
399 $em = $this->getDoctrine()->getManager();
400 $em->persist($entry);
401 $em->flush();
402
403 $json = $this->get('serializer')->serialize($entry, 'json');
404
405 return (new JsonResponse())->setJson($json);
406 }
407
408 /**
409 * Retrieve all tags.
410 *
411 * @ApiDoc()
412 *
413 * @return JsonResponse
414 */
415 public function getTagsAction()
416 {
417 $this->validateAuthentication();
418
419 $tags = $this->getDoctrine()
420 ->getRepository('WallabagCoreBundle:Tag')
421 ->findAllTags($this->getUser()->getId());
422
423 $json = $this->get('serializer')->serialize($tags, 'json');
424
425 return (new JsonResponse())->setJson($json);
426 }
427
428 /**
429 * Permanently remove one tag from **every** entry.
430 *
431 * @ApiDoc(
432 * requirements={
433 * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
434 * }
435 * )
436 *
437 * @return JsonResponse
438 */
439 public function deleteTagLabelAction(Request $request)
440 {
441 $this->validateAuthentication();
442 $label = $request->request->get('tag', '');
443
444 $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
445
446 if (empty($tag)) {
447 throw $this->createNotFoundException('Tag not found');
448 }
449
450 $this->getDoctrine()
451 ->getRepository('WallabagCoreBundle:Entry')
452 ->removeTag($this->getUser()->getId(), $tag);
453
454 $this->cleanOrphanTag($tag);
455
456 $json = $this->get('serializer')->serialize($tag, 'json');
457
458 return (new JsonResponse())->setJson($json);
459 }
460
461 /**
462 * Permanently remove some tags from **every** entry.
463 *
464 * @ApiDoc(
465 * requirements={
466 * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
467 * }
468 * )
469 *
470 * @return JsonResponse
471 */
472 public function deleteTagsLabelAction(Request $request)
473 {
474 $this->validateAuthentication();
475
476 $tagsLabels = $request->request->get('tags', '');
477
478 $tags = [];
479
480 foreach (explode(',', $tagsLabels) as $tagLabel) {
481 $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
482
483 if (!empty($tagEntity)) {
484 $tags[] = $tagEntity;
485 }
486 }
487
488 if (empty($tags)) {
489 throw $this->createNotFoundException('Tags not found');
490 }
491
492 $this->getDoctrine()
493 ->getRepository('WallabagCoreBundle:Entry')
494 ->removeTags($this->getUser()->getId(), $tags);
495
496 $this->cleanOrphanTag($tags);
497
498 $json = $this->get('serializer')->serialize($tags, 'json');
499
500 return (new JsonResponse())->setJson($json);
501 }
502
503 /**
504 * Permanently remove one tag from **every** entry.
505 *
506 * @ApiDoc(
507 * requirements={
508 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
509 * }
510 * )
511 *
512 * @return JsonResponse
513 */
514 public function deleteTagAction(Tag $tag)
515 {
516 $this->validateAuthentication();
517
518 $this->getDoctrine()
519 ->getRepository('WallabagCoreBundle:Entry')
520 ->removeTag($this->getUser()->getId(), $tag);
521
522 $this->cleanOrphanTag($tag);
523
524 $json = $this->get('serializer')->serialize($tag, 'json');
525
526 return (new JsonResponse())->setJson($json);
527 }
528
529 /**
530 * Retrieve annotations for an entry.
531 *
532 * @ApiDoc(
533 * requirements={
534 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
535 * }
536 * )
537 *
538 * @param Entry $entry
539 *
540 * @return JsonResponse
541 */
542 public function getAnnotationsAction(Entry $entry)
543 {
544 $this->validateAuthentication();
545
546 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:getAnnotations', [
547 'entry' => $entry,
548 ]);
549 }
550
551 /**
552 * Creates a new annotation.
553 *
554 * @ApiDoc(
555 * requirements={
556 * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"},
557 * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"},
558 * {"name"="text", "dataType"="string", "required"=true, "description"=""},
559 * }
560 * )
561 *
562 * @param Request $request
563 * @param Entry $entry
564 *
565 * @return JsonResponse
566 */
567 public function postAnnotationAction(Request $request, Entry $entry)
568 {
569 $this->validateAuthentication();
570
571 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:postAnnotation', [
572 'request' => $request,
573 'entry' => $entry,
574 ]);
575 }
576
577 /**
578 * Updates an annotation.
579 *
580 * @ApiDoc(
581 * requirements={
582 * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"}
583 * }
584 * )
585 *
586 * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation")
587 *
588 * @param Annotation $annotation
589 * @param Request $request
590 *
591 * @return JsonResponse
592 */
593 public function putAnnotationAction(Annotation $annotation, Request $request)
594 {
595 $this->validateAuthentication();
596
597 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:putAnnotation', [
598 'annotation' => $annotation,
599 'request' => $request,
600 ]);
601 }
602
603 /**
604 * Removes an annotation.
605 *
606 * @ApiDoc(
607 * requirements={
608 * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"}
609 * }
610 * )
611 *
612 * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation")
613 *
614 * @param Annotation $annotation
615 *
616 * @return JsonResponse
617 */
618 public function deleteAnnotationAction(Annotation $annotation)
619 {
620 $this->validateAuthentication();
621
622 return $this->forward('WallabagAnnotationBundle:WallabagAnnotation:deleteAnnotation', [
623 'annotation' => $annotation,
624 ]);
625 }
626
627 /** 11 /**
628 * Retrieve version number. 12 * Retrieve version number.
629 * 13 *
@@ -634,32 +18,15 @@ class WallabagRestController extends FOSRestController
634 public function getVersionAction() 18 public function getVersionAction()
635 { 19 {
636 $version = $this->container->getParameter('wallabag_core.version'); 20 $version = $this->container->getParameter('wallabag_core.version');
637
638 $json = $this->get('serializer')->serialize($version, 'json'); 21 $json = $this->get('serializer')->serialize($version, 'json');
639
640 return (new JsonResponse())->setJson($json); 22 return (new JsonResponse())->setJson($json);
641 } 23 }
642 24
643 /** 25 protected function validateAuthentication()
644 * Remove orphan tag in case no entries are associated to it.
645 *
646 * @param Tag|array $tags
647 */
648 private function cleanOrphanTag($tags)
649 { 26 {
650 if (!is_array($tags)) { 27 if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
651 $tags = [$tags]; 28 throw new AccessDeniedException();
652 }
653
654 $em = $this->getDoctrine()->getManager();
655
656 foreach ($tags as $tag) {
657 if (count($tag->getEntries()) === 0) {
658 $em->remove($tag);
659 }
660 } 29 }
661
662 $em->flush();
663 } 30 }
664 31
665 /** 32 /**
@@ -668,7 +35,7 @@ class WallabagRestController extends FOSRestController
668 * 35 *
669 * @param int $requestUserId User id from the requested source 36 * @param int $requestUserId User id from the requested source
670 */ 37 */
671 private function validateUserAccess($requestUserId) 38 protected function validateUserAccess($requestUserId)
672 { 39 {
673 $user = $this->get('security.token_storage')->getToken()->getUser(); 40 $user = $this->get('security.token_storage')->getToken()->getUser();
674 if ($requestUserId != $user->getId()) { 41 if ($requestUserId != $user->getId()) {
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
index 35f8b2c1..8e1886ac 100644
--- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
+++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
@@ -1,4 +1,14 @@
1api: 1entry:
2 type: rest 2 type: rest
3 resource: "WallabagApiBundle:WallabagRest" 3 resource: "WallabagApiBundle:EntryRest"
4 name_prefix: api_ 4 name_prefix: api_
5
6tag:
7 type: rest
8 resource: "WallabagApiBundle:TagRest"
9 name_prefix: api_
10
11misc:
12 type: rest
13 resource: "WallabagApiBundle:WallabagRest"
14 name_prefix: api_
diff --git a/src/Wallabag/CoreBundle/Controller/ExportController.php b/src/Wallabag/CoreBundle/Controller/ExportController.php
index 6191d5d7..79653cfe 100644
--- a/src/Wallabag/CoreBundle/Controller/ExportController.php
+++ b/src/Wallabag/CoreBundle/Controller/ExportController.php
@@ -4,8 +4,10 @@ namespace Wallabag\CoreBundle\Controller;
4 4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Bundle\FrameworkBundle\Controller\Controller; 6use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7use Symfony\Component\HttpFoundation\Request;
7use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 8use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
8use Wallabag\CoreBundle\Entity\Entry; 9use Wallabag\CoreBundle\Entity\Entry;
10use Wallabag\CoreBundle\Entity\Tag;
9 11
10/** 12/**
11 * The try/catch can be removed once all formats will be implemented. 13 * The try/catch can be removed once all formats will be implemented.
@@ -51,15 +53,24 @@ class ExportController extends Controller
51 * 53 *
52 * @return \Symfony\Component\HttpFoundation\Response 54 * @return \Symfony\Component\HttpFoundation\Response
53 */ 55 */
54 public function downloadEntriesAction($format, $category) 56 public function downloadEntriesAction(Request $request, $format, $category)
55 { 57 {
56 $method = ucfirst($category); 58 $method = ucfirst($category);
57 $methodBuilder = 'getBuilderFor'.$method.'ByUser'; 59 $methodBuilder = 'getBuilderFor'.$method.'ByUser';
58 $entries = $this->getDoctrine() 60
59 ->getRepository('WallabagCoreBundle:Entry') 61 if ($category == 'tag_entries') {
60 ->$methodBuilder($this->getUser()->getId()) 62 $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneBySlug($request->query->get('tag'));
61 ->getQuery() 63
62 ->getResult(); 64 $entries = $this->getDoctrine()
65 ->getRepository('WallabagCoreBundle:Entry')
66 ->findAllByTagId($this->getUser()->getId(), $tag->getId());
67 } else {
68 $entries = $this->getDoctrine()
69 ->getRepository('WallabagCoreBundle:Entry')
70 ->$methodBuilder($this->getUser()->getId())
71 ->getQuery()
72 ->getResult();
73 }
63 74
64 try { 75 try {
65 return $this->get('wallabag_core.helper.entries_export') 76 return $this->get('wallabag_core.helper.entries_export')
diff --git a/src/Wallabag/CoreBundle/Controller/TagController.php b/src/Wallabag/CoreBundle/Controller/TagController.php
index 4542d484..a3e70fd0 100644
--- a/src/Wallabag/CoreBundle/Controller/TagController.php
+++ b/src/Wallabag/CoreBundle/Controller/TagController.php
@@ -143,6 +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 ]); 147 ]);
147 } 148 }
148} 149}
diff --git a/src/Wallabag/CoreBundle/Helper/EntriesExport.php b/src/Wallabag/CoreBundle/Helper/EntriesExport.php
index e50c68a6..4bf292a4 100644
--- a/src/Wallabag/CoreBundle/Helper/EntriesExport.php
+++ b/src/Wallabag/CoreBundle/Helper/EntriesExport.php
@@ -8,7 +8,6 @@ use JMS\Serializer\SerializerBuilder;
8use PHPePub\Core\EPub; 8use PHPePub\Core\EPub;
9use PHPePub\Core\Structure\OPF\DublinCore; 9use PHPePub\Core\Structure\OPF\DublinCore;
10use Symfony\Component\HttpFoundation\Response; 10use Symfony\Component\HttpFoundation\Response;
11use Craue\ConfigBundle\Util\Config;
12 11
13/** 12/**
14 * This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest. 13 * This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest.
@@ -27,12 +26,12 @@ class EntriesExport
27 </div>'; 26 </div>';
28 27
29 /** 28 /**
30 * @param Config $craueConfig CraueConfig instance to get wallabag instance url from database 29 * @param string $wallabagUrl Wallabag instance url
31 * @param string $logoPath Path to the logo FROM THE BUNDLE SCOPE 30 * @param string $logoPath Path to the logo FROM THE BUNDLE SCOPE
32 */ 31 */
33 public function __construct(Config $craueConfig, $logoPath) 32 public function __construct($wallabagUrl, $logoPath)
34 { 33 {
35 $this->wallabagUrl = $craueConfig->get('wallabag_url'); 34 $this->wallabagUrl = $wallabagUrl;
36 $this->logoPath = $logoPath; 35 $this->logoPath = $logoPath;
37 } 36 }
38 37
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 56d776ad..9786ac27 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -55,6 +55,7 @@ services:
55 '.fok.nl': 'Googlebot/2.1' 55 '.fok.nl': 'Googlebot/2.1'
56 'getpocket.com': 'PHP/5.2' 56 'getpocket.com': 'PHP/5.2'
57 'iansommerville.com': 'PHP/5.2' 57 'iansommerville.com': 'PHP/5.2'
58 '.slashdot.org': 'PHP/5.2'
58 calls: 59 calls:
59 - [ setLogger, [ "@logger" ] ] 60 - [ setLogger, [ "@logger" ] ]
60 tags: 61 tags:
@@ -91,7 +92,7 @@ services:
91 wallabag_core.helper.entries_export: 92 wallabag_core.helper.entries_export:
92 class: Wallabag\CoreBundle\Helper\EntriesExport 93 class: Wallabag\CoreBundle\Helper\EntriesExport
93 arguments: 94 arguments:
94 - "@craue_config" 95 - '@=service(''craue_config'').get(''wallabag_url'')'
95 - src/Wallabag/CoreBundle/Resources/public/themes/_global/img/appicon/apple-touch-icon-152.png 96 - src/Wallabag/CoreBundle/Resources/public/themes/_global/img/appicon/apple-touch-icon-152.png
96 97
97 wallabag.operator.array.matches: 98 wallabag.operator.array.matches:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 21c26079..aeae6bcf 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -150,7 +150,7 @@ entry:
150 # starred: 'Starred entries' 150 # starred: 'Starred entries'
151 # archived: 'Archived entries' 151 # archived: 'Archived entries'
152 # filtered: 'Filtered entries' 152 # filtered: 'Filtered entries'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 156 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'RSS-oplysninger opdateret' 472 rss_updated: 'RSS-oplysninger opdateret'
473 # tagging_rules_updated: 'Tagging rules updated' 473 # tagging_rules_updated: 'Tagging rules updated'
474 # tagging_rules_deleted: 'Tagging rule deleted' 474 # tagging_rules_deleted: 'Tagging rule deleted'
475 # user_added: 'User "%username%" added'
476 # rss_token_updated: 'RSS token updated' 475 # rss_token_updated: 'RSS token updated'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index ff70cbee..2105d02d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Favorisierte Einträge' 150 starred: 'Favorisierte Einträge'
151 archived: 'Archivierte Einträge' 151 archived: 'Archivierte Einträge'
152 filtered: 'Gefilterte Einträge' 152 filtered: 'Gefilterte Einträge'
153 filtered_tags: 'Gefiltert nach Tags' 153 filtered_tags: 'Gefiltert nach Tags:'
154 untagged: 'Nicht getaggte Einträge' 154 untagged: 'Nicht getaggte Einträge'
155 list: 155 list:
156 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' 156 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'RSS-Informationen aktualisiert' 472 rss_updated: 'RSS-Informationen aktualisiert'
473 tagging_rules_updated: 'Tagging-Regeln aktualisiert' 473 tagging_rules_updated: 'Tagging-Regeln aktualisiert'
474 tagging_rules_deleted: 'Tagging-Regel gelöscht' 474 tagging_rules_deleted: 'Tagging-Regel gelöscht'
475 user_added: 'Benutzer "%username%" erstellt'
476 rss_token_updated: 'RSS-Token aktualisiert' 475 rss_token_updated: 'RSS-Token aktualisiert'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 36382b6f..2bb95728 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Starred entries' 150 starred: 'Starred entries'
151 archived: 'Archived entries' 151 archived: 'Archived entries'
152 filtered: 'Filtered entries' 152 filtered: 'Filtered entries'
153 filtered_tags: 'Filtered by tags' 153 filtered_tags: 'Filtered by tags:'
154 untagged: 'Untagged entries' 154 untagged: 'Untagged entries'
155 list: 155 list:
156 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 156 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'RSS information updated' 472 rss_updated: 'RSS information updated'
473 tagging_rules_updated: 'Tagging rules updated' 473 tagging_rules_updated: 'Tagging rules updated'
474 tagging_rules_deleted: 'Tagging rule deleted' 474 tagging_rules_deleted: 'Tagging rule deleted'
475 # user_added: 'User "%username%" added'
476 rss_token_updated: 'RSS token updated' 475 rss_token_updated: 'RSS token updated'
477 annotations_reset: Annotations reset 476 annotations_reset: Annotations reset
478 tags_reset: Tags reset 477 tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 2c80fe8f..ca3db487 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Artículos favoritos' 150 starred: 'Artículos favoritos'
151 archived: 'Artículos archivados' 151 archived: 'Artículos archivados'
152 filtered: 'Artículos filtrados' 152 filtered: 'Artículos filtrados'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' 156 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'La configuración de los feeds RSS ha sido actualizada' 472 rss_updated: 'La configuración de los feeds RSS ha sido actualizada'
473 tagging_rules_updated: 'Regla de etiquetado borrada' 473 tagging_rules_updated: 'Regla de etiquetado borrada'
474 tagging_rules_deleted: 'Regla de etiquetado actualizada' 474 tagging_rules_deleted: 'Regla de etiquetado actualizada'
475 user_added: 'Usuario "%username%" añadido'
476 rss_token_updated: 'RSS token actualizado' 475 rss_token_updated: 'RSS token actualizado'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 6b6211d6..1914215a 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'مقاله‌های برگزیده' 150 starred: 'مقاله‌های برگزیده'
151 archived: 'مقاله‌های بایگانی‌شده' 151 archived: 'مقاله‌های بایگانی‌شده'
152 filtered: 'مقاله‌های فیلترشده' 152 filtered: 'مقاله‌های فیلترشده'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' 156 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد' 472 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد'
473 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد' 473 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد'
474 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد' 474 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد'
475 user_added: 'کابر "%username%" افزوده شد'
476 rss_token_updated: 'کد آر-اس-اس به‌روز شد' 475 rss_token_updated: 'کد آر-اس-اس به‌روز شد'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 74d59e1a..60fa9a39 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -1,94 +1,94 @@
1security: 1security:
2 login: 2 login:
3 page_title: 'Bienvenue sur wallabag !' 3 page_title: "Bienvenue sur wallabag !"
4 keep_logged_in: 'Rester connecté' 4 keep_logged_in: "Rester connecté"
5 forgot_password: 'Mot de passe oublié ?' 5 forgot_password: "Mot de passe oublié ?"
6 submit: 'Se connecter' 6 submit: "Se connecter"
7 register: 'Créer un compte' 7 register: "Créer un compte"
8 username: "Nom d'utilisateur" 8 username: "Nom dutilisateur"
9 password: 'Mot de passe' 9 password: "Mot de passe"
10 cancel: 'Annuler' 10 cancel: "Annuler"
11 resetting: 11 resetting:
12 description: "Saisissez votre adresse e-mail ci-dessous, nous vous enverrons les instructions pour réinitialiser votre mot de passe." 12 description: "Saisissez votre adresse courriel ci-dessous, nous vous enverrons les instructions pour réinitialiser votre mot de passe."
13 register: 13 register:
14 page_title: 'Se créer un compte' 14 page_title: "Se créer un compte"
15 go_to_account: 'Aller sur votre compte' 15 go_to_account: "Aller sur votre compte"
16 16
17menu: 17menu:
18 left: 18 left:
19 unread: 'Non lus' 19 unread: "Non lus"
20 starred: 'Favoris' 20 starred: "Favoris"
21 archive: 'Lus' 21 archive: "Lus"
22 all_articles: 'Tous les articles' 22 all_articles: "Tous les articles"
23 config: 'Configuration' 23 config: "Configuration"
24 tags: 'Tags' 24 tags: "Tags"
25 internal_settings: 'Configuration interne' 25 internal_settings: "Configuration interne"
26 import: 'Importer' 26 import: "Importer"
27 howto: 'Aide' 27 howto: "Aide"
28 developer: 'Développeur' 28 developer: "Développeur"
29 logout: 'Déconnexion' 29 logout: "Déconnexion"
30 about: 'À propos' 30 about: "À propos"
31 search: 'Recherche' 31 search: "Recherche"
32 save_link: 'Sauvegarder un nouvel article' 32 save_link: "Sauvegarder un nouvel article"
33 back_to_unread: 'Retour aux articles non lus' 33 back_to_unread: "Retour aux articles non lus"
34 users_management: 'Gestion des utilisateurs' 34 users_management: "Gestion des utilisateurs"
35 top: 35 top:
36 add_new_entry: 'Sauvegarder un nouvel article' 36 add_new_entry: "Sauvegarder un nouvel article"
37 search: 'Rechercher' 37 search: "Rechercher"
38 filter_entries: 'Filtrer les articles' 38 filter_entries: "Filtrer les articles"
39 export: 'Exporter' 39 export: "Exporter"
40 search_form: 40 search_form:
41 input_label: 'Saisissez votre terme de recherche' 41 input_label: "Saisissez votre terme de recherche"
42 42
43footer: 43footer:
44 wallabag: 44 wallabag:
45 elsewhere: 'Emportez wallabag avec vous' 45 elsewhere: "Emportez wallabag avec vous"
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
51config: 51config:
52 page_title: 'Configuration' 52 page_title: "Configuration"
53 tab_menu: 53 tab_menu:
54 settings: 'Paramètres' 54 settings: "Paramètres"
55 rss: 'RSS' 55 rss: "RSS"
56 user_info: 'Mon compte' 56 user_info: "Mon compte"
57 password: 'Mot de passe' 57 password: "Mot de passe"
58 rules: 'Règles de tag automatiques' 58 rules: "Règles de tag automatiques"
59 new_user: 'Créer un compte' 59 new_user: "Créer un compte"
60 form: 60 form:
61 save: 'Enregistrer' 61 save: "Enregistrer"
62 form_settings: 62 form_settings:
63 theme_label: 'Thème' 63 theme_label: "Thème"
64 items_per_page_label: "Nombre d'articles par page" 64 items_per_page_label: "Nombre darticles par page"
65 language_label: 'Langue' 65 language_label: "Langue"
66 reading_speed: 66 reading_speed:
67 label: 'Vitesse de lecture' 67 label: "Vitesse de lecture"
68 help_message: 'Vous pouvez utiliser un outil en ligne pour estimer votre vitesse de lecture :' 68 help_message: "Vous pouvez utiliser un outil en ligne pour estimer votre vitesse de lecture :"
69 100_word: 'Je lis environ 100 mots par minute' 69 100_word: "Je lis environ 100 mots par minute"
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 pocket_consumer_key_label: Clé d'authentification Pocket pour importer les données 73 pocket_consumer_key_label: Clé dauthentification Pocket pour importer les données
74 android_configuration: Configurez votre application Android 74 android_configuration: Configurez votre application Android
75 form_rss: 75 form_rss:
76 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d'abord créer un jeton." 76 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton."
77 token_label: 'Jeton RSS' 77 token_label: "Jeton RSS"
78 no_token: 'Aucun jeton généré' 78 no_token: "Aucun jeton généré"
79 token_create: 'Créez votre jeton' 79 token_create: "Créez votre jeton"
80 token_reset: 'Réinitialisez votre jeton' 80 token_reset: "Réinitialisez votre jeton"
81 rss_links: 'URL de vos flux RSS' 81 rss_links: "Adresse de vos flux RSS"
82 rss_link: 82 rss_link:
83 unread: 'non lus' 83 unread: "non lus"
84 starred: 'favoris' 84 starred: "favoris"
85 archive: 'lus' 85 archive: "lus"
86 rss_limit: "Nombre d'articles dans le flux" 86 rss_limit: "Nombre darticles dans le flux"
87 form_user: 87 form_user:
88 two_factor_description: "Activer l'authentification double-facteur veut dire que vous allez recevoir un code par email à chaque nouvelle connexion non approuvée." 88 two_factor_description: "Activer l’authentification double-facteur veut dire que vous allez recevoir un code par courriel à chaque nouvelle connexion non approuvée."
89 name_label: 'Nom' 89 name_label: "Nom"
90 email_label: 'Adresse e-mail' 90 email_label: "Adresse courriel"
91 twoFactorAuthentication_label: 'Double authentification' 91 twoFactorAuthentication_label: "Double authentification"
92 delete: 92 delete:
93 title: Supprimer mon compte (attention danger !) 93 title: Supprimer mon compte (attention danger !)
94 description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté. 94 description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté.
@@ -102,335 +102,335 @@ config:
102 entries: Supprimer TOUS les articles 102 entries: Supprimer TOUS les articles
103 confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE) 103 confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE)
104 form_password: 104 form_password:
105 old_password_label: 'Mot de passe actuel' 105 old_password_label: "Mot de passe actuel"
106 new_password_label: 'Nouveau mot de passe' 106 new_password_label: "Nouveau mot de passe"
107 repeat_new_password_label: 'Confirmez votre nouveau mot de passe' 107 repeat_new_password_label: "Confirmez votre nouveau mot de passe"
108 form_rules: 108 form_rules:
109 if_label: 'si' 109 if_label: "si"
110 then_tag_as_label: 'alors attribuer les tags' 110 then_tag_as_label: "alors attribuer les tags"
111 delete_rule_label: 'supprimer' 111 delete_rule_label: "supprimer"
112 edit_rule_label: 'éditer' 112 edit_rule_label: "éditer"
113 rule_label: 'Règle' 113 rule_label: "Règle"
114 tags_label: 'Tags' 114 tags_label: "Tags"
115 faq: 115 faq:
116 title: 'FAQ' 116 title: "FAQ"
117 tagging_rules_definition_title: 'Que signifient les règles de tag automatiques ?' 117 tagging_rules_definition_title: "Que signifient les règles de tag automatiques ?"
118 tagging_rules_definition_description: "Ce sont des règles utilisées par wallabag pour classer automatiquement vos nouveaux articles.<br />À chaque fois qu'un nouvel article est ajouté, toutes les règles de tag automatiques seront utilisées afin d'ajouter les tags que vous avez configurés, vous épargnant ainsi l'effort de classifier vos articles manuellement." 118 tagging_rules_definition_description: "Ce sont des règles utilisées par wallabag pour classer automatiquement vos nouveaux articles.<br />À chaque fois qu’un nouvel article est ajouté, toutes les règles de tag automatiques seront utilisées afin d’ajouter les tags que vous avez configurés, vous épargnant ainsi l’effort de classifier vos articles manuellement."
119 how_to_use_them_title: 'Comment les utiliser ?' 119 how_to_use_them_title: "Comment les utiliser ?"
120 how_to_use_them_description: 'Imaginons que voulez attribuer aux nouveaux articles le tag « <i>lecture courte</i> » lorsque le temps de lecture est inférieur à 3 minutes.<br />Dans ce cas, vous devriez mettre « readingTime &lt;= 3 » dans le champ <i>Règle</i> et « <i>lecture courte</i> » dans le champ <i>Tag</i>.<br />Plusieurs tags peuvent être ajoutés simultanément en les séparant par des virgules : « <i>lecture courte, à lire</i> »<br />Des règles complexes peuvent être créées en utilisant des opérateurs prédéfinis: si « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » alors attribuer les tags « <i>lecture longue, github </i> »' 120 how_to_use_them_description: "Imaginons que voulez attribuer aux nouveaux articles le tag « <i>lecture courte</i> » lorsque le temps de lecture est inférieur à 3 minutes.<br />Dans ce cas, vous devriez mettre « readingTime &lt;= 3 » dans le champ <i>Règle</i> et « <i>lecture courte</i> » dans le champ <i>Tag</i>.<br />Plusieurs tags peuvent être ajoutés simultanément en les séparant par des virgules : « <i>lecture courte, à lire</i> »<br />Des règles complexes peuvent être créées en utilisant des opérateurs prédéfinis: si « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » alors attribuer les tags « <i>lecture longue, github</i> »"
121 variables_available_title: 'Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?' 121 variables_available_title: "Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?"
122 variables_available_description: 'Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles de tag automatiques :' 122 variables_available_description: "Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles de tag automatiques :"
123 meaning: 'Signification' 123 meaning: "Signification"
124 variable_description: 124 variable_description:
125 label: 'Variable' 125 label: "Variable"
126 title: "Titre de l'article" 126 title: "Titre de larticle"
127 url: "URL de l'article" 127 url: "Adresse de larticle"
128 isArchived: "Si l'article est archivé ou non" 128 isArchived: "Si larticle est archivé ou non"
129 isStarred: "Si l'article est favori ou non" 129 isStarred: "Si larticle est favori ou non"
130 content: "Le contenu de l'article" 130 content: "Le contenu de larticle"
131 language: "La langue de l'article" 131 language: "La langue de larticle"
132 mimetype: "Le type MIME de l'article" 132 mimetype: "Le type MIME de larticle"
133 readingTime: "Le temps de lecture estimé de l'article, en minutes" 133 readingTime: "Le temps de lecture estimé de larticle, en minutes"
134 domainName: "Le nom de domaine de l'article" 134 domainName: "Le nom de domaine de larticle"
135 operator_description: 135 operator_description:
136 label: 'Opérateur' 136 label: "Opérateur"
137 less_than: 'Moins que…...' 137 less_than: "Moins que…..."
138 strictly_less_than: 'Strictement moins que…' 138 strictly_less_than: "Strictement moins que…"
139 greater_than: 'Plus que…' 139 greater_than: "Plus que…"
140 strictly_greater_than: 'Strictement plus que…' 140 strictly_greater_than: "Strictement plus que…"
141 equal_to: 'Égal à…' 141 equal_to: "Égal à…"
142 not_equal_to: 'Différent de…' 142 not_equal_to: "Différent de…"
143 or: "Une règle OU l'autre" 143 or: "Une règle OU lautre"
144 and: "Une règle ET l'autre" 144 and: "Une règle ET lautre"
145 matches: 'Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches "football"</code>' 145 matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
146 146
147entry: 147entry:
148 page_titles: 148 page_titles:
149 unread: 'Articles non lus' 149 unread: "Articles non lus"
150 starred: 'Articles favoris' 150 starred: "Articles favoris"
151 archived: 'Articles lus' 151 archived: "Articles lus"
152 filtered: 'Articles filtrés' 152 filtered: "Articles filtrés"
153 filtered_tags: 'Articles filtrés par tags' 153 filtered_tags: "Articles filtrés par tags :"
154 untagged: 'Article sans tag' 154 untagged: "Article sans tag"
155 list: 155 list:
156 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." 156 number_on_the_page: "{0} Il ny a pas darticles.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
157 reading_time: 'durée de lecture' 157 reading_time: "durée de lecture"
158 reading_time_minutes: 'durée de lecture: %readingTime% min' 158 reading_time_minutes: "durée de lecture: %readingTime% min"
159 reading_time_less_one_minute: 'durée de lecture: <small class="inferieur">&lt;</small> 1 min' 159 reading_time_less_one_minute: "durée de lecture: <small class=\"inferieur\">&lt;</small> 1 min"
160 number_of_tags: '{1}et un autre tag|]1,Inf[et %count% autres tags' 160 number_of_tags: "{1}et un autre tag|]1,Inf[et %count% autres tags"
161 reading_time_minutes_short: '%readingTime% min' 161 reading_time_minutes_short: "%readingTime% min"
162 reading_time_less_one_minute_short: '<small class="inferieur">&lt;</small> 1 min' 162 reading_time_less_one_minute_short: "<small class=\"inferieur\">&lt;</small> 1 min"
163 original_article: 'original' 163 original_article: "original"
164 toogle_as_read: 'Marquer comme lu/non lu' 164 toogle_as_read: "Marquer comme lu/non lu"
165 toogle_as_star: 'Marquer comme favori' 165 toogle_as_star: "Marquer comme favori"
166 delete: 'Supprimer' 166 delete: "Supprimer"
167 export_title: 'Exporter' 167 export_title: "Exporter"
168 filters: 168 filters:
169 title: 'Filtres' 169 title: "Filtres"
170 status_label: 'Status' 170 status_label: "Status"
171 archived_label: 'Lus' 171 archived_label: "Lus"
172 starred_label: 'Favoris' 172 starred_label: "Favoris"
173 unread_label: 'Non lus' 173 unread_label: "Non lus"
174 preview_picture_label: 'A une photo' 174 preview_picture_label: "A une photo"
175 preview_picture_help: 'Photo' 175 preview_picture_help: "Photo"
176 language_label: 'Langue' 176 language_label: "Langue"
177 reading_time: 177 reading_time:
178 label: 'Durée de lecture en minutes' 178 label: "Durée de lecture en minutes"
179 from: 'de' 179 from: "de"
180 to: 'à' 180 to: "à"
181 domain_label: 'Nom de domaine' 181 domain_label: "Nom de domaine"
182 created_at: 182 created_at:
183 label: 'Date de création' 183 label: "Date de création"
184 from: 'de' 184 from: "de"
185 to: 'à' 185 to: "à"
186 action: 186 action:
187 clear: 'Effacer' 187 clear: "Effacer"
188 filter: 'Filtrer' 188 filter: "Filtrer"
189 view: 189 view:
190 left_menu: 190 left_menu:
191 back_to_top: 'Revenir en haut' 191 back_to_top: "Revenir en haut"
192 back_to_homepage: 'Retour' 192 back_to_homepage: "Retour"
193 set_as_read: 'Marquer comme lu' 193 set_as_read: "Marquer comme lu"
194 set_as_unread: 'Marquer comme non lu' 194 set_as_unread: "Marquer comme non lu"
195 set_as_starred: 'Mettre en favori' 195 set_as_starred: "Mettre en favori"
196 view_original_article: 'Article original' 196 view_original_article: "Article original"
197 re_fetch_content: 'Recharger le contenu' 197 re_fetch_content: "Recharger le contenu"
198 delete: 'Supprimer' 198 delete: "Supprimer"
199 add_a_tag: 'Ajouter un tag' 199 add_a_tag: "Ajouter un tag"
200 share_content: 'Partager' 200 share_content: "Partager"
201 share_email_label: 'Email' 201 share_email_label: "Courriel"
202 public_link: 'Lien public' 202 public_link: "Lien public"
203 delete_public_link: 'Supprimer lien public' 203 delete_public_link: "Supprimer le lien public"
204 download: 'Télécharger' 204 download: "Télécharger"
205 print: 'Imprimer' 205 print: "Imprimer"
206 problem: 206 problem:
207 label: 'Un problème ?' 207 label: "Un problème ?"
208 description: "Est-ce que cet article s'affiche mal ?" 208 description: "Est-ce que cet article saffiche mal ?"
209 edit_title: 'Modifier le titre' 209 edit_title: "Modifier le titre"
210 original_article: 'original' 210 original_article: "original"
211 annotations_on_the_entry: '{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations' 211 annotations_on_the_entry: "{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations"
212 created_at: 'Date de création' 212 created_at: "Date de création"
213 new: 213 new:
214 page_title: 'Sauvegarder un nouvel article' 214 page_title: "Sauvegarder un nouvel article"
215 placeholder: 'http://website.com' 215 placeholder: "http://website.com"
216 form_new: 216 form_new:
217 url_label: Url 217 url_label: "Adresse"
218 edit: 218 edit:
219 page_title: 'Éditer un article' 219 page_title: "Éditer un article"
220 title_label: 'Titre' 220 title_label: "Titre"
221 url_label: 'Url' 221 url_label: "Adresse"
222 is_public_label: 'Public' 222 is_public_label: "Public"
223 save_label: 'Enregistrer' 223 save_label: "Enregistrer"
224 public: 224 public:
225 shared_by_wallabag: "Cet article a été partagé par <a href='%wallabag_instance%'>wallabag</a>" 225 shared_by_wallabag: "Cet article a été partagé par <a href=\"%wallabag_instance%\">wallabag</a>"
226 226
227about: 227about:
228 page_title: 'À propos' 228 page_title: "À propos"
229 top_menu: 229 top_menu:
230 who_behind_wallabag: "L'équipe derrière wallabag" 230 who_behind_wallabag: "Léquipe derrière wallabag"
231 getting_help: "Besoin d'aide" 231 getting_help: "Besoin daide"
232 helping: 'Aider wallabag' 232 helping: "Aider wallabag"
233 contributors: 'Contributeurs' 233 contributors: "Contributeurs"
234 third_party: 'Librairies tierces' 234 third_party: "Librairies tierces"
235 who_behind_wallabag: 235 who_behind_wallabag:
236 developped_by: 'Développé par' 236 developped_by: "Développé par"
237 website: 'Site web' 237 website: "Site web"
238 many_contributors: 'Et plein de contributeurs ♥ <a href="https://github.com/wallabag/wallabag/graphs/contributors">sur Github</a>' 238 many_contributors: "Et plein de contributeurs ♥ <a href=\"https://github.com/wallabag/wallabag/graphs/contributors\">sur Github</a>"
239 project_website: 'Site web du projet' 239 project_website: "Site web du projet"
240 license: 'Licence' 240 license: "Licence"
241 version: 'Version' 241 version: "Version"
242 getting_help: 242 getting_help:
243 documentation: 'Documentation' 243 documentation: "Documentation"
244 bug_reports: 'Rapport de bugs' 244 bug_reports: "Rapport de bogue"
245 support: '<a href="https://support.wallabag.org">Sur notre site de support</a> ou <a href="https://github.com/wallabag/wallabag/issues">sur GitHub</a>' 245 support: "<a href=\"https://support.wallabag.org\">Sur notre site de support</a> ou <a href=\"https://github.com/wallabag/wallabag/issues\">sur GitHub</a>"
246 helping: 246 helping:
247 description: 'wallabag est gratuit et opensource. Vous pouvez nous aider :' 247 description: "wallabag est gratuit et opensource. Vous pouvez nous aider :"
248 by_contributing: 'en contribuant au projet :' 248 by_contributing: "en contribuant au projet :"
249 by_contributing_2: 'un ticket recense tous nos besoins' 249 by_contributing_2: "un ticket recense tous nos besoins"
250 by_paypal: 'via Paypal' 250 by_paypal: "via Paypal"
251 contributors: 251 contributors:
252 description: "Merci aux contributeurs de l'application web de wallabag" 252 description: "Merci aux contributeurs de lapplication web de wallabag"
253 third_party: 253 third_party:
254 description: 'Voici la liste des dépendances utilisées dans wallabag (et leur license) :' 254 description: "Voici la liste des dépendances utilisées dans wallabag (et leur license) :"
255 package: 'Dépendance' 255 package: "Dépendance"
256 license: 'Licence' 256 license: "Licence"
257 257
258howto: 258howto:
259 page_title: 'Aide' 259 page_title: "Aide"
260 page_description: "Il y a plusieurs façon d'enregistrer un article :" 260 page_description: "Il y a plusieurs façon denregistrer un article :"
261 top_menu: 261 top_menu:
262 browser_addons: 'Extensions de navigateur' 262 browser_addons: "Extensions de navigateur"
263 mobile_apps: 'Applications smartphone' 263 mobile_apps: "Applications smartphone"
264 bookmarklet: 'Bookmarklet' 264 bookmarklet: "Bookmarklet"
265 form: 265 form:
266 description: 'Grâce à ce formulaire' 266 description: "Grâce à ce formulaire"
267 browser_addons: 267 browser_addons:
268 firefox: 'Extension Firefox' 268 firefox: "Extension Firefox"
269 chrome: 'Extension Chrome' 269 chrome: "Extension Chrome"
270 mobile_apps: 270 mobile_apps:
271 android: 271 android:
272 via_f_droid: 'via F-Droid' 272 via_f_droid: "via F-Droid"
273 via_google_play: 'via Google Play' 273 via_google_play: "via Google Play"
274 ios: 'sur iTunes Store' 274 ios: "sur iTunes Store"
275 windows: 'sur Microsoft Store' 275 windows: "sur Microsoft Store"
276 bookmarklet: 276 bookmarklet:
277 description: 'Glissez et déposez ce lien dans votre barre de favoris :' 277 description: "Glissez et déposez ce lien dans votre barre de favoris :"
278 278
279quickstart: 279quickstart:
280 page_title: 'Pour bien débuter' 280 page_title: "Pour bien débuter"
281 more: 'Et plus encore…' 281 more: "Et plus encore…"
282 intro: 282 intro:
283 title: 'Bienvenue sur wallabag !' 283 title: "Bienvenue sur wallabag !"
284 paragraph_1: "Nous allons vous accompagner pour vous faire faire le tour de la maison et vous présenter quelques fonctionnalités qui pourraient vous intéresser pour vous approprier cet outil." 284 paragraph_1: "Nous allons vous accompagner pour vous faire faire le tour de la maison et vous présenter quelques fonctionnalités qui pourraient vous intéresser pour vous approprier cet outil."
285 paragraph_2: 'Suivez-nous !' 285 paragraph_2: "Suivez-nous !"
286 configure: 286 configure:
287 title: "Configurez l'application" 287 title: "Configurez lapplication"
288 description: 'Pour voir une application qui vous correspond, allez voir du côté de la configuration de wallabag.' 288 description: "Pour voir une application qui vous correspond, allez voir du côté de la configuration de wallabag."
289 language: "Changez la langue et le design de l'application" 289 language: "Changez la langue et le design de lapplication"
290 rss: 'Activez les flux RSS' 290 rss: "Activez les flux RSS"
291 tagging_rules: 'Écrivez des règles pour classer automatiquement vos articles' 291 tagging_rules: "Écrivez des règles pour classer automatiquement vos articles"
292 admin: 292 admin:
293 title: 'Administration' 293 title: "Administration"
294 description: "En tant qu'administrateur sur wallabag, vous avez des privilèges qui vous permettent de :" 294 description: "En tant quadministrateur sur wallabag, vous avez des privilèges qui vous permettent de :"
295 new_user: 'Créer un nouvel utilisateur' 295 new_user: "Créer un nouvel utilisateur"
296 analytics: 'Configurer les statistiques' 296 analytics: "Configurer les statistiques"
297 sharing: 'Activer des paramètres de partages' 297 sharing: "Activer des paramètres de partages"
298 export: "Configurer les formats d'export" 298 export: "Configurer les formats dexport"
299 import: "Configurer l'import" 299 import: "Configurer limport"
300 first_steps: 300 first_steps:
301 title: 'Premiers pas' 301 title: "Premiers pas"
302 description: "Maintenant que wallabag est bien configuré, il est temps d'archiver le web. Vous pouvez cliquer sur le signe + dans le coin en haut à droite." 302 description: "Maintenant que wallabag est bien configuré, il est temps d’archiver le web. Vous pouvez cliquer sur le signe + dans le coin en haut à droite."
303 new_article: 'Ajoutez votre premier article' 303 new_article: "Ajoutez votre premier article"
304 unread_articles: 'Et rangez-le !' 304 unread_articles: "Et rangez-le !"
305 migrate: 305 migrate:
306 title: 'Migrer depuis un service existant' 306 title: "Migrer depuis un service existant"
307 description: "Vous êtes un ancien utilisateur d'un service existant ? Nous allons vous aider à récupérer vos données sur wallabag." 307 description: "Vous êtes un ancien utilisateur d’un service existant ? Nous allons vous aider à récupérer vos données sur wallabag."
308 pocket: 'Migrer depuis Pocket' 308 pocket: "Migrer depuis Pocket"
309 wallabag_v1: 'Migrer depuis wallabag v1' 309 wallabag_v1: "Migrer depuis wallabag v1"
310 wallabag_v2: 'Migrer depuis wallabag v2' 310 wallabag_v2: "Migrer depuis wallabag v2"
311 readability: 'Migrer depuis Readability' 311 readability: "Migrer depuis Readability"
312 instapaper: 'Migrer depuis Instapaper' 312 instapaper: "Migrer depuis Instapaper"
313 developer: 313 developer:
314 title: 'Pour les développeurs' 314 title: "Pour les développeurs"
315 description: 'Nous avons aussi pensé aux développeurs : Docker, API, traductions, etc.' 315 description: "Nous avons aussi pensé aux développeurs : Docker, API, traductions, etc."
316 create_application: 'Créer votre application tierce' 316 create_application: "Créer votre application tierce"
317 use_docker: 'Utiliser Docker pour installer wallabag' 317 use_docker: "Utiliser Docker pour installer wallabag"
318 docs: 318 docs:
319 title: 'Documentation complète' 319 title: "Documentation complète"
320 description: "Il y a tellement de fonctionnalités dans wallabag. N'hésitez pas à lire le manuel pour les connaitre et apprendre comment les utiliser." 320 description: "Il y a tellement de fonctionnalités dans wallabag. N’hésitez pas à lire le manuel pour les connaitre et apprendre comment les utiliser."
321 annotate: 'Annoter votre article' 321 annotate: "Annoter votre article"
322 export: 'Convertissez vos articles en ePub ou en PDF' 322 export: "Convertissez vos articles en ePub ou en PDF"
323 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l'article qui vous intéresse" 323 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l’article qui vous intéresse"
324 fetching_errors: "Que faire si mon article n'est pas correctement récupéré ?" 324 fetching_errors: "Que faire si mon article nest pas correctement récupéré ?"
325 all_docs: "Et encore plein d'autres choses !" 325 all_docs: "Et encore plein dautres choses !"
326 support: 326 support:
327 title: 'Support' 327 title: "Support"
328 description: 'Parce que vous avez peut-être besoin de nous poser une question, nous sommes disponibles pour vous.' 328 description: "Parce que vous avez peut-être besoin de nous poser une question, nous sommes disponibles pour vous."
329 github: 'Sur GitHub' 329 github: "Sur GitHub"
330 email: 'Par e-mail' 330 email: "Par courriel"
331 gitter: 'Sur Gitter' 331 gitter: "Sur Gitter"
332 332
333tag: 333tag:
334 page_title: 'Tags' 334 page_title: "Tags"
335 list: 335 list:
336 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." 336 number_on_the_page: "{0} Il ny a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags."
337 see_untagged_entries: 'Voir les articles sans tag' 337 see_untagged_entries: "Voir les articles sans tag"
338 338
339import: 339import:
340 page_title: 'Importer' 340 page_title: "Importer"
341 page_description: "Bienvenue dans l'outil de migration de wallabag. Choisissez ci-dessous le service depuis lequel vous souhaitez migrer." 341 page_description: "Bienvenue dans l’outil de migration de wallabag. Choisissez ci-dessous le service depuis lequel vous souhaitez migrer."
342 action: 342 action:
343 import_contents: 'Importer les contenus' 343 import_contents: "Importer les contenus"
344 form: 344 form:
345 mark_as_read_title: 'Marquer tout comme lu ?' 345 mark_as_read_title: "Marquer tout comme lu ?"
346 mark_as_read_label: 'Marquer tous les contenus importés comme lus' 346 mark_as_read_label: "Marquer tous les contenus importés comme lus"
347 file_label: 'Fichier' 347 file_label: "Fichier"
348 save_label: 'Importer le fichier' 348 save_label: "Importer le fichier"
349 pocket: 349 pocket:
350 page_title: 'Importer > Pocket' 350 page_title: "Importer > Pocket"
351 description: "Cet outil va importer toutes vos données de Pocket. Pocket ne nous autorise pas à récupérer le contenu depuis leur service, donc wallabag doit reparcourir chaque article pour récupérer son contenu." 351 description: "Cet outil va importer toutes vos données de Pocket. Pocket ne nous autorise pas à récupérer le contenu depuis leur service, donc wallabag doit reparcourir chaque article pour récupérer son contenu."
352 config_missing: 352 config_missing:
353 description: "L'import à partir de Pocket n'est pas configuré." 353 description: "Limport à partir de Pocket nest pas configuré."
354 admin_message: "Vous devez définir %keyurls%une clé pour l'API Pocket%keyurle%." 354 admin_message: "Vous devez définir %keyurls%une clé pour lAPI Pocket%keyurle%."
355 user_message: "L'administrateur de votre serveur doit définir une clé pour l'API Pocket." 355 user_message: "Ladministrateur de votre serveur doit définir une clé pour lAPI Pocket."
356 authorize_message: "Vous pouvez importer vos données depuis votre compte Pocket. Vous n'avez qu'à cliquer sur le bouton ci-dessous et à autoriser wallabag à se connecter à getpocket.com." 356 authorize_message: "Vous pouvez importer vos données depuis votre compte Pocket. Vous n’avez qu’à cliquer sur le bouton ci-dessous et à autoriser wallabag à se connecter à getpocket.com."
357 connect_to_pocket: 'Se connecter à Pocket et importer les données' 357 connect_to_pocket: "Se connecter à Pocket et importer les données"
358 wallabag_v1: 358 wallabag_v1:
359 page_title: 'Importer > Wallabag v1' 359 page_title: "Importer > wallabag v1"
360 description: 'Cet outil va importer toutes vos données de wallabag v1. Sur votre page de configuration de wallabag v1, cliquez sur "Export JSON" dans la section "Exporter vos données de wallabag". Vous allez récupérer un fichier "wallabag-export-1-xxxx-xx-xx.json".' 360 description: "Cet outil va importer toutes vos données de wallabag v1. Sur votre page de configuration de wallabag v1, cliquez sur « Export JSON » dans la section « Exporter vos données de wallabag ». Vous allez récupérer un fichier « wallabag-export-1-xxxx-xx-xx.json »."
361 how_to: "Choisissez le fichier de votre export wallabag v1 et cliquez sur le bouton ci-dessous pour l'importer." 361 how_to: "Choisissez le fichier de votre export wallabag v1 et cliquez sur le bouton ci-dessous pour limporter."
362 wallabag_v2: 362 wallabag_v2:
363 page_title: 'Importer > Wallabag v2' 363 page_title: "Importer > wallabag v2"
364 description: "Cet outil va importer tous vos articles d'une autre instance de wallabag v2. Allez dans tous vos articles, puis, sur la barre latérale, cliquez sur \"JSON\". Vous allez récupérer un fichier \"All articles.json\"" 364 description: "Cet outil va importer tous vos articles d’une autre instance de wallabag v2. Allez dans tous vos articles, puis, sur la barre latérale, cliquez sur « JSON ». Vous allez récupérer un fichier « All articles.json »"
365 readability: 365 readability:
366 page_title: 'Importer > Readability' 366 page_title: "Importer > Readability"
367 description: 'Cet outil va importer toutes vos données de Readability. Sur la page des outils (https://www.readability.com/tools/), cliquez sur "Export your data" dans la section "Data Export". Vous allez recevoir un email avec un lien pour télécharger le json.' 367 description: "Cet outil va importer toutes vos données de Readability. Sur la page des outils (https://www.readability.com/tools/), cliquez sur « Export your data » dans la section « Data Export ». Vous allez recevoir un courriel avec un lien pour télécharger le json."
368 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l'importer." 368 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour limporter."
369 worker: 369 worker:
370 enabled: "Les imports sont asynchrones. Une fois l'import commencé un worker externe traitera les messages un par un. Le service activé est :" 370 enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :"
371 download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d'activer les imports asynchrones." 371 download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d'activer les imports asynchrones."
372 firefox: 372 firefox:
373 page_title: 'Import > Firefox' 373 page_title: "Import > Firefox"
374 description: "Cet outil va vous permettre d'importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>" 374 description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>"
375 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." 375 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."
376 chrome: 376 chrome:
377 page_title: 'Import > Chrome' 377 page_title: "Import > Chrome"
378 description: "Cet outil va vous permettre d'importer tous vos marques-pages de Google Chrome/Chromium. Pour Google Chrome, la situation du fichier dépend de votre système d'exploitation : <ul><li>Sur GNU/Linux, allez dans le répertoire <code>~/.config/google-chrome/Default/</code></li><li>Sous Windows, il devrait se trouver à <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>Sur OS X, il devrait se trouver dans le fichier <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Une fois que vous y êtes, copiez le fichier Bookmarks à un endroit où vous le retrouverez.<em><br>Notez que si vous utilisez Chromium à la place de Chrome, vous devez corriger les chemins en conséquence.</em></p>" 378 description: "Cet outil va vous permettre d’importer tous vos marques-pages de Google Chrome/Chromium. Pour Google Chrome, la situation du fichier dépend de votre système d’exploitation : <ul><li>Sur GNU/Linux, allez dans le répertoire <code>~/.config/google-chrome/Default/</code></li><li>Sous Windows, il devrait se trouver à <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>Sur OS X, il devrait se trouver dans le fichier <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Une fois que vous y êtes, copiez le fichier Bookmarks à un endroit où vous le retrouverez.<em><br>Notez que si vous utilisez Chromium à la place de Chrome, vous devez corriger les chemins en conséquence.</em></p>"
379 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." 379 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."
380 instapaper: 380 instapaper:
381 page_title: 'Import > Instapaper' 381 page_title: "Import > Instapaper"
382 description: 'Sur la page des paramètres (https://www.instapaper.com/user), cliquez sur "Download .CSV file" dans la section "Export". Un fichier CSV se téléchargera ("instapaper-export.csv").' 382 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 »)."
383 how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour l'importer." 383 how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour limporter."
384 384
385developer: 385developer:
386 page_title: 'Développeur' 386 page_title: "Développeur"
387 welcome_message: "Bienvenue sur l'API de wallabag" 387 welcome_message: "Bienvenue sur lAPI de wallabag"
388 documentation: 'Documentation' 388 documentation: "Documentation"
389 how_to_first_app: 'Comment créer votre première application' 389 how_to_first_app: "Comment créer votre première application"
390 full_documentation: "Voir la documentation complète de l'API" 390 full_documentation: "Voir la documentation complète de lAPI"
391 list_methods: "Lister toutes les méthodes de l'API" 391 list_methods: "Lister toutes les méthodes de lAPI"
392 clients: 392 clients:
393 title: 'Clients' 393 title: "Clients"
394 create_new: 'Créer un nouveau client' 394 create_new: "Créer un nouveau client"
395 existing_clients: 395 existing_clients:
396 title: 'Les clients existants' 396 title: "Les clients existants"
397 field_id: 'ID Client' 397 field_id: "ID Client"
398 field_secret: 'Clé secrète' 398 field_secret: "Clé secrète"
399 field_uris: 'URLs de redirection' 399 field_uris: "Adresse de redirection"
400 field_grant_types: 'Type de privilège accordé' 400 field_grant_types: "Type de privilège accordé"
401 no_client: 'Aucun client pour le moment' 401 no_client: "Aucun client pour le moment"
402 remove: 402 remove:
403 warn_message_1: 'Vous avez la possibilité de supprimer le client %name%. Cette action est IRRÉVERSIBLE !' 403 warn_message_1: "Vous avez la possibilité de supprimer le client %name%. Cette action est IRRÉVERSIBLE !"
404 warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag." 404 warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l’utilisaient ne fonctionneront plus avec votre compte wallabag."
405 action: 'Supprimer le client %name%' 405 action: "Supprimer le client %name%"
406 client: 406 client:
407 page_title: 'Développeur > Nouveau client' 407 page_title: "Développeur > Nouveau client"
408 page_description: "Vous allez créer un nouveau client. Merci de remplir l'url de redirection vers votre application." 408 page_description: "Vous allez créer un nouveau client. Merci de remplir l’adresse de redirection vers votre application."
409 form: 409 form:
410 name_label: "Nom du client" 410 name_label: "Nom du client"
411 redirect_uris_label: 'URLs de redirection (optionnel)' 411 redirect_uris_label: "Adresses de redirection (optionnel)"
412 save_label: 'Créer un nouveau client' 412 save_label: "Créer un nouveau client"
413 action_back: 'Retour' 413 action_back: "Retour"
414 client_parameter: 414 client_parameter:
415 page_title: 'Développeur > Les paramètres de votre client' 415 page_title: "Développeur > Les paramètres de votre client"
416 page_description: 'Voilà les paramètres de votre client' 416 page_description: "Voilà les paramètres de votre client"
417 field_name: 'Nom du client' 417 field_name: "Nom du client"
418 field_id: 'ID Client' 418 field_id: "ID client"
419 field_secret: 'Clé secrète' 419 field_secret: "Clé secrète"
420 back: 'Retour' 420 back: "Retour"
421 read_howto: 'Lire "comment créer ma première application"' 421 read_howto: "Lire « comment créer ma première application »"
422 howto: 422 howto:
423 page_title: 'Développeur > Comment créer votre première application' 423 page_title: "Développeur > Comment créer votre première application"
424 description: 424 description:
425 paragraph_1: "Les commandes suivantes utilisent la <a href=\"https://github.com/jkbrzt/httpie\">librarie HTTPie</a>. Assurez-vous qu'elle soit installée avant de l'utiliser." 425 paragraph_1: "Les commandes suivantes utilisent la <a href=\"https://github.com/jkbrzt/httpie\">librarie HTTPie</a>. Assurez-vous qu’elle soit installée avant de l’utiliser."
426 paragraph_2: "Vous avez besoin d'un token pour échanger entre votre application et l'API de wallabag." 426 paragraph_2: "Vous avez besoin dun token pour échanger entre votre application et lAPI de wallabag."
427 paragraph_3: 'Pour créer un token, vous devez <a href="%link%">créer un nouveau client</a>.' 427 paragraph_3: "Pour créer un token, vous devez <a href=\"%link%\">créer un nouveau client</a>."
428 paragraph_4: 'Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):' 428 paragraph_4: "Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):"
429 paragraph_5: "L'API vous retournera une réponse comme ça :" 429 paragraph_5: "LAPI vous retournera une réponse comme ça :"
430 paragraph_6: "L'access_token doit être utilisé pour faire un appel à l'API. Par exemple :" 430 paragraph_6: "Laccess_token doit être utilisé pour faire un appel à lAPI. Par exemple :"
431 paragraph_7: "Cet appel va retourner tous les articles de l'utilisateur." 431 paragraph_7: "Cet appel va retourner tous les articles de lutilisateur."
432 paragraph_8: "Si vous voulez toutes les méthodes de l'API, jetez un oeil <a href=\"%link%\">à la documentation de l'API</a>." 432 paragraph_8: "Si vous voulez toutes les méthodes de l’API, jetez un oeil <a href=\"%link%\">à la documentation de l’API</a>."
433 back: 'Retour' 433 back: "Retour"
434 434
435user: 435user:
436 page_title: Gestion des utilisateurs 436 page_title: Gestion des utilisateurs
@@ -444,20 +444,20 @@ user:
444 no: Non 444 no: Non
445 create_new_one: Créer un nouvel utilisateur 445 create_new_one: Créer un nouvel utilisateur
446 form: 446 form:
447 username_label: "Nom d'utilisateur" 447 username_label: "Nom dutilisateur"
448 name_label: 'Nom' 448 name_label: "Nom"
449 password_label: 'Mot de passe' 449 password_label: "Mot de passe"
450 repeat_new_password_label: 'Confirmez votre nouveau mot de passe' 450 repeat_new_password_label: "Confirmez votre nouveau mot de passe"
451 plain_password_label: 'Mot de passe en clair' 451 plain_password_label: "Mot de passe en clair"
452 email_label: 'Adresse e-mail' 452 email_label: "Adresse courriel"
453 enabled_label: 'Activé' 453 enabled_label: "Activé"
454 locked_label: 'Bloqué' 454 locked_label: "Bloqué"
455 last_login_label: 'Dernière connexion' 455 last_login_label: "Dernière connexion"
456 twofactor_label: Double authentification 456 twofactor_label: "Double authentification"
457 save: Sauvegarder 457 save: "Sauvegarder"
458 delete: Supprimer 458 delete: "Supprimer"
459 delete_confirm: Êtes-vous r? 459 delete_confirm: "Voulez-vous vraiment ?"
460 back_to_list: Revenir à la liste 460 back_to_list: "Revenir à la liste"
461 461
462error: 462error:
463 page_title: Une erreur est survenue 463 page_title: Une erreur est survenue
@@ -465,47 +465,46 @@ error:
465flashes: 465flashes:
466 config: 466 config:
467 notice: 467 notice:
468 config_saved: 'Les paramètres ont bien été mis à jour. Certains seront pris en compte après déconnexion.' 468 config_saved: "Les paramètres ont bien été mis à jour. Certains seront pris en compte après déconnexion."
469 password_updated: 'Votre mot de passe a bien été mis à jour' 469 password_updated: "Votre mot de passe a bien été mis à jour"
470 password_not_updated_demo: "En démo, vous ne pouvez pas changer le mot de passe de cet utilisateur." 470 password_not_updated_demo: "En démo, vous ne pouvez pas changer le mot de passe de cet utilisateur."
471 user_updated: 'Vos informations personnelles ont bien été mises à jour' 471 user_updated: "Vos informations personnelles ont bien été mises à jour"
472 rss_updated: 'La configuration des flux RSS a bien été mise à jour' 472 rss_updated: "La configuration des flux RSS a bien été mise à jour"
473 tagging_rules_updated: 'Règles mises à jour' 473 tagging_rules_updated: "Règles mises à jour"
474 tagging_rules_deleted: 'Règle supprimée' 474 tagging_rules_deleted: "Règle supprimée"
475 user_added: 'Utilisateur "%username%" ajouté' 475 rss_token_updated: "Jeton RSS mis à jour"
476 rss_token_updated: 'Jeton RSS mis à jour'
477 annotations_reset: Annotations supprimées 476 annotations_reset: Annotations supprimées
478 tags_reset: Tags supprimés 477 tags_reset: Tags supprimés
479 entries_reset: Articles supprimés 478 entries_reset: Articles supprimés
480 entry: 479 entry:
481 notice: 480 notice:
482 entry_already_saved: 'Article déjà sauvegardé le %date%' 481 entry_already_saved: "Article déjà sauvergardé le %date%"
483 entry_saved: 'Article enregistré' 482 entry_saved: "Article enregistré"
484 entry_saved_failed: 'Article enregistré mais impossible de récupérer le contenu' 483 entry_saved_failed: "Article enregistré mais impossible de récupérer le contenu"
485 entry_updated: 'Article mis à jour' 484 entry_updated: "Article mis à jour"
486 entry_reloaded: 'Article rechargé' 485 entry_reloaded: "Article rechargé"
487 entry_reloaded_failed: "Article mis à jour mais impossible de récupérer le contenu" 486 entry_reloaded_failed: "Article mis à jour mais impossible de récupérer le contenu"
488 entry_archived: 'Article marqué comme lu' 487 entry_archived: "Article marqué comme lu"
489 entry_unarchived: 'Article marqué comme non lu' 488 entry_unarchived: "Article marqué comme non lu"
490 entry_starred: 'Article ajouté dans les favoris' 489 entry_starred: "Article ajouté dans les favoris"
491 entry_unstarred: 'Article retiré des favoris' 490 entry_unstarred: "Article retiré des favoris"
492 entry_deleted: 'Article supprimé' 491 entry_deleted: "Article supprimé"
493 tag: 492 tag:
494 notice: 493 notice:
495 tag_added: 'Tag ajouté' 494 tag_added: "Tag ajouté"
496 import: 495 import:
497 notice: 496 notice:
498 failed: "L'import a échoué, veuillez ré-essayer" 497 failed: "Limport a échoué, veuillez ré-essayer"
499 failed_on_file: "Erreur lors du traitement de l'import. Vérifier votre fichier." 498 failed_on_file: "Erreur lors du traitement de limport. Vérifiez votre fichier."
500 summary: "Rapport d'import: %imported% importés, %skipped% déjà présents." 499 summary: "Rapport dimport : %imported% importés, %skipped% déjà présents."
501 summary_with_queue: "Rapport d'import: %queued% en cours de traitement." 500 summary_with_queue: "Rapport dimport: %queued% en cours de traitement."
502 error: 501 error:
503 redis_enabled_not_installed: Redis est activé pour les imports asynchrones mais <u>impossible de s'y connecter</u>. Vérifier la configuration de Redis. 502 redis_enabled_not_installed: "Redis est activé pour les imports asynchrones mais <u>impossible de s’y connecter</u>. Vérifier la configuration de Redis."
504 rabbit_enabled_not_installed: RabbitMQ est activé pour les imports asynchrones mais <u>impossible de s'y connecter</u>. Vérifier la configuration de RabbitMQ. 503 rabbit_enabled_not_installed: "RabbitMQ est activé pour les imports asynchrones mais <u>impossible de s’y connecter</u>. Vérifier la configuration de RabbitMQ."
505 developer: 504 developer:
506 notice: 505 notice:
507 client_created: 'Nouveau client %name% créé' 506 client_created: "Nouveau client %name% créé"
508 client_deleted: 'Client %name% supprimé' 507 client_deleted: "Client %name% supprimé"
509 user: 508 user:
510 notice: 509 notice:
511 added: 'Utilisateur "%username%" ajouté' 510 added: 'Utilisateur "%username%" ajouté'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index a448b602..7f401684 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Contenuti preferiti' 150 starred: 'Contenuti preferiti'
151 archived: 'Contenuti archiviati' 151 archived: 'Contenuti archiviati'
152 filtered: 'Contenuti filtrati' 152 filtered: 'Contenuti filtrati'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." 156 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'Informazioni RSS aggiornate' 472 rss_updated: 'Informazioni RSS aggiornate'
473 tagging_rules_updated: 'Regole di tagging aggiornate' 473 tagging_rules_updated: 'Regole di tagging aggiornate'
474 tagging_rules_deleted: 'Regola di tagging aggiornate' 474 tagging_rules_deleted: 'Regola di tagging aggiornate'
475 user_added: 'Utente "%username%" aggiunto'
476 rss_token_updated: 'RSS token aggiornato' 475 rss_token_updated: 'RSS token aggiornato'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index a61f7cdd..c3282b0e 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Articles favorits' 150 starred: 'Articles favorits'
151 archived: 'Articles legits' 151 archived: 'Articles legits'
152 filtered: 'Articles filtrats' 152 filtered: 'Articles filtrats'
153 filtered_tags: 'Filtats per etiquetas' 153 filtered_tags: 'Filtats per etiquetas:'
154 untagged: 'Articles sens etiqueta' 154 untagged: 'Articles sens etiqueta'
155 list: 155 list:
156 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." 156 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn' 472 rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn'
473 tagging_rules_updated: 'Règlas misa a jorn' 473 tagging_rules_updated: 'Règlas misa a jorn'
474 tagging_rules_deleted: 'Règla suprimida' 474 tagging_rules_deleted: 'Règla suprimida'
475 user_added: 'Utilizaire "%username%" ajustat'
476 rss_token_updated: 'Geton RSS mes a jorn' 475 rss_token_updated: 'Geton RSS mes a jorn'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index a7387b79..87731faf 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -150,7 +150,7 @@ entry:
150 starred: 'Wpisy oznaczone gwiazdką' 150 starred: 'Wpisy oznaczone gwiazdką'
151 archived: 'Zarchiwizowane wpisy' 151 archived: 'Zarchiwizowane wpisy'
152 filtered: 'Odfiltrowane wpisy' 152 filtered: 'Odfiltrowane wpisy'
153 filtered_tags: 'Filtrowane po tagach' 153 filtered_tags: 'Filtrowane po tagach:'
154 untagged: 'Odtaguj wpisy' 154 untagged: 'Odtaguj wpisy'
155 list: 155 list:
156 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' 156 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'Informacje RSS zaktualizowane' 472 rss_updated: 'Informacje RSS zaktualizowane'
473 tagging_rules_updated: 'Reguły tagowania zaktualizowane' 473 tagging_rules_updated: 'Reguły tagowania zaktualizowane'
474 tagging_rules_deleted: 'Reguła tagowania usunięta' 474 tagging_rules_deleted: 'Reguła tagowania usunięta'
475 user_added: 'Użytkownik "%username%" dodany'
476 rss_token_updated: 'Token kanału RSS zaktualizowany' 475 rss_token_updated: 'Token kanału RSS zaktualizowany'
477 annotations_reset: Zresetuj adnotacje 476 annotations_reset: Zresetuj adnotacje
478 tags_reset: Zresetuj tagi 477 tags_reset: Zresetuj tagi
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
new file mode 100644
index 00000000..c1c60430
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -0,0 +1,491 @@
1security:
2 login:
3 page_title: 'Bem vindo ao wallabag!'
4 keep_logged_in: 'Mantenha-me autenticado'
5 forgot_password: 'Esqueceu a senha?'
6 submit: 'Login'
7 register: 'Registre-se'
8 username: 'Nome de usuário'
9 password: 'Senha'
10 cancel: 'Cancelar'
11 resetting:
12 description: 'Digite seu endereço de e-mail abaixo e enviaremos instruções para resetar sua senha.'
13 register:
14 page_title: 'Criar uma conta'
15 go_to_account: 'Ir para sua conta'
16
17menu:
18 left:
19 unread: 'Não lido'
20 starred: 'Destacado'
21 archive: 'Arquivo'
22 all_articles: 'Todas as entradas'
23 config: 'Configurações'
24 tags: 'Tags'
25 internal_settings: 'Configurações Internas'
26 import: 'Importar'
27 howto: 'How to'
28 developer: 'Desenvolvedor'
29 logout: 'Sair'
30 about: 'Sobre'
31 search: 'Pesquisa'
32 save_link: 'Salvar um link'
33 back_to_unread: 'Voltar para os artigos não lidos'
34 users_management: 'Gestão de Usuários'
35 top:
36 add_new_entry: 'Adicionar uma nova entrada'
37 search: 'Pesquisa'
38 filter_entries: 'Filtrar entradas'
39 export: 'Exportar'
40 search_form:
41 input_label: 'Digite aqui sua pesquisa'
42
43footer:
44 wallabag:
45 elsewhere: 'Leve o wallabag com você'
46 social: 'Social'
47 powered_by: 'provido por'
48 about: 'Sobre'
49 stats: 'Desde %user_creation% você leu %nb_archives% artigos. Isso é %per_day% por dia!'
50
51config:
52 page_title: 'Config'
53 tab_menu:
54 settings: 'Configurações'
55 rss: 'RSS'
56 user_info: 'Informação do Usuário'
57 password: 'Senha'
58 rules: 'Regras de tags'
59 new_user: 'Adicionar um usuário'
60 form:
61 save: 'Salvar'
62 form_settings:
63 theme_label: 'Tema'
64 items_per_page_label: 'Itens por página'
65 language_label: 'Idioma'
66 reading_speed:
67 label: 'Velocidade de leitura'
68 help_message: 'Você pode usar ferramentas online para estimar sua velocidade de leitura:'
69 100_word: 'Posso ler ~100 palavras por minuto'
70 200_word: 'Posso ler ~200 palavras por minuto'
71 300_word: 'Posso ler ~300 palavras por minuto'
72 400_word: 'Posso ler ~400 palavras por minuto'
73 pocket_consumer_key_label: 'Chave do consumidor do Pocket para importar conteúdo'
74 form_rss:
75 description: 'Feeds RSS providos pelo wallabag permitem que você leia seus artigos salvos em seu leitor de RSS favorito. Você precisa gerar um token primeiro.'
76 token_label: 'Token RSS'
77 no_token: 'Nenhum Token'
78 token_create: 'Criar seu token'
79 token_reset: 'Gerar novamente seu token'
80 rss_links: 'Links RSS'
81 rss_link:
82 unread: 'não lido'
83 starred: 'destacado'
84 archive: 'arquivado'
85 rss_limit: 'Número de itens no feed'
86 form_user:
87 two_factor_description: 'Habilitar autenticação de dois passos significa que você receberá um e-mail com um código a cada nova conexão desconhecida.'
88 name_label: 'Nome'
89 email_label: 'E-mail'
90 twoFactorAuthentication_label: 'Autenticação de dois passos'
91 form_password:
92 old_password_label: 'Senha atual'
93 new_password_label: 'Nova senha'
94 repeat_new_password_label: 'Repita a nova senha'
95 form_rules:
96 if_label: 'if'
97 then_tag_as_label: 'então coloque a tag'
98 delete_rule_label: 'apagar'
99 edit_rule_label: 'editar'
100 rule_label: 'Regras'
101 tags_label: 'Tags'
102 faq:
103 title: 'FAQ'
104 tagging_rules_definition_title: 'O que as « regras de tags » significam?'
105 tagging_rules_definition_description: 'São regras usadas pelo Wallabag para automaticamente adicionar tags em novos artigos.<br />Cada vez que um novo artigo é adicionado, todas as regras de tags podem ser usadas para adicionar as tags que você configurou, ajudando-o com o problema de classificar manualmente seus artigos.'
106 how_to_use_them_title: 'Como eu as utilizo?'
107 how_to_use_them_description: 'Vamos dizer que você deseja adicionar a tag « <i>leitura rápida</i> » quando o tempo de leitura for menor que 3 minutos.<br />Neste caso, você deve « readingTime &lt;= 3 » no campo <i>Regra</i> e « <i>leitura rápida</i> » no campo <i>Tags</i>.<br />Diversas tags podem ser adicionadas simultâneamente separando-as com vírgula: « <i>leitura rápida, precisa ser lido</i> »<br />Regras complexas podem ser escritas usando os seguintes operadores pré-definidos: if « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » então adicione a tag « <i>leitura longa, github </i> »'
108 variables_available_title: 'Quais variáveis e operadores eu posso usar para escrever regras?'
109 variables_available_description: 'As seguintes variáveis e operadores podem ser usados para criar regras de tags:'
110 meaning: 'Meaning'
111 variable_description:
112 label: 'Variável'
113 title: 'Título da entrada'
114 url: 'URL da entrada'
115 isArchived: 'Se a entrada está arquivada ou não'
116 isDestacado: 'Se a entrada está destacada ou não'
117 content: 'O conteúdo da entrada'
118 language: 'O idioma da entrada'
119 mimetype: 'O mime-type da entrada'
120 readingTime: 'O tempo estimado de leitura da entrada, em minutos'
121 domainName: 'O domínio da entrada'
122 operator_description:
123 label: 'Operador'
124 less_than: 'Menor que...'
125 strictly_less_than: 'Estritamente menor que...'
126 greater_than: 'Maior que...'
127 strictly_greater_than: 'Estritamente maior que...'
128 equal_to: 'Igual a...'
129 not_equal_to: 'Diferente de...'
130 or: 'Uma regra OU outra'
131 and: 'Uma regra E outra'
132 matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>título corresponde a "futebol"</code>'
133
134entry:
135 page_titles:
136 unread: 'Entradas não lidas'
137 starred: 'Entradas destacadas'
138 archived: 'Entradas arquivadas'
139 filtered: 'Entradas filtradas'
140 filtered_tags: 'Filtrar por tags:'
141 untagged: 'Entradas sem tags'
142 list:
143 number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.'
144 reading_time: 'tempo estimado de leitura'
145 reading_time_minutes: 'tempo estimado de leitura: %readingTime% min'
146 reading_time_less_one_minute: 'tempo estimado de leitura: <small class="inferieur">&lt;</small> 1 min'
147 number_of_tags: '{1}e uma outra tag|]1,Inf[e %count% outras tags'
148 reading_time_minutes_short: '%readingTime% min'
149 reading_time_less_one_minute_short: '<small class="inferieur">&lt;</small> 1 min'
150 original_article: 'original'
151 toogle_as_read: 'Marcar como lido'
152 toogle_as_star: 'Marcar como destacado'
153 delete: 'Apagar'
154 export_title: 'Exportar'
155 filters:
156 title: 'Filtros'
157 status_label: 'Status'
158 archived_label: 'Arquivado'
159 starred_label: 'Destacado'
160 unread_label: 'Não Lido'
161 preview_picture_label: 'Possui uma imagem de preview'
162 preview_picture_help: 'Imagem de preview'
163 language_label: 'Idioma'
164 reading_time:
165 label: 'Tempo de leitura em minutos'
166 from: 'de'
167 to: 'para'
168 domain_label: 'Nome do domínio'
169 created_at:
170 label: 'Data de criação'
171 from: 'de'
172 to: 'para'
173 action:
174 clear: 'Limpar'
175 filter: 'Filtro'
176 view:
177 left_menu:
178 back_to_top: 'Voltar ao topo'
179 back_to_homepage: 'Voltar'
180 set_as_read: 'Marcar como lido'
181 set_as_unread: 'Marcar como não lido'
182 set_as_starred: 'Alternar destaque'
183 view_original_article: 'Artigo original'
184 re_fetch_content: 'Recapturar o conteúdo'
185 delete: 'Apagar'
186 add_a_tag: 'Adicionar uma tag'
187 share_content: 'Compartilhar'
188 share_email_label: 'E-mail'
189 public_link: 'link público'
190 delete_public_link: 'apagar link público'
191 download: 'Download'
192 print: 'Imprimir'
193 problem:
194 label: 'Problemas?'
195 description: 'este artigo aparece errado?'
196 edit_title: 'Editar título'
197 original_article: 'original'
198 annotations_on_the_entry: '{0} Sem anotações|{1} Uma anotação|]1,Inf[ %nbAnnotations% anotações'
199 created_at: 'Data de criação'
200 new:
201 page_title: 'Salvar nova entrada'
202 placeholder: 'http://website.com'
203 form_new:
204 url_label: Url
205 edit:
206 page_title: 'Editar uma entrada'
207 title_label: 'Título'
208 url_label: 'Url'
209 is_public_label: 'Público'
210 save_label: 'Salvar'
211 public:
212 shared_by_wallabag: "Este artigo foi compartilhado pelo <a href='%wallabag_instance%'>wallabag</a>"
213
214about:
215 page_title: 'Sobre'
216 top_menu:
217 who_behind_wallabag: 'Quem está por trás do wallabag'
218 getting_help: 'Obtendo ajuda'
219 helping: 'Ajudando o wallabag'
220 contributors: 'Contribuidores'
221 third_party: 'Bibliotecas terceiras'
222 who_behind_wallabag:
223 developped_by: 'Desenvolvido por'
224 website: 'website'
225 many_contributors: 'E muitos outros contribuidores ♥ <a href="https://github.com/wallabag/wallabag/graphs/contributors">no Github</a>'
226 project_website: 'Website do projeto'
227 license: 'Licença'
228 version: 'Versão'
229 getting_help:
230 documentation: 'Documentação'
231 bug_reports: 'Informar bugs'
232 support: '<a href="https://support.wallabag.org">Em nosso site de suporte</a> ou <a href="https://github.com/wallabag/wallabag/issues">no GitHub</a>'
233 helping:
234 description: 'wallabag é livre e software livre. Você pode nos ajudar:'
235 by_contributing: 'contribuindo com o projeto:'
236 by_contributing_2: 'uma lista de todas as nossas necessidades'
237 by_paypal: 'via Paypal'
238 contributors:
239 description: 'Obrigado por contribuir com a aplicação web wallabag'
240 third_party:
241 description: 'Aqui está a lista de bibliotecas terceiras usadas no wallabag (com suas licenças):'
242 package: 'Pacote'
243 license: 'Licença'
244
245howto:
246 page_title: 'How to'
247 page_description: 'Existem diferentes formas de salvar um artigo:'
248 top_menu:
249 browser_addons: 'Extensões de navegadores'
250 mobile_apps: "App's móveis"
251 bookmarklet: 'Bookmarklet'
252 form:
253 description: 'Obrigado por este formulário'
254 browser_addons:
255 firefox: 'Extensão padrão do Firefox'
256 chrome: 'Extensão do Chrome'
257 mobile_apps:
258 android:
259 via_f_droid: 'via F-Droid'
260 via_google_play: 'via Google Play'
261 ios: 'na iTunes Store'
262 windows: 'na Microsoft Store'
263 bookmarklet:
264 description: 'Arraste e solve este link na sua barra de favoritos:'
265
266quickstart:
267 page_title: 'Começo Rápido'
268 more: 'Mais...'
269 intro:
270 title: 'Bem-vindo ao wallabag!'
271 paragraph_1: 'Nós podemos acompanhar você em sua visita ao wallabag e mostrar algumas funcionalidades que podem lhe interessar.'
272 paragraph_2: 'Siga-nos!'
273 configure:
274 title: 'Configurar a aplicação'
275 description: 'Para ter uma aplicação que atende você, dê uma olhada na configuração do wallabag.'
276 language: 'Alterar idioma e design'
277 rss: 'Habilitar feeds RSS'
278 tagging_rules: 'Escrever regras para acrescentar tags automaticamente em seus artigos'
279 admin:
280 title: 'Administração'
281 description: 'Como administrador você tem privilégios no wallabag. Você pode:'
282 new_user: 'Criar um novo usuário'
283 analytics: 'Configurar o analytics'
284 sharing: 'habilitar alguns parâmetros para compartilhamento de artigos'
285 export: 'Configurar exportação'
286 import: 'Configurar importação'
287 first_steps:
288 title: 'Primeiros passos'
289 description: "Agora o wallabag está bem configurado, é hora de arquivar a web. Você pode clicar no sinal de + no topo a direita para adicionar um link."
290 new_article: 'Salvar seu primeiro artigo'
291 unread_articles: 'E classificá-lo!'
292 migrate:
293 title: 'Migrar de um serviço existente'
294 description: 'Você está usando um outro serviço? Nós podemos ajudá-lo a recuperar seus dados para o wallabag.'
295 pocket: 'Migrar do Pocket'
296 wallabag_v1: 'Migrar do wallabag v1'
297 wallabag_v2: 'Migrar do wallabag v2'
298 readability: 'Migrate from Readability'
299 instapaper: 'Migrate from Instapaper'
300 developer:
301 title: 'Desenvolvedores'
302 description: 'Nós também agradecemos os desenvolvedores: Docker, API, traduções, etc.'
303 create_application: 'Criar sua aplicação terceira'
304 use_docker: 'Usar o Docker para instalar o wallabag'
305 docs:
306 title: 'Documentação completa'
307 description: "Existem muitas funcionalidades no wallabag. Não hesite em ler o manual para conhecê-las e aprender como usá-las."
308 annotate: 'Anotar seu artigo'
309 export: 'Converter seu artigo em ePUB ou PDF'
310 search_filters: 'veja coo você pode encontrar um artigo usanndo o motor de busca e filtros'
311 fetching_errors: 'O que eu posso fazer quando um artigo encontra erros na recuperação?'
312 all_docs: 'E outros muitos artigos!'
313 support:
314 title: 'Suporte'
315 description: 'Se você precisa de ajuda, nós estamos aqui.'
316 github: 'No GitHub'
317 email: 'Por e-mail'
318 gitter: 'No Gitter'
319
320tag:
321 page_title: 'Tags'
322 list:
323 number_on_the_page: '{0} Não existem tags.|{1} Uma tag.|]1,Inf[ Existem %count% tags.'
324 see_untagged_entries: 'Ver entradas sem tags'
325
326import:
327 page_title: 'Importar'
328 page_description: 'Bem-vindo ao importador do wallabag. Por favo selecione o serviço do qual deseja migrar.'
329 action:
330 import_contents: 'Importar conteúdos'
331 form:
332 mark_as_read_title: 'Marcar todos como lidos?'
333 mark_as_read_label: 'Marcar todas as entradas importadas como lidas'
334 file_label: 'Arquivo'
335 save_label: 'Carregar arquivo'
336 pocket:
337 page_title: 'Importar > Pocket'
338 description: 'Com este importador você importa todos os seus dados do Pocket. O Pocket não nos permite recuperar o conteúdo de seu serviço, então o conteúdo que pode ser lido é recarregado pelo wallabag.'
339 config_missing:
340 description: 'O importador do Pocket não está configurado.'
341 admin_message: 'Você precisa definir uma %keyurls%a pocket_consumer_key%keyurle%.'
342 user_message: 'Seu administrador do servidor precisa definir uma chave de API para o Pocket.'
343 authorize_message: 'Você pode importar seus dados de sua conta do Pocket. Você somente precisa clicar no botão abaixo e autorizar a aplicação a conectar-se ao getpocket.com.'
344 connect_to_pocket: 'Conecte ao Pocket e importe os dados'
345 wallabag_v1:
346 page_title: 'Importar > Wallabag v1'
347 description: 'Com este importador você importa todos os seus artigos do wallabag v1. Na sua página de configuração, clique em "JSON export" na opção "Export your wallabag data". Você irá criar um arquivo "wallabag-export-1-xxxx-xx-xx.json".'
348 how_to: 'Por favor, selecione seu exportador wallabag e clique no botão abaixo para carregar e importar.'
349 wallabag_v2:
350 page_title: 'Importar > Wallabag v2'
351 description: 'Com este importador você importa todos os seus artigos do wallabag v2. Vá em Todos os artigos e então, na barra lateral de exportação, clique em "JSON". Você irá criar um arquivo "All articles.json".'
352 readability:
353 page_title: 'Importar > Readability'
354 description: 'Este importador pode importar todos os artigos do Readability. Nas página ferramentas (https://www.readability.com/tools/), clique em "Export your data" na seção "Data Export". Você receberá um e-mail para fazer o download de um json (que de fato não termina com .json).'
355 how_to: 'Por favor, selecione sua exportação do Readability e clique no botão abaixo para importá-la.'
356 worker:
357 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 é:"
358 firefox:
359 page_title: 'Importar > Firefox'
360 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."
361 how_to: "Por favor, escolha o arquivo de backup dos favoritos e clique no botão abaixo para importá-lo. Note que o processo pode demorar até que todos os artigos tenham sido copiados."
362 chrome:
363 page_title: 'Importar > Chrome'
364 description: "Com este importador você importa todos os favoritos de seu Chrome. A localização do arquivo depende de seu sistema operacional: <ul><li>Em Linux, vá para o diretório <code>~/.config/chromium/Default/</code></li><li>Em Windows, ele deve estar em <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>Em OS X, ele deve estar em <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Uma vez que você pegou o arquivo, copie-o para algum lugar que você o encontre.<em><br>Note que se você possui o Chromium ao invés do Chrome, você precisa corrigir os caminhos.</em></p>"
365 how_to: "Por favor, escolha o arquivo de backup dos favoritos e clique no botão abaixo para importá-lo. Note que o processo pode demorar até que todos os artigos tenham sido copiados."
366 instapaper:
367 page_title: 'Importar > Instapaper'
368 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").'
369 how_to: 'Por favor, selecione sua exportação do seu Instapaper e clique no botão abaixo para importá-la.'
370
371developer:
372 page_title: 'Desenvolvedor'
373 welcome_message: 'Bem-vindo a API do wallabag'
374 documentation: 'Documentação'
375 how_to_first_app: 'Como criar minha primeira aplicação'
376 full_documentation: 'Ver a documentação completa da API'
377 list_methods: 'Lista de métodos da API'
378 clients:
379 title: 'Clientes'
380 create_new: 'Criar um novo cliente'
381 existing_clients:
382 title: 'Clientes existentes'
383 field_id: 'ID do cliente'
384 field_secret: 'Chave do cliente'
385 field_uris: 'URIs de redirecionamento'
386 field_grant_types: 'Tipo permitido'
387 no_client: 'Nenhum cliente até agora.'
388 remove:
389 warn_message_1: 'Você tem permissão pare remover este cliente. Esta ação é IRREVERSÍVEL !'
390 warn_message_2: 'Se você remover isso, todo o aplicativo configurado com este cliente não poderá se autenticar no seu wallabag.'
391 action: 'Remover este cliente'
392 client:
393 page_title: 'Desenvolvedor > Novo cliente'
394 page_description: 'Você está prestes a criar um novo cliente. Por favor preencha o campo abaixo para a URI de redirecionamento de sua aplicação.'
395 form:
396 name_label: 'Nome do cliente'
397 redirect_uris_label: 'URIs de redirecionamento'
398 save_label: 'Criar um novo cliente'
399 action_back: 'Voltar'
400 client_parameter:
401 page_title: 'Desenvolvedor > Parâmetros de clientes'
402 page_description: 'Aqui estão os parâmetros de seus clientes.'
403 field_name: 'Nome do cliente'
404 field_id: 'ID do cliente'
405 field_secret: 'Chave do cliente'
406 back: 'Voltar'
407 read_howto: 'Leia o how-to "Criar minha primeira aplicação"'
408 howto:
409 page_title: 'Desenvolvedor > Criar minha primeira aplicação'
410 description:
411 paragraph_1: 'Os seguintes comandos fazem uso da <a href="https://github.com/jkbrzt/httpie">biblioteca HTTPie</a>. Tenha certeza que ela está instalada em seu servidor antes de usá-la.'
412 paragraph_2: 'Você precisa de um token para a comunicação entre sua aplicação terceira e a API do wallabag.'
413 paragraph_3: 'Para criar este token, você precisa <a href="%link%">criar um novo cliente</a>.'
414 paragraph_4: 'Agora, crie seu token (altere client_id, client_secret, username e password com os valores corretos):'
415 paragraph_5: 'A API pode retornar uma resposta como essa:'
416 paragraph_6: 'O access_token é utilizável para fazer uma chamada para o endpoint da API. Por exemplo:'
417 paragraph_7: 'Esta chamada pode retornar todas as entradas de seu usuário.'
418 paragraph_8: 'Se você deseja ver todos os endpoints da API, dê uma olhada <a href="%link%">em nossa documentação da API</a>.'
419 back: 'Voltar'
420
421user:
422 page_title: 'Gerenciamento de Usuários'
423 new_user: 'Criar um novo usuário'
424 edit_user: 'Editar um usuário existente'
425 description: 'Aqui você gerencia todos os usuários (cria, edita e apaga)'
426 list:
427 actions: 'Ações'
428 edit_action: 'Editar'
429 yes: 'Sim'
430 no: 'Não'
431 create_new_one: 'Criar um novo usuário'
432 form:
433 username_label: 'Nome de Usuário'
434 name_label: 'Nome'
435 password_label: 'Senha'
436 repeat_new_password_label: 'Repita a nova senha'
437 plain_password_label: '????'
438 email_label: 'E-mail'
439 enabled_label: 'Habilitado'
440 locked_label: 'Travado'
441 last_login_label: 'Último login'
442 twofactor_label: 'Autenticação de dois passos'
443 save: 'Salvar'
444 delete: 'Apagar'
445 delete_confirm: 'Tem certeza?'
446 back_to_list: 'Voltar para a lista'
447
448flashes:
449 config:
450 notice:
451 config_saved: 'Configiração salva. Alguns parâmetros podem ser considerados depois da desconexão.'
452 password_updated: 'Senha atualizada'
453 password_not_updated_demo: 'Em modo de demonstração, você não pode alterar a senha deste usuário.'
454 rss_updated: 'Informação de RSS atualizada'
455 tagging_rules_updated: 'Regras de tags atualizadas'
456 tagging_rules_deleted: 'Regra de tag apagada'
457 rss_token_updated: 'Token RSS atualizado'
458 entry:
459 notice:
460 entry_already_saved: 'Entrada já foi salva em %date%'
461 entry_saved: 'Entrada salva'
462 entry_saved_failed: 'Failed to save entry'
463 entry_updated: 'Entrada atualizada'
464 entry_reloaded: 'Entrada recarregada'
465 entry_reloaded_failed: 'Falha em recarregar a entrada'
466 entry_archived: 'Entrada arquivada'
467 entry_unarchived: 'Entrada desarquivada'
468 entry_starred: 'Entrada destacada'
469 entry_unstarred: 'Entrada não destacada'
470 entry_deleted: 'Entrada apagada'
471 tag:
472 notice:
473 tag_added: 'Tag adicionada'
474 import:
475 notice:
476 failed: 'Importação falhou, por favor tente novamente.'
477 failed_on_file: 'Erro ao processar a importação. Por favor verifique seu arquivo de importação.'
478 summary: 'relatório de importação: %imported% importados, %skipped% já existem.'
479 summary_with_queue: 'Importar sumáario: %queued% agendados.'
480 error:
481 redis_enabled_not_installed: 'O Redis está habilitado para importação assíncrona mas parece que <u>não podemos nos conectar nele</u>. Por favor verifique as configurações do Redis.'
482 rabbit_enabled_not_installed: 'O RabbitMQ está habilitado para importação assíncrona mas parece que <u>não podemos nos conectar nele</u>. Por favor verifique as configurações do RabbitMQ.'
483 developer:
484 notice:
485 client_created: 'Novo cliente criado.'
486 client_deleted: 'Cliente removido'
487 user:
488 notice:
489 added: 'Usuário "%username%" adicionado'
490 updated: 'Usuário "%username%" atualizado'
491 deleted: 'Usuário "%username%" removido'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index 070abe27..50f1b6a2 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -150,7 +150,7 @@ entry:
150 # starred: 'Starred entries' 150 # starred: 'Starred entries'
151 # archived: 'Archived entries' 151 # archived: 'Archived entries'
152 # filtered: 'Filtered entries' 152 # filtered: 'Filtered entries'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 156 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'Informație RSS actualizată' 472 rss_updated: 'Informație RSS actualizată'
473 # tagging_rules_updated: 'Tagging rules updated' 473 # tagging_rules_updated: 'Tagging rules updated'
474 # tagging_rules_deleted: 'Tagging rule deleted' 474 # tagging_rules_deleted: 'Tagging rule deleted'
475 # user_added: 'User "%username%" added'
476 # rss_token_updated: 'RSS token updated' 475 # rss_token_updated: 'RSS token updated'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 7679b32a..07939ebc 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -150,7 +150,7 @@ entry:
150 # starred: 'Starred entries' 150 # starred: 'Starred entries'
151 # archived: 'Archived entries' 151 # archived: 'Archived entries'
152 # filtered: 'Filtered entries' 152 # filtered: 'Filtered entries'
153 # filtered_tags: 'Filtered by tags' 153 # filtered_tags: 'Filtered by tags:'
154 # untagged: 'Untagged entries' 154 # untagged: 'Untagged entries'
155 list: 155 list:
156 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' 156 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
@@ -472,7 +472,6 @@ flashes:
472 rss_updated: 'RSS bilgiler güncellendi' 472 rss_updated: 'RSS bilgiler güncellendi'
473 tagging_rules_updated: 'Tagging rules updated' 473 tagging_rules_updated: 'Tagging rules updated'
474 tagging_rules_deleted: 'Tagging rule deleted' 474 tagging_rules_deleted: 'Tagging rule deleted'
475 user_added: 'User "%username%" added'
476 rss_token_updated: 'RSS token updated' 475 rss_token_updated: 'RSS token updated'
477 # annotations_reset: Annotations reset 476 # annotations_reset: Annotations reset
478 # tags_reset: Tags reset 477 # tags_reset: Tags reset
diff --git a/src/Wallabag/CoreBundle/Resources/translations/validators.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/validators.fr.yml
index 7ecb4acf..2d5eca29 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/validators.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/validators.fr.yml
@@ -1,6 +1,6 @@
1validator: 1validator:
2 password_must_match: 'Les deux mots de passe doivent être les mêmes' 2 password_must_match: "Les deux mots de passe doivent être les mêmes"
3 password_too_short: 'Le mot de passe doit contenir au moins 8 caractères' 3 password_too_short: "Le mot de passe doit contenir au moins 8 caractères"
4 password_wrong_value: 'Votre mot de passe actuel est faux' 4 password_wrong_value: "Votre mot de passe actuel est faux"
5 item_per_page_too_high: "Ca ne va pas plaire à l'application" 5 item_per_page_too_high: "Ça ne va pas plaire à lapplication"
6 rss_limit_too_hight: "Ca ne va pas plaire à l'application" 6 rss_limit_too_hight: "Ça ne va pas plaire à lapplication"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/validators.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/validators.pt.yml
new file mode 100644
index 00000000..49890830
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/translations/validators.pt.yml
@@ -0,0 +1,6 @@
1validator:
2 password_must_match: 'Os campos de senha devem coincidir.'
3 password_too_short: 'A senha deve ter pelo menos 8 caracteres'
4 password_wrong_value: 'A senha atual informada está errada'
5 item_per_page_too_high: 'Certamente isso pode matar a aplicação'
6 rss_limit_too_hight: 'Certamente isso pode matar a aplicação'
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 3af88b23..5d657c7e 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,7 +1,11 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %} 1{% extends "WallabagCoreBundle::layout.html.twig" %}
2 2
3{% block title %} 3{% block title %}
4 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" %} 4 {% set currentTag = '' %}
5 {% if tag is defined %}
6 {% set currentTag = tag %}
7 {% endif %}
8 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'currentTag': currentTag} %}
5{% endblock %} 9{% endblock %}
6 10
7{% block content %} 11{% block content %}
@@ -49,19 +53,23 @@
49 <!-- Export --> 53 <!-- Export -->
50 <aside id="download-form"> 54 <aside id="download-form">
51 {% set currentRoute = app.request.attributes.get('_route') %} 55 {% set currentRoute = app.request.attributes.get('_route') %}
56 {% set currentTag = '' %}
57 {% if tag is defined %}
58 {% set currentTag = tag %}
59 {% endif %}
52 {% if currentRoute == 'homepage' %} 60 {% if currentRoute == 'homepage' %}
53 {% set currentRoute = 'unread' %} 61 {% set currentRoute = 'unread' %}
54 {% endif %} 62 {% endif %}
55 <h2>{{ 'entry.list.export_title'|trans }}</h2> 63 <h2>{{ 'entry.list.export_title'|trans }}</h2>
56 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a> 64 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a>
57 <ul> 65 <ul>
58 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %} 66 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %}
59 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %} 67 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %}
60 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %} 68 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %}
61 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %} 69 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %}
62 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %} 70 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %}
63 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %} 71 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %}
64 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %} 72 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %}
65 </ul> 73 </ul>
66 </aside> 74 </aside>
67 75
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 d1c2f203..92cabdd9 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
@@ -7,7 +7,7 @@
7{% elseif currentRoute == 'all' %} 7{% elseif currentRoute == 'all' %}
8 {{ 'entry.page_titles.filtered'|trans }} 8 {{ 'entry.page_titles.filtered'|trans }}
9{% elseif currentRoute == 'tag_entries' %} 9{% elseif currentRoute == 'tag_entries' %}
10 {{ 'entry.page_titles.filtered_tags'|trans }} 10 {{ 'entry.page_titles.filtered_tags'|trans }} {{ currentTag }}
11{% elseif currentRoute == 'untagged' %} 11{% elseif currentRoute == 'untagged' %}
12 {{ 'entry.page_titles.untagged'|trans }} 12 {{ 'entry.page_titles.untagged'|trans }}
13{% else %} 13{% else %}
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 919f94ec..1225e680 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,7 +1,11 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %} 1{% extends "WallabagCoreBundle::layout.html.twig" %}
2 2
3{% block title %} 3{% block title %}
4 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" %} 4 {% set currentTag = '' %}
5 {% if tag is defined %}
6 {% set currentTag = tag %}
7 {% endif %}
8 {% include "@WallabagCore/themes/common/Entry/_title.html.twig" with {'currentTag': currentTag} %}
5{% endblock %} 9{% endblock %}
6 10
7{% block content %} 11{% block content %}
@@ -95,18 +99,22 @@
95 <!-- Export --> 99 <!-- Export -->
96 <div id="export" class="side-nav fixed right-aligned"> 100 <div id="export" class="side-nav fixed right-aligned">
97 {% set currentRoute = app.request.attributes.get('_route') %} 101 {% set currentRoute = app.request.attributes.get('_route') %}
102 {% set currentTag = '' %}
103 {% if tag is defined %}
104 {% set currentTag = tag %}
105 {% endif %}
98 {% if currentRoute == 'homepage' %} 106 {% if currentRoute == 'homepage' %}
99 {% set currentRoute = 'unread' %} 107 {% set currentRoute = 'unread' %}
100 {% endif %} 108 {% endif %}
101 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4> 109 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4>
102 <ul> 110 <ul>
103 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %} 111 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub', 'tag' : currentTag }) }}">EPUB</a></li>{% endif %}
104 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %} 112 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi', 'tag' : currentTag }) }}">MOBI</a></li>{% endif %}
105 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %} 113 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf', 'tag' : currentTag }) }}">PDF</a></li>{% endif %}
106 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %} 114 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json', 'tag' : currentTag }) }}">JSON</a></li>{% endif %}
107 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %} 115 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv', 'tag' : currentTag }) }}">CSV</a></li>{% endif %}
108 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %} 116 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt', 'tag' : currentTag }) }}">TXT</a></li>{% endif %}
109 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %} 117 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml', 'tag' : currentTag }) }}">XML</a></li>{% endif %}
110 </ul> 118 </ul>
111 </div> 119 </div>
112 120
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php
index 2f7a906e..13f3dcb9 100644
--- a/src/Wallabag/ImportBundle/Command/ImportCommand.php
+++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php
@@ -56,6 +56,9 @@ class ImportCommand extends ContainerAwareCommand
56 case 'instapaper': 56 case 'instapaper':
57 $import = $this->getContainer()->get('wallabag_import.instapaper.import'); 57 $import = $this->getContainer()->get('wallabag_import.instapaper.import');
58 break; 58 break;
59 case 'instapaper':
60 $wallabag = $this->getContainer()->get('wallabag_import.instapaper.import');
61 break;
59 case 'v1': 62 case 'v1':
60 default: 63 default:
61 $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); 64 $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import');
diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
index ca9d18f1..961208f2 100644
--- a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
+++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php
@@ -4,7 +4,6 @@ namespace Wallabag\UserBundle\Mailer;
4 4
5use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; 5use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
6use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface; 6use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
7use Craue\ConfigBundle\Util\Config;
8 7
9/** 8/**
10 * Custom mailer for TwoFactorBundle email. 9 * Custom mailer for TwoFactorBundle email.
@@ -61,16 +60,17 @@ class AuthCodeMailer implements AuthCodeMailerInterface
61 * @param \Twig_Environment $twig 60 * @param \Twig_Environment $twig
62 * @param string $senderEmail 61 * @param string $senderEmail
63 * @param string $senderName 62 * @param string $senderName
64 * @param Config $craueConfig Craue\Config instance to get wallabag support url from database 63 * @param string $supportUrl wallabag support url
64 * @param string $wallabagUrl wallabag instance url
65 */ 65 */
66 public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $senderEmail, $senderName, Config $craueConfig) 66 public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig, $senderEmail, $senderName, $supportUrl, $wallabagUrl)
67 { 67 {
68 $this->mailer = $mailer; 68 $this->mailer = $mailer;
69 $this->twig = $twig; 69 $this->twig = $twig;
70 $this->senderEmail = $senderEmail; 70 $this->senderEmail = $senderEmail;
71 $this->senderName = $senderName; 71 $this->senderName = $senderName;
72 $this->supportUrl = $craueConfig->get('wallabag_support_url'); 72 $this->supportUrl = $supportUrl;
73 $this->wallabagUrl = $craueConfig->get('wallabag_url'); 73 $this->wallabagUrl = $wallabagUrl;
74 } 74 }
75 75
76 /** 76 /**
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml
index 8062e53f..164a25ec 100644
--- a/src/Wallabag/UserBundle/Resources/config/services.yml
+++ b/src/Wallabag/UserBundle/Resources/config/services.yml
@@ -6,7 +6,8 @@ services:
6 - "@twig" 6 - "@twig"
7 - "%scheb_two_factor.email.sender_email%" 7 - "%scheb_two_factor.email.sender_email%"
8 - "%scheb_two_factor.email.sender_name%" 8 - "%scheb_two_factor.email.sender_name%"
9 - "@craue_config" 9 - '@=service(''craue_config'').get(''wallabag_support_url'')'
10 - '@=service(''craue_config'').get(''wallabag_url'')'
10 11
11 wallabag_user.password_resetting: 12 wallabag_user.password_resetting:
12 class: Wallabag\UserBundle\EventListener\PasswordResettingListener 13 class: Wallabag\UserBundle\EventListener\PasswordResettingListener
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
index 30ab5dd9..fbc95a05 100644
--- a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
+++ b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.fr.yml
@@ -1,11 +1,11 @@
1# Two factor mail 1# Two factor mail
2auth_code: 2auth_code:
3 on: 'sur' 3 on: "sur"
4 mailer: 4 mailer:
5 subject: "Code d'authentification wallabag" 5 subject: "Code dauthentification wallabag"
6 body: 6 body:
7 hello: "Bonjour %user%," 7 hello: "Bonjour %user%,"
8 first_para: "Comme vous avez activé la double authentification sur votre compte wallabag et que vous venez de vous connecter depuis un nouvel appareil (ordinateur, téléphone, etc.), nous vous envoyons un code pour valider votre connexion." 8 first_para: "Comme vous avez activé la double authentification sur votre compte wallabag et que vous venez de vous connecter depuis un nouvel appareil (ordinateur, téléphone, etc.), nous vous envoyons un code pour valider votre connexion."
9 second_para: "Voici le code à renseigner :" 9 second_para: "Voici le code à renseigner :"
10 support: "Si vous avez un problème de connexion, n'hésitez pas à contacter le support :" 10 support: "Si vous avez un problème de connexion, nhésitez pas à contacter le support :"
11 signature: "L'équipe wallabag" 11 signature: "Léquipe wallabag"