aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/ApiBundle/Controller/EntryRestController.php367
-rw-r--r--src/Wallabag/ApiBundle/Controller/TagRestController.php171
-rw-r--r--src/Wallabag/ApiBundle/Controller/WallabagRestController.php522
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing_rest.yml7
-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/Repository/EntryRepository.php2
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml726
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml492
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml2
-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/ImportBundle/Resources/config/services.yml1
-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
31 files changed, 1493 insertions, 939 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/EntryRestController.php b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
new file mode 100644
index 00000000..24fa7b3b
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Controller/EntryRestController.php
@@ -0,0 +1,367 @@
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;
13
14class EntryRestController extends WallabagRestController
15{
16 /**
17 * Check if an entry exist by url.
18 *
19 * @ApiDoc(
20 * parameters={
21 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
22 * {"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"}
23 * }
24 * )
25 *
26 * @return JsonResponse
27 */
28 public function getEntriesExistsAction(Request $request)
29 {
30 $this->validateAuthentication();
31
32 $urls = $request->query->get('urls', []);
33
34 // handle multiple urls first
35 if (!empty($urls)) {
36 $results = [];
37 foreach ($urls as $url) {
38 $res = $this->getDoctrine()
39 ->getRepository('WallabagCoreBundle:Entry')
40 ->findByUrlAndUserId($url, $this->getUser()->getId());
41
42 $results[$url] = false === $res ? false : true;
43 }
44
45 $json = $this->get('serializer')->serialize($results, 'json');
46
47 return (new JsonResponse())->setJson($json);
48 }
49
50 // let's see if it is a simple url?
51 $url = $request->query->get('url', '');
52
53 if (empty($url)) {
54 throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
55 }
56
57 $res = $this->getDoctrine()
58 ->getRepository('WallabagCoreBundle:Entry')
59 ->findByUrlAndUserId($url, $this->getUser()->getId());
60
61 $exists = false === $res ? false : true;
62
63 $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
64
65 return (new JsonResponse())->setJson($json);
66 }
67
68 /**
69 * Retrieve all entries. It could be filtered by many options.
70 *
71 * @ApiDoc(
72 * parameters={
73 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
74 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
75 * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
76 * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
77 * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
78 * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
79 * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
80 * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
81 * }
82 * )
83 *
84 * @return JsonResponse
85 */
86 public function getEntriesAction(Request $request)
87 {
88 $this->validateAuthentication();
89
90 $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
91 $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
92 $sort = $request->query->get('sort', 'created');
93 $order = $request->query->get('order', 'desc');
94 $page = (int) $request->query->get('page', 1);
95 $perPage = (int) $request->query->get('perPage', 30);
96 $tags = $request->query->get('tags', '');
97 $since = $request->query->get('since', 0);
98
99 $pager = $this->getDoctrine()
100 ->getRepository('WallabagCoreBundle:Entry')
101 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
102
103 $pager->setCurrentPage($page);
104 $pager->setMaxPerPage($perPage);
105
106 $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
107 $paginatedCollection = $pagerfantaFactory->createRepresentation(
108 $pager,
109 new Route(
110 'api_get_entries',
111 [
112 'archive' => $isArchived,
113 'starred' => $isStarred,
114 'sort' => $sort,
115 'order' => $order,
116 'page' => $page,
117 'perPage' => $perPage,
118 'tags' => $tags,
119 'since' => $since,
120 ],
121 UrlGeneratorInterface::ABSOLUTE_URL
122 )
123 );
124
125 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
126
127 return (new JsonResponse())->setJson($json);
128 }
129
130 /**
131 * Retrieve a single entry.
132 *
133 * @ApiDoc(
134 * requirements={
135 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
136 * }
137 * )
138 *
139 * @return JsonResponse
140 */
141 public function getEntryAction(Entry $entry)
142 {
143 $this->validateAuthentication();
144 $this->validateUserAccess($entry->getUser()->getId());
145
146 $json = $this->get('serializer')->serialize($entry, 'json');
147
148 return (new JsonResponse())->setJson($json);
149 }
150
151 /**
152 * Create an entry.
153 *
154 * @ApiDoc(
155 * parameters={
156 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
157 * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
158 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
159 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
160 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
161 * }
162 * )
163 *
164 * @return JsonResponse
165 */
166 public function postEntriesAction(Request $request)
167 {
168 $this->validateAuthentication();
169
170 $url = $request->request->get('url');
171 $title = $request->request->get('title');
172 $isArchived = $request->request->get('archive');
173 $isStarred = $request->request->get('starred');
174
175 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
176
177 if (false === $entry) {
178 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
179 new Entry($this->getUser()),
180 $url
181 );
182 }
183
184 if (!is_null($title)) {
185 $entry->setTitle($title);
186 }
187
188 $tags = $request->request->get('tags', '');
189 if (!empty($tags)) {
190 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
191 }
192
193 if (!is_null($isStarred)) {
194 $entry->setStarred((bool) $isStarred);
195 }
196
197 if (!is_null($isArchived)) {
198 $entry->setArchived((bool) $isArchived);
199 }
200
201 $em = $this->getDoctrine()->getManager();
202 $em->persist($entry);
203
204 $em->flush();
205
206 $json = $this->get('serializer')->serialize($entry, 'json');
207
208 return (new JsonResponse())->setJson($json);
209 }
210
211 /**
212 * Change several properties of an entry.
213 *
214 * @ApiDoc(
215 * requirements={
216 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
217 * },
218 * parameters={
219 * {"name"="title", "dataType"="string", "required"=false},
220 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
221 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
222 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
223 * }
224 * )
225 *
226 * @return JsonResponse
227 */
228 public function patchEntriesAction(Entry $entry, Request $request)
229 {
230 $this->validateAuthentication();
231 $this->validateUserAccess($entry->getUser()->getId());
232
233 $title = $request->request->get('title');
234 $isArchived = $request->request->get('archive');
235 $isStarred = $request->request->get('starred');
236
237 if (!is_null($title)) {
238 $entry->setTitle($title);
239 }
240
241 if (!is_null($isArchived)) {
242 $entry->setArchived((bool) $isArchived);
243 }
244
245 if (!is_null($isStarred)) {
246 $entry->setStarred((bool) $isStarred);
247 }
248
249 $tags = $request->request->get('tags', '');
250 if (!empty($tags)) {
251 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
252 }
253
254 $em = $this->getDoctrine()->getManager();
255 $em->flush();
256
257 $json = $this->get('serializer')->serialize($entry, 'json');
258
259 return (new JsonResponse())->setJson($json);
260 }
261
262 /**
263 * Delete **permanently** an entry.
264 *
265 * @ApiDoc(
266 * requirements={
267 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
268 * }
269 * )
270 *
271 * @return JsonResponse
272 */
273 public function deleteEntriesAction(Entry $entry)
274 {
275 $this->validateAuthentication();
276 $this->validateUserAccess($entry->getUser()->getId());
277
278 $em = $this->getDoctrine()->getManager();
279 $em->remove($entry);
280 $em->flush();
281
282 $json = $this->get('serializer')->serialize($entry, 'json');
283
284 return (new JsonResponse())->setJson($json);
285 }
286
287 /**
288 * Retrieve all tags for an entry.
289 *
290 * @ApiDoc(
291 * requirements={
292 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
293 * }
294 * )
295 *
296 * @return JsonResponse
297 */
298 public function getEntriesTagsAction(Entry $entry)
299 {
300 $this->validateAuthentication();
301 $this->validateUserAccess($entry->getUser()->getId());
302
303 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
304
305 return (new JsonResponse())->setJson($json);
306 }
307
308 /**
309 * Add one or more tags to an entry.
310 *
311 * @ApiDoc(
312 * requirements={
313 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
314 * },
315 * parameters={
316 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
317 * }
318 * )
319 *
320 * @return JsonResponse
321 */
322 public function postEntriesTagsAction(Request $request, Entry $entry)
323 {
324 $this->validateAuthentication();
325 $this->validateUserAccess($entry->getUser()->getId());
326
327 $tags = $request->request->get('tags', '');
328 if (!empty($tags)) {
329 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
330 }
331
332 $em = $this->getDoctrine()->getManager();
333 $em->persist($entry);
334 $em->flush();
335
336 $json = $this->get('serializer')->serialize($entry, 'json');
337
338 return (new JsonResponse())->setJson($json);
339 }
340
341 /**
342 * Permanently remove one tag for an entry.
343 *
344 * @ApiDoc(
345 * requirements={
346 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
347 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
348 * }
349 * )
350 *
351 * @return JsonResponse
352 */
353 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
354 {
355 $this->validateAuthentication();
356 $this->validateUserAccess($entry->getUser()->getId());
357
358 $entry->removeTag($tag);
359 $em = $this->getDoctrine()->getManager();
360 $em->persist($entry);
361 $em->flush();
362
363 $json = $this->get('serializer')->serialize($entry, 'json');
364
365 return (new JsonResponse())->setJson($json);
366 }
367}
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 9997913d..e927a890 100644
--- a/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
@@ -3,19 +3,12 @@
3namespace Wallabag\ApiBundle\Controller; 3namespace Wallabag\ApiBundle\Controller;
4 4
5use FOS\RestBundle\Controller\FOSRestController; 5use FOS\RestBundle\Controller\FOSRestController;
6use Hateoas\Configuration\Route;
7use Hateoas\Representation\Factory\PagerfantaFactory;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpFoundation\JsonResponse;
11use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
12use Symfony\Component\Security\Core\Exception\AccessDeniedException; 6use Symfony\Component\Security\Core\Exception\AccessDeniedException;
13use Wallabag\CoreBundle\Entity\Entry; 7use Wallabag\CoreBundle\Entity\Entry;
14use Wallabag\CoreBundle\Entity\Tag;
15 8
16class WallabagRestController extends FOSRestController 9class WallabagRestController extends FOSRestController
17{ 10{
18 private function validateAuthentication() 11 protected function validateAuthentication()
19 { 12 {
20 if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) { 13 if (false === $this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY')) {
21 throw new AccessDeniedException(); 14 throw new AccessDeniedException();
@@ -23,523 +16,12 @@ class WallabagRestController extends FOSRestController
23 } 16 }
24 17
25 /** 18 /**
26 * Check if an entry exist by url.
27 *
28 * @ApiDoc(
29 * parameters={
30 * {"name"="url", "dataType"="string", "required"=true, "format"="An url", "description"="Url to check if it exists"},
31 * {"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"}
32 * }
33 * )
34 *
35 * @return JsonResponse
36 */
37 public function getEntriesExistsAction(Request $request)
38 {
39 $this->validateAuthentication();
40
41 $urls = $request->query->get('urls', []);
42
43 // handle multiple urls first
44 if (!empty($urls)) {
45 $results = [];
46 foreach ($urls as $url) {
47 $res = $this->getDoctrine()
48 ->getRepository('WallabagCoreBundle:Entry')
49 ->findByUrlAndUserId($url, $this->getUser()->getId());
50
51 $results[$url] = false === $res ? false : true;
52 }
53
54 $json = $this->get('serializer')->serialize($results, 'json');
55
56 return (new JsonResponse())->setJson($json);
57 }
58
59 // let's see if it is a simple url?
60 $url = $request->query->get('url', '');
61
62 if (empty($url)) {
63 throw $this->createAccessDeniedException('URL is empty?, logged user id: '.$this->getUser()->getId());
64 }
65
66 $res = $this->getDoctrine()
67 ->getRepository('WallabagCoreBundle:Entry')
68 ->findByUrlAndUserId($url, $this->getUser()->getId());
69
70 $exists = false === $res ? false : true;
71
72 $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
73
74 return (new JsonResponse())->setJson($json);
75 }
76
77 /**
78 * Retrieve all entries. It could be filtered by many options.
79 *
80 * @ApiDoc(
81 * parameters={
82 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by archived status."},
83 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0, all entries by default", "description"="filter by starred status."},
84 * {"name"="sort", "dataType"="string", "required"=false, "format"="'created' or 'updated', default 'created'", "description"="sort entries by date."},
85 * {"name"="order", "dataType"="string", "required"=false, "format"="'asc' or 'desc', default 'desc'", "description"="order of sort."},
86 * {"name"="page", "dataType"="integer", "required"=false, "format"="default '1'", "description"="what page you want."},
87 * {"name"="perPage", "dataType"="integer", "required"=false, "format"="default'30'", "description"="results per page."},
88 * {"name"="tags", "dataType"="string", "required"=false, "format"="api,rest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
89 * {"name"="since", "dataType"="integer", "required"=false, "format"="default '0'", "description"="The timestamp since when you want entries updated."},
90 * }
91 * )
92 *
93 * @return JsonResponse
94 */
95 public function getEntriesAction(Request $request)
96 {
97 $this->validateAuthentication();
98
99 $isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
100 $isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
101 $sort = $request->query->get('sort', 'created');
102 $order = $request->query->get('order', 'desc');
103 $page = (int) $request->query->get('page', 1);
104 $perPage = (int) $request->query->get('perPage', 30);
105 $tags = $request->query->get('tags', '');
106 $since = $request->query->get('since', 0);
107
108 $pager = $this->getDoctrine()
109 ->getRepository('WallabagCoreBundle:Entry')
110 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order, $since, $tags);
111
112 $pager->setCurrentPage($page);
113 $pager->setMaxPerPage($perPage);
114
115 $pagerfantaFactory = new PagerfantaFactory('page', 'perPage');
116 $paginatedCollection = $pagerfantaFactory->createRepresentation(
117 $pager,
118 new Route(
119 'api_get_entries',
120 [
121 'archive' => $isArchived,
122 'starred' => $isStarred,
123 'sort' => $sort,
124 'order' => $order,
125 'page' => $page,
126 'perPage' => $perPage,
127 'tags' => $tags,
128 'since' => $since,
129 ],
130 UrlGeneratorInterface::ABSOLUTE_URL
131 )
132 );
133
134 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
135
136 return (new JsonResponse())->setJson($json);
137 }
138
139 /**
140 * Retrieve a single entry.
141 *
142 * @ApiDoc(
143 * requirements={
144 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
145 * }
146 * )
147 *
148 * @return JsonResponse
149 */
150 public function getEntryAction(Entry $entry)
151 {
152 $this->validateAuthentication();
153 $this->validateUserAccess($entry->getUser()->getId());
154
155 $json = $this->get('serializer')->serialize($entry, 'json');
156
157 return (new JsonResponse())->setJson($json);
158 }
159
160 /**
161 * Create an entry.
162 *
163 * @ApiDoc(
164 * parameters={
165 * {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
166 * {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
167 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
168 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already starred"},
169 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="entry already archived"},
170 * }
171 * )
172 *
173 * @return JsonResponse
174 */
175 public function postEntriesAction(Request $request)
176 {
177 $this->validateAuthentication();
178
179 $url = $request->request->get('url');
180 $title = $request->request->get('title');
181 $isArchived = $request->request->get('archive');
182 $isStarred = $request->request->get('starred');
183
184 $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
185
186 if (false === $entry) {
187 $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
188 new Entry($this->getUser()),
189 $url
190 );
191 }
192
193 if (!is_null($title)) {
194 $entry->setTitle($title);
195 }
196
197 $tags = $request->request->get('tags', '');
198 if (!empty($tags)) {
199 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
200 }
201
202 if (!is_null($isStarred)) {
203 $entry->setStarred((bool) $isStarred);
204 }
205
206 if (!is_null($isArchived)) {
207 $entry->setArchived((bool) $isArchived);
208 }
209
210 $em = $this->getDoctrine()->getManager();
211 $em->persist($entry);
212
213 $em->flush();
214
215 $json = $this->get('serializer')->serialize($entry, 'json');
216
217 return (new JsonResponse())->setJson($json);
218 }
219
220 /**
221 * Change several properties of an entry.
222 *
223 * @ApiDoc(
224 * requirements={
225 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
226 * },
227 * parameters={
228 * {"name"="title", "dataType"="string", "required"=false},
229 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
230 * {"name"="archive", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="archived the entry."},
231 * {"name"="starred", "dataType"="integer", "required"=false, "format"="1 or 0", "description"="starred the entry."},
232 * }
233 * )
234 *
235 * @return JsonResponse
236 */
237 public function patchEntriesAction(Entry $entry, Request $request)
238 {
239 $this->validateAuthentication();
240 $this->validateUserAccess($entry->getUser()->getId());
241
242 $title = $request->request->get('title');
243 $isArchived = $request->request->get('archive');
244 $isStarred = $request->request->get('starred');
245
246 if (!is_null($title)) {
247 $entry->setTitle($title);
248 }
249
250 if (!is_null($isArchived)) {
251 $entry->setArchived((bool) $isArchived);
252 }
253
254 if (!is_null($isStarred)) {
255 $entry->setStarred((bool) $isStarred);
256 }
257
258 $tags = $request->request->get('tags', '');
259 if (!empty($tags)) {
260 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
261 }
262
263 $em = $this->getDoctrine()->getManager();
264 $em->flush();
265
266 $json = $this->get('serializer')->serialize($entry, 'json');
267
268 return (new JsonResponse())->setJson($json);
269 }
270
271 /**
272 * Delete **permanently** an entry.
273 *
274 * @ApiDoc(
275 * requirements={
276 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
277 * }
278 * )
279 *
280 * @return JsonResponse
281 */
282 public function deleteEntriesAction(Entry $entry)
283 {
284 $this->validateAuthentication();
285 $this->validateUserAccess($entry->getUser()->getId());
286
287 $em = $this->getDoctrine()->getManager();
288 $em->remove($entry);
289 $em->flush();
290
291 $json = $this->get('serializer')->serialize($entry, 'json');
292
293 return (new JsonResponse())->setJson($json);
294 }
295
296 /**
297 * Retrieve all tags for an entry.
298 *
299 * @ApiDoc(
300 * requirements={
301 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
302 * }
303 * )
304 *
305 * @return JsonResponse
306 */
307 public function getEntriesTagsAction(Entry $entry)
308 {
309 $this->validateAuthentication();
310 $this->validateUserAccess($entry->getUser()->getId());
311
312 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
313
314 return (new JsonResponse())->setJson($json);
315 }
316
317 /**
318 * Add one or more tags to an entry.
319 *
320 * @ApiDoc(
321 * requirements={
322 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
323 * },
324 * parameters={
325 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
326 * }
327 * )
328 *
329 * @return JsonResponse
330 */
331 public function postEntriesTagsAction(Request $request, Entry $entry)
332 {
333 $this->validateAuthentication();
334 $this->validateUserAccess($entry->getUser()->getId());
335
336 $tags = $request->request->get('tags', '');
337 if (!empty($tags)) {
338 $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
339 }
340
341 $em = $this->getDoctrine()->getManager();
342 $em->persist($entry);
343 $em->flush();
344
345 $json = $this->get('serializer')->serialize($entry, 'json');
346
347 return (new JsonResponse())->setJson($json);
348 }
349
350 /**
351 * Permanently remove one tag for an entry.
352 *
353 * @ApiDoc(
354 * requirements={
355 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
356 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
357 * }
358 * )
359 *
360 * @return JsonResponse
361 */
362 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
363 {
364 $this->validateAuthentication();
365 $this->validateUserAccess($entry->getUser()->getId());
366
367 $entry->removeTag($tag);
368 $em = $this->getDoctrine()->getManager();
369 $em->persist($entry);
370 $em->flush();
371
372 $json = $this->get('serializer')->serialize($entry, 'json');
373
374 return (new JsonResponse())->setJson($json);
375 }
376
377 /**
378 * Retrieve all tags.
379 *
380 * @ApiDoc()
381 *
382 * @return JsonResponse
383 */
384 public function getTagsAction()
385 {
386 $this->validateAuthentication();
387
388 $tags = $this->getDoctrine()
389 ->getRepository('WallabagCoreBundle:Tag')
390 ->findAllTags($this->getUser()->getId());
391
392 $json = $this->get('serializer')->serialize($tags, 'json');
393
394 return (new JsonResponse())->setJson($json);
395 }
396
397 /**
398 * Permanently remove one tag from **every** entry.
399 *
400 * @ApiDoc(
401 * requirements={
402 * {"name"="tag", "dataType"="string", "required"=true, "requirement"="\w+", "description"="Tag as a string"}
403 * }
404 * )
405 *
406 * @return JsonResponse
407 */
408 public function deleteTagLabelAction(Request $request)
409 {
410 $this->validateAuthentication();
411 $label = $request->request->get('tag', '');
412
413 $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($label);
414
415 if (empty($tag)) {
416 throw $this->createNotFoundException('Tag not found');
417 }
418
419 $this->getDoctrine()
420 ->getRepository('WallabagCoreBundle:Entry')
421 ->removeTag($this->getUser()->getId(), $tag);
422
423 $this->cleanOrphanTag($tag);
424
425 $json = $this->get('serializer')->serialize($tag, 'json');
426
427 return (new JsonResponse())->setJson($json);
428 }
429
430 /**
431 * Permanently remove some tags from **every** entry.
432 *
433 * @ApiDoc(
434 * requirements={
435 * {"name"="tags", "dataType"="string", "required"=true, "format"="tag1,tag2", "description"="Tags as strings (comma splitted)"}
436 * }
437 * )
438 *
439 * @return JsonResponse
440 */
441 public function deleteTagsLabelAction(Request $request)
442 {
443 $this->validateAuthentication();
444
445 $tagsLabels = $request->request->get('tags', '');
446
447 $tags = [];
448
449 foreach (explode(',', $tagsLabels) as $tagLabel) {
450 $tagEntity = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneByLabel($tagLabel);
451
452 if (!empty($tagEntity)) {
453 $tags[] = $tagEntity;
454 }
455 }
456
457 if (empty($tags)) {
458 throw $this->createNotFoundException('Tags not found');
459 }
460
461 $this->getDoctrine()
462 ->getRepository('WallabagCoreBundle:Entry')
463 ->removeTags($this->getUser()->getId(), $tags);
464
465 $this->cleanOrphanTag($tags);
466
467 $json = $this->get('serializer')->serialize($tags, 'json');
468
469 return (new JsonResponse())->setJson($json);
470 }
471
472 /**
473 * Permanently remove one tag from **every** entry.
474 *
475 * @ApiDoc(
476 * requirements={
477 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
478 * }
479 * )
480 *
481 * @return JsonResponse
482 */
483 public function deleteTagAction(Tag $tag)
484 {
485 $this->validateAuthentication();
486
487 $this->getDoctrine()
488 ->getRepository('WallabagCoreBundle:Entry')
489 ->removeTag($this->getUser()->getId(), $tag);
490
491 $this->cleanOrphanTag($tag);
492
493 $json = $this->get('serializer')->serialize($tag, 'json');
494
495 return (new JsonResponse())->setJson($json);
496 }
497
498 /**
499 * Retrieve version number.
500 *
501 * @ApiDoc()
502 *
503 * @return JsonResponse
504 */
505 public function getVersionAction()
506 {
507 $version = $this->container->getParameter('wallabag_core.version');
508
509 $json = $this->get('serializer')->serialize($version, 'json');
510
511 return (new JsonResponse())->setJson($json);
512 }
513
514 /**
515 * Remove orphan tag in case no entries are associated to it.
516 *
517 * @param Tag|array $tags
518 */
519 private function cleanOrphanTag($tags)
520 {
521 if (!is_array($tags)) {
522 $tags = [$tags];
523 }
524
525 $em = $this->getDoctrine()->getManager();
526
527 foreach ($tags as $tag) {
528 if (count($tag->getEntries()) === 0) {
529 $em->remove($tag);
530 }
531 }
532
533 $em->flush();
534 }
535
536 /**
537 * Validate that the first id is equal to the second one. 19 * Validate that the first id is equal to the second one.
538 * If not, throw exception. It means a user try to access information from an other user. 20 * If not, throw exception. It means a user try to access information from an other user.
539 * 21 *
540 * @param int $requestUserId User id from the requested source 22 * @param int $requestUserId User id from the requested source
541 */ 23 */
542 private function validateUserAccess($requestUserId) 24 protected function validateUserAccess($requestUserId)
543 { 25 {
544 $user = $this->get('security.token_storage')->getToken()->getUser(); 26 $user = $this->get('security.token_storage')->getToken()->getUser();
545 if ($requestUserId != $user->getId()) { 27 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 5f43f971..c1af9e02 100644
--- a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
+++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
@@ -1,4 +1,9 @@
1entries: 1entries:
2 type: rest 2 type: rest
3 resource: "WallabagApiBundle:WallabagRest" 3 resource: "WallabagApiBundle:EntryRest"
4 name_prefix: api_
5
6tags:
7 type: rest
8 resource: "WallabagApiBundle:TagRest"
4 name_prefix: api_ 9 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 5acc6852..707f3bbe 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/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index cd2b47b9..4f03ae0f 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -22,7 +22,7 @@ class EntryRepository extends EntityRepository
22 return $this->createQueryBuilder('e') 22 return $this->createQueryBuilder('e')
23 ->leftJoin('e.user', 'u') 23 ->leftJoin('e.user', 'u')
24 ->andWhere('u.id = :userId')->setParameter('userId', $userId) 24 ->andWhere('u.id = :userId')->setParameter('userId', $userId)
25 ->orderBy('e.id', 'desc') 25 ->orderBy('e.createdAt', 'desc')
26 ; 26 ;
27 } 27 }
28 28
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 614488a6..90a2419e 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 714ced14..6ca7e459 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -137,7 +137,7 @@ entry:
137 # starred: 'Starred entries' 137 # starred: 'Starred entries'
138 # archived: 'Archived entries' 138 # archived: 'Archived entries'
139 # filtered: 'Filtered entries' 139 # filtered: 'Filtered entries'
140 # filtered_tags: 'Filtered by tags' 140 # filtered_tags: 'Filtered by tags:'
141 # untagged: 'Untagged entries' 141 # untagged: 'Untagged entries'
142 list: 142 list:
143 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 143 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index 57e49f84..8fd1d82a 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Favorisierte Einträge' 137 starred: 'Favorisierte Einträge'
138 archived: 'Archivierte Einträge' 138 archived: 'Archivierte Einträge'
139 filtered: 'Gefilterte Einträge' 139 filtered: 'Gefilterte Einträge'
140 filtered_tags: 'Gefiltert nach Tags' 140 filtered_tags: 'Gefiltert nach Tags:'
141 untagged: 'Nicht getaggte Einträge' 141 untagged: 'Nicht getaggte Einträge'
142 list: 142 list:
143 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.' 143 number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 4a59c75e..02f56535 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Starred entries' 137 starred: 'Starred entries'
138 archived: 'Archived entries' 138 archived: 'Archived entries'
139 filtered: 'Filtered entries' 139 filtered: 'Filtered entries'
140 filtered_tags: 'Filtered by tags' 140 filtered_tags: 'Filtered by tags:'
141 untagged: 'Untagged entries' 141 untagged: 'Untagged entries'
142 list: 142 list:
143 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 143 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 1b1e0cb1..42ec8183 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Artículos favoritos' 137 starred: 'Artículos favoritos'
138 archived: 'Artículos archivados' 138 archived: 'Artículos archivados'
139 filtered: 'Artículos filtrados' 139 filtered: 'Artículos filtrados'
140 # filtered_tags: 'Filtered by tags' 140 # filtered_tags: 'Filtered by tags:'
141 # untagged: 'Untagged entries' 141 # untagged: 'Untagged entries'
142 list: 142 list:
143 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.' 143 number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 41dc8acf..f82167df 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'مقاله‌های برگزیده' 137 starred: 'مقاله‌های برگزیده'
138 archived: 'مقاله‌های بایگانی‌شده' 138 archived: 'مقاله‌های بایگانی‌شده'
139 filtered: 'مقاله‌های فیلترشده' 139 filtered: 'مقاله‌های فیلترشده'
140 # filtered_tags: 'Filtered by tags' 140 # filtered_tags: 'Filtered by tags:'
141 # untagged: 'Untagged entries' 141 # untagged: 'Untagged entries'
142 list: 142 list:
143 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.' 143 number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 7fb9681d..421cb8b5 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -1,422 +1,422 @@
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 form_rss: 74 form_rss:
75 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d'abord créer un jeton." 75 description: "Les flux RSS fournis par wallabag vous permettent de lire vos articles sauvegardés dans votre lecteur de flux préféré. Pour pouvoir les utiliser, vous devez d’abord créer un jeton."
76 token_label: 'Jeton RSS' 76 token_label: "Jeton RSS"
77 no_token: 'Aucun jeton généré' 77 no_token: "Aucun jeton généré"
78 token_create: 'Créez votre jeton' 78 token_create: "Créez votre jeton"
79 token_reset: 'Réinitialisez votre jeton' 79 token_reset: "Réinitialisez votre jeton"
80 rss_links: 'URL de vos flux RSS' 80 rss_links: "Adresse de vos flux RSS"
81 rss_link: 81 rss_link:
82 unread: 'non lus' 82 unread: "non lus"
83 starred: 'favoris' 83 starred: "favoris"
84 archive: 'lus' 84 archive: "lus"
85 rss_limit: "Nombre d'articles dans le flux" 85 rss_limit: "Nombre darticles dans le flux"
86 form_user: 86 form_user:
87 two_factor_description: "Activer l'authentification double-facteur veut dire que vous allez recevoir un code par email à chaque nouvelle connexion non approuvée." 87 two_factor_description: "Activer l’authentification double-facteur veut dire que vous allez recevoir un code par courriel à chaque nouvelle connexion non approuvée."
88 name_label: 'Nom' 88 name_label: "Nom"
89 email_label: 'Adresse e-mail' 89 email_label: "Adresse courriel"
90 twoFactorAuthentication_label: 'Double authentification' 90 twoFactorAuthentication_label: "Double authentification"
91 form_password: 91 form_password:
92 old_password_label: 'Mot de passe actuel' 92 old_password_label: "Mot de passe actuel"
93 new_password_label: 'Nouveau mot de passe' 93 new_password_label: "Nouveau mot de passe"
94 repeat_new_password_label: 'Confirmez votre nouveau mot de passe' 94 repeat_new_password_label: "Confirmez votre nouveau mot de passe"
95 form_rules: 95 form_rules:
96 if_label: 'si' 96 if_label: "si"
97 then_tag_as_label: 'alors attribuer les tags' 97 then_tag_as_label: "alors attribuer les tags"
98 delete_rule_label: 'supprimer' 98 delete_rule_label: "supprimer"
99 edit_rule_label: 'éditer' 99 edit_rule_label: "éditer"
100 rule_label: 'Règle' 100 rule_label: "Règle"
101 tags_label: 'Tags' 101 tags_label: "Tags"
102 faq: 102 faq:
103 title: 'FAQ' 103 title: "FAQ"
104 tagging_rules_definition_title: 'Que signifient les règles de tag automatiques ?' 104 tagging_rules_definition_title: "Que signifient les règles de tag automatiques ?"
105 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." 105 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."
106 how_to_use_them_title: 'Comment les utiliser ?' 106 how_to_use_them_title: "Comment les utiliser ?"
107 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> »' 107 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> »"
108 variables_available_title: 'Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?' 108 variables_available_title: "Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?"
109 variables_available_description: 'Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles de tag automatiques :' 109 variables_available_description: "Les variables et opérateurs suivants peuvent être utilisés pour écrire des règles de tag automatiques :"
110 meaning: 'Signification' 110 meaning: "Signification"
111 variable_description: 111 variable_description:
112 label: 'Variable' 112 label: "Variable"
113 title: "Titre de l'article" 113 title: "Titre de larticle"
114 url: "URL de l'article" 114 url: "Adresse de larticle"
115 isArchived: "Si l'article est archivé ou non" 115 isArchived: "Si larticle est archivé ou non"
116 isStarred: "Si l'article est favori ou non" 116 isStarred: "Si larticle est favori ou non"
117 content: "Le contenu de l'article" 117 content: "Le contenu de larticle"
118 language: "La langue de l'article" 118 language: "La langue de larticle"
119 mimetype: "Le type MIME de l'article" 119 mimetype: "Le type MIME de larticle"
120 readingTime: "Le temps de lecture estimé de l'article, en minutes" 120 readingTime: "Le temps de lecture estimé de larticle, en minutes"
121 domainName: "Le nom de domaine de l'article" 121 domainName: "Le nom de domaine de larticle"
122 operator_description: 122 operator_description:
123 label: 'Opérateur' 123 label: "Opérateur"
124 less_than: 'Moins que…...' 124 less_than: "Moins que…..."
125 strictly_less_than: 'Strictement moins que…' 125 strictly_less_than: "Strictement moins que…"
126 greater_than: 'Plus que…' 126 greater_than: "Plus que…"
127 strictly_greater_than: 'Strictement plus que…' 127 strictly_greater_than: "Strictement plus que…"
128 equal_to: 'Égal à…' 128 equal_to: "Égal à…"
129 not_equal_to: 'Différent de…' 129 not_equal_to: "Différent de…"
130 or: "Une règle OU l'autre" 130 or: "Une règle OU lautre"
131 and: "Une règle ET l'autre" 131 and: "Une règle ET lautre"
132 matches: 'Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches "football"</code>' 132 matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
133 133
134entry: 134entry:
135 page_titles: 135 page_titles:
136 unread: 'Articles non lus' 136 unread: "Articles non lus"
137 starred: 'Articles favoris' 137 starred: "Articles favoris"
138 archived: 'Articles lus' 138 archived: "Articles lus"
139 filtered: 'Articles filtrés' 139 filtered: "Articles filtrés"
140 filtered_tags: 'Articles filtrés par tags' 140 filtered_tags: "Articles filtrés par tags :"
141 untagged: 'Article sans tag' 141 untagged: "Article sans tag"
142 list: 142 list:
143 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." 143 number_on_the_page: "{0} Il ny a pas darticles.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
144 reading_time: 'durée de lecture' 144 reading_time: "durée de lecture"
145 reading_time_minutes: 'durée de lecture: %readingTime% min' 145 reading_time_minutes: "durée de lecture: %readingTime% min"
146 reading_time_less_one_minute: 'durée de lecture: <small class="inferieur">&lt;</small> 1 min' 146 reading_time_less_one_minute: "durée de lecture: <small class=\"inferieur\">&lt;</small> 1 min"
147 number_of_tags: '{1}et un autre tag|]1,Inf[et %count% autres tags' 147 number_of_tags: "{1}et un autre tag|]1,Inf[et %count% autres tags"
148 reading_time_minutes_short: '%readingTime% min' 148 reading_time_minutes_short: "%readingTime% min"
149 reading_time_less_one_minute_short: '<small class="inferieur">&lt;</small> 1 min' 149 reading_time_less_one_minute_short: "<small class=\"inferieur\">&lt;</small> 1 min"
150 original_article: 'original' 150 original_article: "original"
151 toogle_as_read: 'Marquer comme lu/non lu' 151 toogle_as_read: "Marquer comme lu/non lu"
152 toogle_as_star: 'Marquer comme favori' 152 toogle_as_star: "Marquer comme favori"
153 delete: 'Supprimer' 153 delete: "Supprimer"
154 export_title: 'Exporter' 154 export_title: "Exporter"
155 filters: 155 filters:
156 title: 'Filtres' 156 title: "Filtres"
157 status_label: 'Status' 157 status_label: "Status"
158 archived_label: 'Lus' 158 archived_label: "Lus"
159 starred_label: 'Favoris' 159 starred_label: "Favoris"
160 unread_label: 'Non lus' 160 unread_label: "Non lus"
161 preview_picture_label: 'A une photo' 161 preview_picture_label: "A une photo"
162 preview_picture_help: 'Photo' 162 preview_picture_help: "Photo"
163 language_label: 'Langue' 163 language_label: "Langue"
164 reading_time: 164 reading_time:
165 label: 'Durée de lecture en minutes' 165 label: "Durée de lecture en minutes"
166 from: 'de' 166 from: "de"
167 to: 'à' 167 to: "à"
168 domain_label: 'Nom de domaine' 168 domain_label: "Nom de domaine"
169 created_at: 169 created_at:
170 label: 'Date de création' 170 label: "Date de création"
171 from: 'de' 171 from: "de"
172 to: 'à' 172 to: "à"
173 action: 173 action:
174 clear: 'Effacer' 174 clear: "Effacer"
175 filter: 'Filtrer' 175 filter: "Filtrer"
176 view: 176 view:
177 left_menu: 177 left_menu:
178 back_to_top: 'Revenir en haut' 178 back_to_top: "Revenir en haut"
179 back_to_homepage: 'Retour' 179 back_to_homepage: "Retour"
180 set_as_read: 'Marquer comme lu' 180 set_as_read: "Marquer comme lu"
181 set_as_unread: 'Marquer comme non lu' 181 set_as_unread: "Marquer comme non lu"
182 set_as_starred: 'Mettre en favori' 182 set_as_starred: "Mettre en favori"
183 view_original_article: 'Article original' 183 view_original_article: "Article original"
184 re_fetch_content: 'Recharger le contenu' 184 re_fetch_content: "Recharger le contenu"
185 delete: 'Supprimer' 185 delete: "Supprimer"
186 add_a_tag: 'Ajouter un tag' 186 add_a_tag: "Ajouter un tag"
187 share_content: 'Partager' 187 share_content: "Partager"
188 share_email_label: 'Email' 188 share_email_label: "Courriel"
189 public_link: 'Lien public' 189 public_link: "Lien public"
190 delete_public_link: 'Supprimer lien public' 190 delete_public_link: "Supprimer le lien public"
191 download: 'Télécharger' 191 download: "Télécharger"
192 print: 'Imprimer' 192 print: "Imprimer"
193 problem: 193 problem:
194 label: 'Un problème ?' 194 label: "Un problème ?"
195 description: "Est-ce que cet article s'affiche mal ?" 195 description: "Est-ce que cet article saffiche mal ?"
196 edit_title: 'Modifier le titre' 196 edit_title: "Modifier le titre"
197 original_article: 'original' 197 original_article: "original"
198 annotations_on_the_entry: '{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations' 198 annotations_on_the_entry: "{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations"
199 created_at: 'Date de création' 199 created_at: "Date de création"
200 new: 200 new:
201 page_title: 'Sauvegarder un nouvel article' 201 page_title: "Sauvegarder un nouvel article"
202 placeholder: 'http://website.com' 202 placeholder: "http://website.com"
203 form_new: 203 form_new:
204 url_label: Url 204 url_label: "Adresse"
205 edit: 205 edit:
206 page_title: 'Éditer un article' 206 page_title: "Éditer un article"
207 title_label: 'Titre' 207 title_label: "Titre"
208 url_label: 'Url' 208 url_label: "Adresse"
209 is_public_label: 'Public' 209 is_public_label: "Public"
210 save_label: 'Enregistrer' 210 save_label: "Enregistrer"
211 public: 211 public:
212 shared_by_wallabag: "Cet article a été partagé par <a href='%wallabag_instance%'>wallabag</a>" 212 shared_by_wallabag: "Cet article a été partagé par <a href=\"%wallabag_instance%\">wallabag</a>"
213 213
214about: 214about:
215 page_title: 'À propos' 215 page_title: "À propos"
216 top_menu: 216 top_menu:
217 who_behind_wallabag: "L'équipe derrière wallabag" 217 who_behind_wallabag: "Léquipe derrière wallabag"
218 getting_help: "Besoin d'aide" 218 getting_help: "Besoin daide"
219 helping: 'Aider wallabag' 219 helping: "Aider wallabag"
220 contributors: 'Contributeurs' 220 contributors: "Contributeurs"
221 third_party: 'Librairies tierces' 221 third_party: "Librairies tierces"
222 who_behind_wallabag: 222 who_behind_wallabag:
223 developped_by: 'Développé par' 223 developped_by: "Développé par"
224 website: 'Site web' 224 website: "Site web"
225 many_contributors: 'Et plein de contributeurs ♥ <a href="https://github.com/wallabag/wallabag/graphs/contributors">sur Github</a>' 225 many_contributors: "Et plein de contributeurs ♥ <a href=\"https://github.com/wallabag/wallabag/graphs/contributors\">sur Github</a>"
226 project_website: 'Site web du projet' 226 project_website: "Site web du projet"
227 license: 'Licence' 227 license: "Licence"
228 version: 'Version' 228 version: "Version"
229 getting_help: 229 getting_help:
230 documentation: 'Documentation' 230 documentation: "Documentation"
231 bug_reports: 'Rapport de bugs' 231 bug_reports: "Rapport de bogue"
232 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>' 232 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>"
233 helping: 233 helping:
234 description: 'wallabag est gratuit et opensource. Vous pouvez nous aider :' 234 description: "wallabag est gratuit et opensource. Vous pouvez nous aider :"
235 by_contributing: 'en contribuant au projet :' 235 by_contributing: "en contribuant au projet :"
236 by_contributing_2: 'un ticket recense tous nos besoins' 236 by_contributing_2: "un ticket recense tous nos besoins"
237 by_paypal: 'via Paypal' 237 by_paypal: "via Paypal"
238 contributors: 238 contributors:
239 description: "Merci aux contributeurs de l'application web de wallabag" 239 description: "Merci aux contributeurs de lapplication web de wallabag"
240 third_party: 240 third_party:
241 description: 'Voici la liste des dépendances utilisées dans wallabag (et leur license) :' 241 description: "Voici la liste des dépendances utilisées dans wallabag (et leur license) :"
242 package: 'Dépendance' 242 package: "Dépendance"
243 license: 'Licence' 243 license: "Licence"
244 244
245howto: 245howto:
246 page_title: 'Aide' 246 page_title: "Aide"
247 page_description: "Il y a plusieurs façon d'enregistrer un article :" 247 page_description: "Il y a plusieurs façon denregistrer un article :"
248 top_menu: 248 top_menu:
249 browser_addons: 'Extensions de navigateur' 249 browser_addons: "Extensions de navigateur"
250 mobile_apps: 'Applications smartphone' 250 mobile_apps: "Applications smartphone"
251 bookmarklet: 'Bookmarklet' 251 bookmarklet: "Bookmarklet"
252 form: 252 form:
253 description: 'Grâce à ce formulaire' 253 description: "Grâce à ce formulaire"
254 browser_addons: 254 browser_addons:
255 firefox: 'Extension Firefox' 255 firefox: "Extension Firefox"
256 chrome: 'Extension Chrome' 256 chrome: "Extension Chrome"
257 mobile_apps: 257 mobile_apps:
258 android: 258 android:
259 via_f_droid: 'via F-Droid' 259 via_f_droid: "via F-Droid"
260 via_google_play: 'via Google Play' 260 via_google_play: "via Google Play"
261 ios: 'sur iTunes Store' 261 ios: "sur iTunes Store"
262 windows: 'sur Microsoft Store' 262 windows: "sur Microsoft Store"
263 bookmarklet: 263 bookmarklet:
264 description: 'Glissez et déposez ce lien dans votre barre de favoris :' 264 description: "Glissez et déposez ce lien dans votre barre de favoris :"
265 265
266quickstart: 266quickstart:
267 page_title: 'Pour bien débuter' 267 page_title: "Pour bien débuter"
268 more: 'Et plus encore…' 268 more: "Et plus encore…"
269 intro: 269 intro:
270 title: 'Bienvenue sur wallabag !' 270 title: "Bienvenue sur wallabag !"
271 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." 271 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."
272 paragraph_2: 'Suivez-nous !' 272 paragraph_2: "Suivez-nous !"
273 configure: 273 configure:
274 title: "Configurez l'application" 274 title: "Configurez lapplication"
275 description: 'Pour voir une application qui vous correspond, allez voir du côté de la configuration de wallabag.' 275 description: "Pour voir une application qui vous correspond, allez voir du côté de la configuration de wallabag."
276 language: "Changez la langue et le design de l'application" 276 language: "Changez la langue et le design de lapplication"
277 rss: 'Activez les flux RSS' 277 rss: "Activez les flux RSS"
278 tagging_rules: 'Écrivez des règles pour classer automatiquement vos articles' 278 tagging_rules: "Écrivez des règles pour classer automatiquement vos articles"
279 admin: 279 admin:
280 title: 'Administration' 280 title: "Administration"
281 description: "En tant qu'administrateur sur wallabag, vous avez des privilèges qui vous permettent de :" 281 description: "En tant quadministrateur sur wallabag, vous avez des privilèges qui vous permettent de :"
282 new_user: 'Créer un nouvel utilisateur' 282 new_user: "Créer un nouvel utilisateur"
283 analytics: 'Configurer les statistiques' 283 analytics: "Configurer les statistiques"
284 sharing: 'Activer des paramètres de partages' 284 sharing: "Activer des paramètres de partages"
285 export: "Configurer les formats d'export" 285 export: "Configurer les formats dexport"
286 import: "Configurer l'import" 286 import: "Configurer limport"
287 first_steps: 287 first_steps:
288 title: 'Premiers pas' 288 title: "Premiers pas"
289 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." 289 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."
290 new_article: 'Ajoutez votre premier article' 290 new_article: "Ajoutez votre premier article"
291 unread_articles: 'Et rangez-le !' 291 unread_articles: "Et rangez-le !"
292 migrate: 292 migrate:
293 title: 'Migrer depuis un service existant' 293 title: "Migrer depuis un service existant"
294 description: "Vous êtes un ancien utilisateur d'un service existant ? Nous allons vous aider à récupérer vos données sur wallabag." 294 description: "Vous êtes un ancien utilisateur d’un service existant ? Nous allons vous aider à récupérer vos données sur wallabag."
295 pocket: 'Migrer depuis Pocket' 295 pocket: "Migrer depuis Pocket"
296 wallabag_v1: 'Migrer depuis wallabag v1' 296 wallabag_v1: "Migrer depuis wallabag v1"
297 wallabag_v2: 'Migrer depuis wallabag v2' 297 wallabag_v2: "Migrer depuis wallabag v2"
298 readability: 'Migrer depuis Readability' 298 readability: "Migrer depuis Readability"
299 instapaper: 'Migrer depuis Instapaper' 299 instapaper: "Migrer depuis Instapaper"
300 developer: 300 developer:
301 title: 'Pour les développeurs' 301 title: "Pour les développeurs"
302 description: 'Nous avons aussi pensé aux développeurs : Docker, API, traductions, etc.' 302 description: "Nous avons aussi pensé aux développeurs : Docker, API, traductions, etc."
303 create_application: 'Créer votre application tierce' 303 create_application: "Créer votre application tierce"
304 use_docker: 'Utiliser Docker pour installer wallabag' 304 use_docker: "Utiliser Docker pour installer wallabag"
305 docs: 305 docs:
306 title: 'Documentation complète' 306 title: "Documentation complète"
307 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." 307 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."
308 annotate: 'Annoter votre article' 308 annotate: "Annoter votre article"
309 export: 'Convertissez vos articles en ePub ou en PDF' 309 export: "Convertissez vos articles en ePub ou en PDF"
310 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l'article qui vous intéresse" 310 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l’article qui vous intéresse"
311 fetching_errors: "Que faire si mon article n'est pas correctement récupéré ?" 311 fetching_errors: "Que faire si mon article nest pas correctement récupéré ?"
312 all_docs: "Et encore plein d'autres choses !" 312 all_docs: "Et encore plein dautres choses !"
313 support: 313 support:
314 title: 'Support' 314 title: "Support"
315 description: 'Parce que vous avez peut-être besoin de nous poser une question, nous sommes disponibles pour vous.' 315 description: "Parce que vous avez peut-être besoin de nous poser une question, nous sommes disponibles pour vous."
316 github: 'Sur GitHub' 316 github: "Sur GitHub"
317 email: 'Par e-mail' 317 email: "Par courriel"
318 gitter: 'Sur Gitter' 318 gitter: "Sur Gitter"
319 319
320tag: 320tag:
321 page_title: 'Tags' 321 page_title: "Tags"
322 list: 322 list:
323 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." 323 number_on_the_page: "{0} Il ny a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags."
324 see_untagged_entries: 'Voir les articles sans tag' 324 see_untagged_entries: "Voir les articles sans tag"
325 325
326import: 326import:
327 page_title: 'Importer' 327 page_title: "Importer"
328 page_description: "Bienvenue dans l'outil de migration de wallabag. Choisissez ci-dessous le service depuis lequel vous souhaitez migrer." 328 page_description: "Bienvenue dans l’outil de migration de wallabag. Choisissez ci-dessous le service depuis lequel vous souhaitez migrer."
329 action: 329 action:
330 import_contents: 'Importer les contenus' 330 import_contents: "Importer les contenus"
331 form: 331 form:
332 mark_as_read_title: 'Marquer tout comme lu ?' 332 mark_as_read_title: "Marquer tout comme lu ?"
333 mark_as_read_label: 'Marquer tous les contenus importés comme lus' 333 mark_as_read_label: "Marquer tous les contenus importés comme lus"
334 file_label: 'Fichier' 334 file_label: "Fichier"
335 save_label: 'Importer le fichier' 335 save_label: "Importer le fichier"
336 pocket: 336 pocket:
337 page_title: 'Importer > Pocket' 337 page_title: "Importer > Pocket"
338 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." 338 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."
339 config_missing: 339 config_missing:
340 description: "L'import à partir de Pocket n'est pas configuré." 340 description: "Limport à partir de Pocket nest pas configuré."
341 admin_message: "Vous devez définir %keyurls%une clé pour l'API Pocket%keyurle%." 341 admin_message: "Vous devez définir %keyurls%une clé pour lAPI Pocket%keyurle%."
342 user_message: "L'administrateur de votre serveur doit définir une clé pour l'API Pocket." 342 user_message: "Ladministrateur de votre serveur doit définir une clé pour lAPI Pocket."
343 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." 343 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."
344 connect_to_pocket: 'Se connecter à Pocket et importer les données' 344 connect_to_pocket: "Se connecter à Pocket et importer les données"
345 wallabag_v1: 345 wallabag_v1:
346 page_title: 'Importer > Wallabag v1' 346 page_title: "Importer > wallabag v1"
347 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".' 347 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 »."
348 how_to: "Choisissez le fichier de votre export wallabag v1 et cliquez sur le bouton ci-dessous pour l'importer." 348 how_to: "Choisissez le fichier de votre export wallabag v1 et cliquez sur le bouton ci-dessous pour limporter."
349 wallabag_v2: 349 wallabag_v2:
350 page_title: 'Importer > Wallabag v2' 350 page_title: "Importer > wallabag v2"
351 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\"" 351 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 »"
352 readability: 352 readability:
353 page_title: 'Importer > Readability' 353 page_title: "Importer > Readability"
354 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.' 354 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."
355 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l'importer." 355 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour limporter."
356 worker: 356 worker:
357 enabled: "Les imports sont asynchrones. Une fois l'import commencé un worker externe traitera les messages un par un. Le service activé est :" 357 enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :"
358 firefox: 358 firefox:
359 page_title: 'Import > Firefox' 359 page_title: "Import > Firefox"
360 description: "Cet outil va vous permettre d'importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>" 360 description: "Cet outil va vous permettre d’importer tous vos marques-pages de Firefox. Ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>"
361 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." 361 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."
362 chrome: 362 chrome:
363 page_title: 'Import > Chrome' 363 page_title: "Import > Chrome"
364 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>" 364 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>"
365 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." 365 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."
366 instapaper: 366 instapaper:
367 page_title: 'Import > Instapaper' 367 page_title: "Import > Instapaper"
368 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").' 368 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 »)."
369 how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour l'importer." 369 how_to: "Choisissez le fichier de votre export Instapaper et cliquez sur le bouton ci-dessous pour limporter."
370 370
371developer: 371developer:
372 page_title: 'Développeur' 372 page_title: "Développeur"
373 welcome_message: "Bienvenue sur l'API de wallabag" 373 welcome_message: "Bienvenue sur lAPI de wallabag"
374 documentation: 'Documentation' 374 documentation: "Documentation"
375 how_to_first_app: 'Comment créer votre première application' 375 how_to_first_app: "Comment créer votre première application"
376 full_documentation: "Voir la documentation complète de l'API" 376 full_documentation: "Voir la documentation complète de lAPI"
377 list_methods: "Lister toutes les méthodes de l'API" 377 list_methods: "Lister toutes les méthodes de lAPI"
378 clients: 378 clients:
379 title: 'Clients' 379 title: "Clients"
380 create_new: 'Créer un nouveau client' 380 create_new: "Créer un nouveau client"
381 existing_clients: 381 existing_clients:
382 title: 'Les clients existants' 382 title: "Les clients existants"
383 field_id: 'ID Client' 383 field_id: "ID Client"
384 field_secret: 'Clé secrète' 384 field_secret: "Clé secrète"
385 field_uris: 'URLs de redirection' 385 field_uris: "Adresse de redirection"
386 field_grant_types: 'Type de privilège accordé' 386 field_grant_types: "Type de privilège accordé"
387 no_client: 'Aucun client pour le moment' 387 no_client: "Aucun client pour le moment"
388 remove: 388 remove:
389 warn_message_1: 'Vous avez la possibilité de supprimer le client %name%. Cette action est IRREVERSIBLE !' 389 warn_message_1: "Vous avez la possibilité de supprimer le client %name%. Cette action est IRRÉVERSIBLE !"
390 warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l'utilisaient ne fonctionneront plus avec votre compte wallabag." 390 warn_message_2: "Si vous supprimez le client %name%, toutes les applications qui l’utilisaient ne fonctionneront plus avec votre compte wallabag."
391 action: 'Supprimer le client %name%' 391 action: "Supprimer le client %name%"
392 client: 392 client:
393 page_title: 'Développeur > Nouveau client' 393 page_title: "Développeur > Nouveau client"
394 page_description: "Vous allez créer un nouveau client. Merci de remplir l'url de redirection vers votre application." 394 page_description: "Vous allez créer un nouveau client. Merci de remplir l’adresse de redirection vers votre application."
395 form: 395 form:
396 name_label: "Nom du client" 396 name_label: "Nom du client"
397 redirect_uris_label: 'URLs de redirection (optionnel)' 397 redirect_uris_label: "Adresses de redirection (optionnel)"
398 save_label: 'Créer un nouveau client' 398 save_label: "Créer un nouveau client"
399 action_back: 'Retour' 399 action_back: "Retour"
400 client_parameter: 400 client_parameter:
401 page_title: 'Développeur > Les paramètres de votre client' 401 page_title: "Développeur > Les paramètres de votre client"
402 page_description: 'Voilà les paramètres de votre client' 402 page_description: "Voilà les paramètres de votre client"
403 field_name: 'Nom du client' 403 field_name: "Nom du client"
404 field_id: 'ID Client' 404 field_id: "ID client"
405 field_secret: 'Clé secrète' 405 field_secret: "Clé secrète"
406 back: 'Retour' 406 back: "Retour"
407 read_howto: 'Lire "comment créer ma première application"' 407 read_howto: "Lire « comment créer ma première application »"
408 howto: 408 howto:
409 page_title: 'Développeur > Comment créer votre première application' 409 page_title: "Développeur > Comment créer votre première application"
410 description: 410 description:
411 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." 411 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."
412 paragraph_2: "Vous avez besoin d'un token pour échanger entre votre application et l'API de wallabag." 412 paragraph_2: "Vous avez besoin dun token pour échanger entre votre application et lAPI de wallabag."
413 paragraph_3: 'Pour créer un token, vous devez <a href="%link%">créer un nouveau client</a>.' 413 paragraph_3: "Pour créer un token, vous devez <a href=\"%link%\">créer un nouveau client</a>."
414 paragraph_4: 'Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):' 414 paragraph_4: "Maintenant créez votre token (remplacer client_id, client_secret, username et password avec les bonnes valeurs):"
415 paragraph_5: "L'API vous retournera une réponse comme ça :" 415 paragraph_5: "LAPI vous retournera une réponse comme ça :"
416 paragraph_6: "L'access_token doit être utilisé pour faire un appel à l'API. Par exemple :" 416 paragraph_6: "Laccess_token doit être utilisé pour faire un appel à lAPI. Par exemple :"
417 paragraph_7: "Cet appel va retourner tous les articles de l'utilisateur." 417 paragraph_7: "Cet appel va retourner tous les articles de lutilisateur."
418 paragraph_8: "Si vous voulez toutes les méthodes de l'API, jetez un oeil <a href=\"%link%\">à la documentation de l'API</a>." 418 paragraph_8: "Si vous voulez toutes les méthodes de l’API, jetez un oeil <a href=\"%link%\">à la documentation de l’API</a>."
419 back: 'Retour' 419 back: "Retour"
420 420
421user: 421user:
422 page_title: Gestion des utilisateurs 422 page_title: Gestion des utilisateurs
@@ -430,20 +430,20 @@ user:
430 no: Non 430 no: Non
431 create_new_one: Créer un nouvel utilisateur 431 create_new_one: Créer un nouvel utilisateur
432 form: 432 form:
433 username_label: "Nom d'utilisateur" 433 username_label: "Nom dutilisateur"
434 name_label: 'Nom' 434 name_label: "Nom"
435 password_label: 'Mot de passe' 435 password_label: "Mot de passe"
436 repeat_new_password_label: 'Confirmez votre nouveau mot de passe' 436 repeat_new_password_label: "Confirmez votre nouveau mot de passe"
437 plain_password_label: 'Mot de passe en clair' 437 plain_password_label: "Mot de passe en clair"
438 email_label: 'Adresse e-mail' 438 email_label: "Adresse courriel"
439 enabled_label: 'Activé' 439 enabled_label: "Activé"
440 locked_label: 'Bloqué' 440 locked_label: "Bloqué"
441 last_login_label: 'Dernière connexion' 441 last_login_label: "Dernière connexion"
442 twofactor_label: Double authentification 442 twofactor_label: "Double authentification"
443 save: Sauvegarder 443 save: "Sauvegarder"
444 delete: Supprimer 444 delete: "Supprimer"
445 delete_confirm: Êtes-vous r? 445 delete_confirm: "Voulez-vous vraiment ?"
446 back_to_list: Revenir à la liste 446 back_to_list: "Revenir à la liste"
447 447
448error: 448error:
449 page_title: Une erreur est survenue 449 page_title: Une erreur est survenue
@@ -451,41 +451,41 @@ error:
451flashes: 451flashes:
452 config: 452 config:
453 notice: 453 notice:
454 config_saved: 'Les paramètres ont bien été mis à jour. Certains seront pris en compte après déconnexion.' 454 config_saved: "Les paramètres ont bien été mis à jour. Certains seront pris en compte après déconnexion."
455 password_updated: 'Votre mot de passe a bien été mis à jour' 455 password_updated: "Votre mot de passe a bien été mis à jour"
456 password_not_updated_demo: "En démo, vous ne pouvez pas changer le mot de passe de cet utilisateur." 456 password_not_updated_demo: "En démo, vous ne pouvez pas changer le mot de passe de cet utilisateur."
457 user_updated: 'Vos informations personnelles ont bien été mises à jour' 457 user_updated: "Vos informations personnelles ont bien été mises à jour"
458 rss_updated: 'La configuration des flux RSS a bien été mise à jour' 458 rss_updated: "La configuration des flux RSS a bien été mise à jour"
459 tagging_rules_updated: 'Règles mises à jour' 459 tagging_rules_updated: "Règles mises à jour"
460 tagging_rules_deleted: 'Règle supprimée' 460 tagging_rules_deleted: "Règle supprimée"
461 user_added: 'Utilisateur "%username%" ajouté' 461 user_added: "Utilisateur \"%username%\" ajouté"
462 rss_token_updated: 'Jeton RSS mis à jour' 462 rss_token_updated: "Jeton RSS mis à jour"
463 entry: 463 entry:
464 notice: 464 notice:
465 entry_already_saved: 'Article déjà sauvergardé le %date%' 465 entry_already_saved: "Article déjà sauvergardé le %date%"
466 entry_saved: 'Article enregistré' 466 entry_saved: "Article enregistré"
467 entry_saved_failed: 'Article enregistré mais impossible de récupérer le contenu' 467 entry_saved_failed: "Article enregistré mais impossible de récupérer le contenu"
468 entry_updated: 'Article mis à jour' 468 entry_updated: "Article mis à jour"
469 entry_reloaded: 'Article rechargé' 469 entry_reloaded: "Article rechargé"
470 entry_reloaded_failed: "Article mis à jour mais impossible de récupérer le contenu" 470 entry_reloaded_failed: "Article mis à jour mais impossible de récupérer le contenu"
471 entry_archived: 'Article marqué comme lu' 471 entry_archived: "Article marqué comme lu"
472 entry_unarchived: 'Article marqué comme non lu' 472 entry_unarchived: "Article marqué comme non lu"
473 entry_starred: 'Article ajouté dans les favoris' 473 entry_starred: "Article ajouté dans les favoris"
474 entry_unstarred: 'Article retiré des favoris' 474 entry_unstarred: "Article retiré des favoris"
475 entry_deleted: 'Article supprimé' 475 entry_deleted: "Article supprimé"
476 tag: 476 tag:
477 notice: 477 notice:
478 tag_added: 'Tag ajouté' 478 tag_added: "Tag ajouté"
479 import: 479 import:
480 notice: 480 notice:
481 failed: "L'import a échoué, veuillez ré-essayer" 481 failed: "Limport a échoué, veuillez ré-essayer"
482 failed_on_file: "Erreur lors du traitement de l'import. Vérifier votre fichier." 482 failed_on_file: "Erreur lors du traitement de limport. Vérifiez votre fichier."
483 summary: "Rapport d'import: %imported% importés, %skipped% déjà présents." 483 summary: "Rapport dimport : %imported% importés, %skipped% déjà présents."
484 summary_with_queue: "Rapport d'import: %queued% en cours de traitement." 484 summary_with_queue: "Rapport dimport: %queued% en cours de traitement."
485 error: 485 error:
486 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. 486 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."
487 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. 487 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."
488 developer: 488 developer:
489 notice: 489 notice:
490 client_created: 'Nouveau client %name% créé' 490 client_created: "Nouveau client %name% créé"
491 client_deleted: 'Client %name% supprimé' 491 client_deleted: "Client %name% supprimé"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index b279ae40..d679ef00 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Contenuti preferiti' 137 starred: 'Contenuti preferiti'
138 archived: 'Contenuti archiviati' 138 archived: 'Contenuti archiviati'
139 filtered: 'Contenuti filtrati' 139 filtered: 'Contenuti filtrati'
140 # filtered_tags: 'Filtered by tags' 140 # filtered_tags: 'Filtered by tags:'
141 # untagged: 'Untagged entries' 141 # untagged: 'Untagged entries'
142 list: 142 list:
143 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti." 143 number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index a4659620..af0fba0d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Articles favorits' 137 starred: 'Articles favorits'
138 archived: 'Articles legits' 138 archived: 'Articles legits'
139 filtered: 'Articles filtrats' 139 filtered: 'Articles filtrats'
140 filtered_tags: 'Filtats per etiquetas' 140 filtered_tags: 'Filtats per etiquetas:'
141 untagged: 'Articles sens etiqueta' 141 untagged: 'Articles sens etiqueta'
142 list: 142 list:
143 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles." 143 number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 798b39c2..bf47b58a 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -137,7 +137,7 @@ entry:
137 starred: 'Wpisy oznaczone gwiazdką' 137 starred: 'Wpisy oznaczone gwiazdką'
138 archived: 'Zarchiwizowane wpisy' 138 archived: 'Zarchiwizowane wpisy'
139 filtered: 'Odfiltrowane wpisy' 139 filtered: 'Odfiltrowane wpisy'
140 filtered_tags: 'Filtrowane po tagach' 140 filtered_tags: 'Filtrowane po tagach:'
141 untagged: 'Odtaguj wpisy' 141 untagged: 'Odtaguj wpisy'
142 list: 142 list:
143 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.' 143 number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
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..f10dc9aa
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -0,0 +1,492 @@
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 user_updated: 'Informação atualizada'
455 rss_updated: 'Informação de RSS atualizada'
456 tagging_rules_updated: 'Regras de tags atualizadas'
457 tagging_rules_deleted: 'Regra de tag apagada'
458 rss_token_updated: 'Token RSS atualizado'
459 entry:
460 notice:
461 entry_already_saved: 'Entrada já foi salva em %date%'
462 entry_saved: 'Entrada salva'
463 entry_saved_failed: 'Failed to save entry'
464 entry_updated: 'Entrada atualizada'
465 entry_reloaded: 'Entrada recarregada'
466 entry_reloaded_failed: 'Falha em recarregar a entrada'
467 entry_archived: 'Entrada arquivada'
468 entry_unarchived: 'Entrada desarquivada'
469 entry_starred: 'Entrada destacada'
470 entry_unstarred: 'Entrada não destacada'
471 entry_deleted: 'Entrada apagada'
472 tag:
473 notice:
474 tag_added: 'Tag adicionada'
475 import:
476 notice:
477 failed: 'Importação falhou, por favor tente novamente.'
478 failed_on_file: 'Erro ao processar a importação. Por favor verifique seu arquivo de importação.'
479 summary: 'relatório de importação: %imported% importados, %skipped% já existem.'
480 summary_with_queue: 'Importar sumáario: %queued% agendados.'
481 error:
482 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.'
483 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.'
484 developer:
485 notice:
486 client_created: 'Novo cliente criado.'
487 client_deleted: 'Cliente removido'
488 user:
489 notice:
490 added: 'Usuário "%username%" adicionado'
491 updated: 'Usuário "%username%" atualizado'
492 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 21f27e08..875c82e8 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -137,7 +137,7 @@ entry:
137 # starred: 'Starred entries' 137 # starred: 'Starred entries'
138 # archived: 'Archived entries' 138 # archived: 'Archived entries'
139 # filtered: 'Filtered entries' 139 # filtered: 'Filtered entries'
140 # filtered_tags: 'Filtered by tags' 140 # filtered_tags: 'Filtered by tags:'
141 # untagged: 'Untagged entries' 141 # untagged: 'Untagged entries'
142 list: 142 list:
143 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 143 # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index f137ec99..f50f629a 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -136,7 +136,7 @@ entry:
136 # starred: 'Starred entries' 136 # starred: 'Starred entries'
137 # archived: 'Archived entries' 137 # archived: 'Archived entries'
138 # filtered: 'Filtered entries' 138 # filtered: 'Filtered entries'
139 # filtered_tags: 'Filtered by tags' 139 # filtered_tags: 'Filtered by tags:'
140 # untagged: 'Untagged entries' 140 # untagged: 'Untagged entries'
141 list: 141 list:
142 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.' 142 number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
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 cc150cf1..0f1c010f 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 %}
@@ -63,19 +67,23 @@
63 <!-- Export --> 67 <!-- Export -->
64 <aside id="download-form"> 68 <aside id="download-form">
65 {% set currentRoute = app.request.attributes.get('_route') %} 69 {% set currentRoute = app.request.attributes.get('_route') %}
70 {% set currentTag = '' %}
71 {% if tag is defined %}
72 {% set currentTag = tag %}
73 {% endif %}
66 {% if currentRoute == 'homepage' %} 74 {% if currentRoute == 'homepage' %}
67 {% set currentRoute = 'unread' %} 75 {% set currentRoute = 'unread' %}
68 {% endif %} 76 {% endif %}
69 <h2>{{ 'entry.list.export_title'|trans }}</h2> 77 <h2>{{ 'entry.list.export_title'|trans }}</h2>
70 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a> 78 <a href="javascript: void(null);" id="download-form-close" class="close-button--popup close-button">&times;</a>
71 <ul> 79 <ul>
72 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %} 80 {% 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 %}
73 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %} 81 {% 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 %}
74 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %} 82 {% 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 %}
75 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %} 83 {% 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 %}
76 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %} 84 {% 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 %}
77 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %} 85 {% 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 %}
78 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %} 86 {% 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 %}
79 </ul> 87 </ul>
80 </aside> 88 </aside>
81 89
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 1f88f774..6347afac 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 %}
@@ -97,18 +101,22 @@
97 <!-- Export --> 101 <!-- Export -->
98 <div id="export" class="side-nav fixed right-aligned"> 102 <div id="export" class="side-nav fixed right-aligned">
99 {% set currentRoute = app.request.attributes.get('_route') %} 103 {% set currentRoute = app.request.attributes.get('_route') %}
104 {% set currentTag = '' %}
105 {% if tag is defined %}
106 {% set currentTag = tag %}
107 {% endif %}
100 {% if currentRoute == 'homepage' %} 108 {% if currentRoute == 'homepage' %}
101 {% set currentRoute = 'unread' %} 109 {% set currentRoute = 'unread' %}
102 {% endif %} 110 {% endif %}
103 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4> 111 <h4 class="center">{{ 'entry.list.export_title'|trans }}</h4>
104 <ul> 112 <ul>
105 {% if craue_setting('export_epub') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'epub' }) }}">EPUB</a></li>{% endif %} 113 {% 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 %}
106 {% if craue_setting('export_mobi') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'mobi' }) }}">MOBI</a></li>{% endif %} 114 {% 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 %}
107 {% if craue_setting('export_pdf') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'pdf' }) }}">PDF</a></li>{% endif %} 115 {% 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 %}
108 {% if craue_setting('export_csv') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'json' }) }}">JSON</a></li>{% endif %} 116 {% 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 %}
109 {% if craue_setting('export_json') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'csv' }) }}">CSV</a></li>{% endif %} 117 {% 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 %}
110 {% if craue_setting('export_txt') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'txt' }) }}">TXT</a></li>{% endif %} 118 {% 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 %}
111 {% if craue_setting('export_xml') %}<li class="bold"><a class="waves-effect" href="{{ path('export_entries', { 'category': currentRoute, 'format': 'xml' }) }}">XML</a></li>{% endif %} 119 {% 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 %}
112 </ul> 120 </ul>
113 </div> 121 </div>
114 122
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php
index 1df38295..d1325338 100644
--- a/src/Wallabag/ImportBundle/Command/ImportCommand.php
+++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php
@@ -50,6 +50,9 @@ class ImportCommand extends ContainerAwareCommand
50 case 'chrome': 50 case 'chrome':
51 $wallabag = $this->getContainer()->get('wallabag_import.chrome.import'); 51 $wallabag = $this->getContainer()->get('wallabag_import.chrome.import');
52 break; 52 break;
53 case 'instapaper':
54 $wallabag = $this->getContainer()->get('wallabag_import.instapaper.import');
55 break;
53 case 'v1': 56 case 'v1':
54 default: 57 default:
55 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); 58 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import');
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml
index 89adc71b..d600be0f 100644
--- a/src/Wallabag/ImportBundle/Resources/config/services.yml
+++ b/src/Wallabag/ImportBundle/Resources/config/services.yml
@@ -20,7 +20,6 @@ services:
20 arguments: 20 arguments:
21 - "@doctrine.orm.entity_manager" 21 - "@doctrine.orm.entity_manager"
22 - "@wallabag_core.content_proxy" 22 - "@wallabag_core.content_proxy"
23 - "@craue_config"
24 calls: 23 calls:
25 - [ setClient, [ "@wallabag_import.pocket.client" ] ] 24 - [ setClient, [ "@wallabag_import.pocket.client" ] ]
26 - [ setLogger, [ "@logger" ]] 25 - [ setLogger, [ "@logger" ]]
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 eb9c8e67..a8ee721b 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"