- { resource: security.yml }
- { resource: services.yml }
+parameters:
+ # Allows to use the live reload feature for changes in assets
+ use_webpack_dev_server: false
+ craue_config.cache_adapter.class: Craue\ConfigBundle\CacheAdapter\SymfonyCacheComponentAdapter
+
framework:
#esi: ~
translator:
assets: ~
wallabag_core:
- version: 2.2.2
+ version: 2.2.3
paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb"
languages:
en: 'English'
reading_speed: 1
cache_lifetime: 10
action_mark_as_read: 1
- list_mode: 1
+ list_mode: 0
fetching_error_message: |
wallabag can't retrieve contents for this article. Please <a href="http://doc.wallabag.org/en/master/user/errors_during_fetching.html#how-can-i-help-to-fix-that">troubleshoot this issue</a>.
+ api_limit_mass_actions: 10
wallabag_user:
registration_enabled: "%fosuser_registration%"
"issues": "https://github.com/wallabag/wallabag/issues"
},
"require": {
- "php": ">=5.5.9",
+ "php": ">=5.6.0",
"ext-pcre": "*",
"ext-dom": "*",
"ext-curl": "*",
"liip/theme-bundle": "~1.1",
"lexik/form-filter-bundle": "~5.0",
"j0k3r/graby": "~1.0",
- "friendsofsymfony/user-bundle": "2.0.x-dev",
+ "friendsofsymfony/user-bundle": "^2.0",
"friendsofsymfony/oauth-server-bundle": "^1.5",
"stof/doctrine-extensions-bundle": "^1.2",
"scheb/two-factor-bundle": "~2.0",
"guzzlehttp/guzzle": "^5.3.1",
"doctrine/doctrine-migrations-bundle": "^1.0",
"paragonie/random_compat": "~1.0",
- "craue/config-bundle": "~1.4",
+ "craue/config-bundle": "~2.0",
"mnapoli/piwik-twig-extension": "^1.0",
"ocramius/proxy-manager": "1.*",
"white-october/pagerfanta-bundle": "^1.0",
"javibravo/simpleue": "^1.0",
"symfony/dom-crawler": "^3.1",
"friendsofsymfony/jsrouting-bundle": "^1.6",
- "bdunogier/guzzle-site-authenticator": "dev-master"
+ "bdunogier/guzzle-site-authenticator": "1.0.0-beta1"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "~2.2",
"config": {
"bin-dir": "bin",
"platform": {
- "php": "5.5.9"
+ "php": "5.6.0"
}
},
"minimum-stability": "dev",
use Hateoas\Configuration\Route;
use Hateoas\Representation\Factory\PagerfantaFactory;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
+use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId($url, $this->getUser()->getId());
- $results[$url] = false === $res ? false : true;
+ $results[$url] = $res instanceof Entry ? $res->getId() : false;
}
- $json = $this->get('serializer')->serialize($results, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($results);
}
// let's see if it is a simple url?
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId($url, $this->getUser()->getId());
- $exists = false === $res ? false : true;
-
- $json = $this->get('serializer')->serialize(['exists' => $exists], 'json');
+ $exists = $res instanceof Entry ? $res->getId() : false;
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse(['exists' => $exists]);
}
/**
)
);
- $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($paginatedCollection);
}
/**
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
->exportAs($request->attributes->get('_format'));
}
+ /**
+ * Handles an entries list and delete URL.
+ *
+ * @ApiDoc(
+ * parameters={
+ * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to delete."}
+ * }
+ * )
+ *
+ * @return JsonResponse
+ */
+ public function deleteEntriesListAction(Request $request)
+ {
+ $this->validateAuthentication();
+
+ $urls = json_decode($request->query->get('urls', []));
+
+ if (empty($urls)) {
+ return $this->sendResponse([]);
+ }
+
+ $results = [];
+
+ // handle multiple urls
+ foreach ($urls as $key => $url) {
+ $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
+ $url,
+ $this->getUser()->getId()
+ );
+
+ $results[$key]['url'] = $url;
+
+ if (false !== $entry) {
+ $em = $this->getDoctrine()->getManager();
+ $em->remove($entry);
+ $em->flush();
+
+ // entry deleted, dispatch event about it!
+ $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
+ }
+
+ $results[$key]['entry'] = $entry instanceof Entry ? true : false;
+ }
+
+ return $this->sendResponse($results);
+ }
+
+ /**
+ * Handles an entries list and create URL.
+ *
+ * @ApiDoc(
+ * parameters={
+ * {"name"="urls", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...'}, {'url': 'http://...'}]", "description"="Urls (as an array) to create."}
+ * }
+ * )
+ *
+ * @return JsonResponse
+ *
+ * @throws HttpException When limit is reached
+ */
+ public function postEntriesListAction(Request $request)
+ {
+ $this->validateAuthentication();
+
+ $urls = json_decode($request->query->get('urls', []));
+ $results = [];
+
+ $limit = $this->container->getParameter('wallabag_core.api_limit_mass_actions');
+
+ if (count($urls) > $limit) {
+ throw new HttpException(400, 'API limit reached');
+ }
+
+ // handle multiple urls
+ if (!empty($urls)) {
+ foreach ($urls as $key => $url) {
+ $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
+ $url,
+ $this->getUser()->getId()
+ );
+
+ $results[$key]['url'] = $url;
+
+ if (false === $entry) {
+ $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
+ new Entry($this->getUser()),
+ $url
+ );
+ }
+
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($entry);
+ $em->flush();
+
+ $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false;
+
+ // entry saved, dispatch event about it!
+ $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ }
+ }
+
+ return $this->sendResponse($results);
+ }
+
/**
* Create an entry.
*
$entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId($url, $this->getUser()->getId());
if (false === $entry) {
- $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
- new Entry($this->getUser()),
- $url
- );
+ $entry = new Entry($this->getUser());
+ try {
+ $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
+ $entry,
+ $url
+ );
+ } catch (\Exception $e) {
+ $this->get('logger')->error('Error while saving an entry', [
+ 'exception' => $e,
+ 'entry' => $entry,
+ ]);
+ $entry->setUrl($url);
+ }
}
if (!is_null($title)) {
// entry saved, dispatch event about it!
$this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
$em = $this->getDoctrine()->getManager();
$em->flush();
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
// entry saved, dispatch event about it!
$this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
// entry deleted, dispatch event about it!
$this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
- $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry->getTags());
}
/**
$em->persist($entry);
$em->flush();
- $json = $this->get('serializer')->serialize($entry, 'json');
-
- return (new JsonResponse())->setJson($json);
+ return $this->sendResponse($entry);
}
/**
$em->persist($entry);
$em->flush();
- $json = $this->get('serializer')->serialize($entry, 'json');
+ return $this->sendResponse($entry);
+ }
+
+ /**
+ * Handles an entries list delete tags from them.
+ *
+ * @ApiDoc(
+ * parameters={
+ * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."}
+ * }
+ * )
+ *
+ * @return JsonResponse
+ */
+ public function deleteEntriesTagsListAction(Request $request)
+ {
+ $this->validateAuthentication();
+
+ $list = json_decode($request->query->get('list', []));
+
+ if (empty($list)) {
+ return $this->sendResponse([]);
+ }
+
+ // handle multiple urls
+ $results = [];
+
+ foreach ($list as $key => $element) {
+ $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
+ $element->url,
+ $this->getUser()->getId()
+ );
+
+ $results[$key]['url'] = $element->url;
+ $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false;
+
+ $tags = $element->tags;
+
+ if (false !== $entry && !(empty($tags))) {
+ $tags = explode(',', $tags);
+ foreach ($tags as $label) {
+ $label = trim($label);
+
+ $tag = $this->getDoctrine()
+ ->getRepository('WallabagCoreBundle:Tag')
+ ->findOneByLabel($label);
+
+ if (false !== $tag) {
+ $entry->removeTag($tag);
+ }
+ }
+
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($entry);
+ $em->flush();
+ }
+ }
+
+ return $this->sendResponse($results);
+ }
+
+ /**
+ * Handles an entries list and add tags to them.
+ *
+ * @ApiDoc(
+ * parameters={
+ * {"name"="list", "dataType"="string", "required"=true, "format"="A JSON array of urls [{'url': 'http://...','tags': 'tag1, tag2'}, {'url': 'http://...','tags': 'tag1, tag2'}]", "description"="Urls (as an array) to handle."}
+ * }
+ * )
+ *
+ * @return JsonResponse
+ */
+ public function postEntriesTagsListAction(Request $request)
+ {
+ $this->validateAuthentication();
+
+ $list = json_decode($request->query->get('list', []));
+
+ if (empty($list)) {
+ return $this->sendResponse([]);
+ }
+
+ $results = [];
+
+ // handle multiple urls
+ foreach ($list as $key => $element) {
+ $entry = $this->get('wallabag_core.entry_repository')->findByUrlAndUserId(
+ $element->url,
+ $this->getUser()->getId()
+ );
+
+ $results[$key]['url'] = $element->url;
+ $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false;
+
+ $tags = $element->tags;
+
+ if (false !== $entry && !(empty($tags))) {
+ $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
+
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($entry);
+ $em->flush();
+ }
+ }
+
+ return $this->sendResponse($results);
+ }
+
+ /**
+ * Shortcut to send data serialized in json.
+ *
+ * @param mixed $data
+ *
+ * @return JsonResponse
+ */
+ private function sendResponse($data)
+ {
+ $json = $this->get('serializer')->serialize($data, 'json');
return (new JsonResponse())->setJson($json);
}
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
# or: 'One rule OR another'
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
-
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
# unread: 'Unread entries'
# share_email_label: 'Email'
# public_link: 'public link'
# delete_public_link: 'delete public link'
- download: 'Download'
+ # export: 'Export'
# print: 'Print'
problem:
label: 'Problemer?'
original_article: 'original'
# annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
created_at: 'Oprettelsesdato'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Gem ny artikel'
placeholder: 'http://website.com'
# page_title: 'Edit an entry'
# title_label: 'Title'
url_label: 'Url'
- # is_public_label: 'Public'
save_label: 'Gem'
public:
# shared_by_wallabag: "This article has been shared by <a href=%wallabag_instance%'>wallabag</a>"
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
annotations: Entferne ALLE Annotationen
tags: Entferne ALLE Tags
entries: Entferne ALLE Einträge
+ # archived: Remove ALL archived entries
confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN)
form_password:
description: "Hier kannst du dein Kennwort ändern. Dieses sollte mindestens acht Zeichen enthalten."
or: 'Eine Regel ODER die andere'
and: 'Eine Regel UND eine andere'
matches: 'Testet, ob eine <i>Variable</i> auf eine <i>Suche</i> zutrifft (Groß- und Kleinschreibung wird nicht berücksichtigt).<br />Beispiel: <code>title matches "Fußball"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'E-Mail'
public_link: 'Öffentlicher Link'
delete_public_link: 'Lösche öffentlichen Link'
- download: 'Herunterladen'
+ export: 'Exportieren'
print: 'Drucken'
problem:
label: 'Probleme?'
original_article: 'original'
annotations_on_the_entry: '{0} Keine Anmerkungen|{1} Eine Anmerkung|]1,Inf[ %count% Anmerkungen'
created_at: 'Erstellungsdatum'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Neuen Artikel speichern'
placeholder: 'https://website.de'
page_title: 'Eintrag bearbeiten'
title_label: 'Titel'
url_label: 'URL'
- is_public_label: 'Öffentlich'
save_label: 'Speichern'
public:
shared_by_wallabag: "Dieser Artikel wurde mittels <a href='%wallabag_instance%'>wallabag</a> geteilt"
delete: Löschen
delete_confirm: Bist du sicher?
back_to_list: Zurück zur Liste
+ search:
+ # placeholder: Filter by username or email
error:
page_title: Ein Fehler ist aufgetreten
annotations_reset: Anmerkungen zurücksetzen
tags_reset: Tags zurücksetzen
entries_reset: Einträge zurücksetzen
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Eintrag bereits am %date% gespeichert'
annotations: Remove ALL annotations
tags: Remove ALL tags
entries: Remove ALL entries
+ archived: Remove ALL archived entries
confirm: Are you really sure? (THIS CAN'T BE UNDONE)
form_password:
description: "You can change your password here. Your new password should by at least 8 characters long."
or: 'One rule OR another'
and: 'One rule AND another'
matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
+ notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'Email'
public_link: 'public link'
delete_public_link: 'delete public link'
- download: 'Download'
+ export: 'Export'
print: 'Print'
problem:
label: 'Problems?'
original_article: 'original'
annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
created_at: 'Creation date'
+ published_at: 'Publication date'
+ published_by: 'Published by'
new:
page_title: 'Save new entry'
placeholder: 'http://website.com'
page_title: 'Edit an entry'
title_label: 'Title'
url_label: 'Url'
- is_public_label: 'Public'
save_label: 'Save'
public:
shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
delete: Delete
delete_confirm: Are you sure?
back_to_list: Back to list
+ search:
+ placeholder: Filter by username or email
error:
page_title: An error occurred
annotations_reset: Annotations reset
tags_reset: Tags reset
entries_reset: Entries reset
+ archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
annotations: Eliminar TODAS las anotaciones
tags: Eliminar TODAS las etiquetas
entries: Eliminar TODOS los artículos
+ # archived: Remove ALL archived entries
confirm: ¿Estás completamente seguro? (NO SE PUEDE DESHACER)
form_password:
description: "Puedes cambiar la contraseña aquí. Tu nueva contraseña debe tener al menos 8 caracteres."
or: 'Una regla U otra'
and: 'Una regla Y la otra'
matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'e-mail'
public_link: 'enlace público'
delete_public_link: 'eliminar enlace público'
- download: 'Descargar'
+ export: 'Exportar'
print: 'Imprimir'
problem:
label: '¿Algún problema?'
original_article: 'original'
annotations_on_the_entry: '{0} Sin anotaciones|{1} Una anotación|]1,Inf[ %count% anotaciones'
created_at: 'Fecha de creación'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Guardar un nuevo artículo'
placeholder: 'http://sitioweb.com'
page_title: 'Editar un artículo'
title_label: 'Título'
url_label: 'URL'
- is_public_label: 'Es público'
save_label: 'Guardar'
public:
shared_by_wallabag: "Este artículo se ha compartido con <a href='%wallabag_instance%'>wallabag</a>"
delete: Eliminar
delete_confirm: ¿Estás seguro?
back_to_list: Volver a la lista
+ search:
+ # placeholder: Filter by username or email
error:
page_title: Ha ocurrido un error
annotations_reset: Anotaciones reiniciadas
tags_reset: Etiquetas reiniciadas
entries_reset: Artículos reiniciados
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Artículo ya guardado el %fecha%'
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
# or: 'One rule OR another'
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'نشانی ایمیل'
# public_link: 'public link'
# delete_public_link: 'delete public link'
- download: 'بارگیری'
+ export: 'بارگیری'
print: 'چاپ'
problem:
label: 'مشکلات؟'
original_article: 'اصلی'
annotations_on_the_entry: '{0} بدون حاشیه|{1} یک حاشیه|]1,Inf[ %nbحاشیه% annotations'
created_at: 'زمان ساخت'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'ذخیرهٔ مقالهٔ تازه'
placeholder: 'http://website.com'
page_title: 'ویرایش مقاله'
title_label: 'عنوان'
url_label: 'نشانی'
- is_public_label: 'عمومی'
save_label: 'ذخیره'
public:
# shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
social: "Social"
powered_by: "propulsé par"
about: "À propos"
- stats: Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour !
+ stats: "Depuis le %user_creation%, vous avez lu %nb_archives% articles. Ce qui fait %per_day% par jour !"
config:
page_title: "Configuration"
300_word: "Je lis environ 300 mots par minute"
400_word: "Je lis environ 400 mots par minute"
action_mark_as_read:
- label: 'Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?'
- redirect_homepage: "À la page d'accueil"
- redirect_current_page: 'À la page courante'
- pocket_consumer_key_label: Clé d’authentification Pocket pour importer les données
- android_configuration: Configurez votre application Android
- help_theme: "L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème que vous préférez."
- help_items_per_page: "Vous pouvez définir le nombre d'articles affichés sur chaque page."
+ label: "Où souhaitez-vous être redirigé après avoir marqué un article comme lu ?"
+ redirect_homepage: "À la page d’accueil"
+ redirect_current_page: "À la page courante"
+ pocket_consumer_key_label: "Clé d’authentification Pocket pour importer les données"
+ android_configuration: "Configurez votre application Android"
+ help_theme: "L’affichage de wallabag est personnalisable. C’est ici que vous choisissez le thème que vous préférez."
+ help_items_per_page: "Vous pouvez définir le nombre d’articles affichés sur chaque page."
help_reading_speed: "wallabag calcule une durée de lecture pour chaque article. Vous pouvez définir ici, grâce à cette liste déroulante, si vous lisez plus ou moins vite. wallabag recalculera la durée de lecture de chaque article."
- help_language: "Vous pouvez définir la langue de l'interface de wallabag."
- help_pocket_consumer_key: "Nécessaire pour l'import depuis Pocket. Vous pouvez le créer depuis votre compte Pocket."
+ help_language: "Vous pouvez définir la langue de l’interface de wallabag."
+ help_pocket_consumer_key: "Nécessaire pour l’import depuis Pocket. Vous pouvez le créer depuis votre compte Pocket."
form_rss:
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."
token_label: "Jeton RSS"
twoFactorAuthentication_label: "Double authentification"
help_twoFactorAuthentication: "Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez un code par email."
delete:
- title: Supprimer mon compte (attention danger !)
- description: Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c'est IRRÉVERSIBLE). Vous serez ensuite déconnecté.
- confirm: Vous êtes vraiment sûr ? (C'EST IRRÉVERSIBLE)
- button: 'Supprimer mon compte'
+ title: "Supprimer mon compte (attention danger !)"
+ description: "Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (c’est IRRÉVERSIBLE). Vous serez ensuite déconnecté."
+ confirm: "Vous êtes vraiment sûr ? (C’EST IRRÉVERSIBLE)"
+ button: "Supprimer mon compte"
reset:
- title: Réinitialisation (attention danger !)
- description: En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES !
- annotations: Supprimer TOUTES les annotations
- tags: Supprimer TOUS les tags
- entries: Supprimer TOUS les articles
- confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE)
+ title: "Réinitialisation (attention danger !)"
+ description: "En cliquant sur les boutons ci-dessous vous avez la possibilité de supprimer certaines informations de votre compte. Attention, ces actions sont IRRÉVERSIBLES !"
+ annotations: "Supprimer TOUTES les annotations"
+ tags: "Supprimer TOUS les tags"
+ entries: "Supprimer TOUS les articles"
+ archived: "Supprimer TOUS les articles archivés"
+ confirm: "Êtes-vous vraiment vraiment sûr ? (C’EST IRRÉVERSIBLE)"
form_password:
description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères."
old_password_label: "Mot de passe actuel"
or: "Une règle OU l’autre"
and: "Une règle ET l’autre"
matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
+ notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>"
entry:
page_titles:
archived: "Articles lus"
filtered: "Articles filtrés"
filtered_tags: "Articles filtrés par tags :"
- filtered_search: 'Articles filtrés par recherche :'
+ filtered_search: "Articles filtrés par recherche :"
untagged: "Article sans tag"
list:
number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
preview_picture_label: "A une photo"
preview_picture_help: "Photo"
language_label: "Langue"
- http_status_label: 'Statut HTTP'
+ http_status_label: "Statut HTTP"
reading_time:
label: "Durée de lecture en minutes"
from: "de"
share_email_label: "Courriel"
public_link: "Lien public"
delete_public_link: "Supprimer le lien public"
- download: "Télécharger"
+ export: "Exporter"
print: "Imprimer"
problem:
label: "Un problème ?"
original_article: "original"
annotations_on_the_entry: "{0} Aucune annotation|{1} Une annotation|]1,Inf[ %count% annotations"
created_at: "Date de création"
+ published_at: "Date de publication"
+ published_by: "Publié par"
new:
page_title: "Sauvegarder un nouvel article"
placeholder: "http://website.com"
page_title: "Éditer un article"
title_label: "Titre"
url_label: "Adresse"
- is_public_label: "Public"
save_label: "Enregistrer"
public:
shared_by_wallabag: "Cet article a été partagé par <a href=\"%wallabag_instance%\">wallabag</a>"
bookmarklet:
description: "Glissez et déposez ce lien dans votre barre de favoris :"
shortcuts:
- page_description: Voici les raccourcis disponibles dans wallabag.
- shortcut: Raccourci
- action: Action
- all_pages_title: Raccourcis disponibles dans toutes les pages
- go_unread: Afficher les articles non lus
- go_starred: Afficher les articles favoris
- go_archive: Afficher les articles lus
- go_all: Afficher tous les articles
- go_tags: Afficher les tags
- go_config: Aller à la configuration
- go_import: Aller aux imports
- go_developers: Aller à la section Développeurs
- go_howto: Afficher l'aide (cette page !)
- go_logout: Se déconnecter
- list_title: Raccourcis disponibles dans les pages de liste
- search: Afficher le formulaire de recherche
- article_title: Raccourcis disponibles quand on affiche un article
- open_original: Ouvrir l'URL originale de l'article
- toggle_favorite: Changer le statut Favori de l'article
- toggle_archive: Changer le status Lu de l'article
- delete: Supprimer l'article
- material_title: Raccourcis disponibles avec le thème Material uniquement
- add_link: Ajouter un nouvel article
- hide_form: Masquer le formulaire courant (recherche ou nouvel article)
- arrows_navigation: Naviguer à travers les articles
- open_article: Afficher l'article sélectionné
+ page_description: "Voici les raccourcis disponibles dans wallabag."
+ shortcut: "Raccourci"
+ action: "Action"
+ all_pages_title: "Raccourcis disponibles dans toutes les pages"
+ go_unread: "Afficher les articles non lus"
+ go_starred: "Afficher les articles favoris"
+ go_archive: "Afficher les articles lus"
+ go_all: "Afficher tous les articles"
+ go_tags: "Afficher les tags"
+ go_config: "Aller à la configuration"
+ go_import: "Aller aux imports"
+ go_developers: "Aller à la section Développeurs"
+ go_howto: "Afficher l’aide (cette page !)"
+ go_logout: "Se déconnecter"
+ list_title: "Raccourcis disponibles dans les pages de liste"
+ search: "Afficher le formulaire de recherche"
+ article_title: "Raccourcis disponibles quand on affiche un article"
+ open_original: "Ouvrir l’URL originale de l’article"
+ toggle_favorite: "Changer le statut Favori de l’article"
+ toggle_archive: "Changer le status Lu de l’article"
+ delete: "Supprimer l’article"
+ material_title: "Raccourcis disponibles avec le thème Material uniquement"
+ add_link: "Ajouter un nouvel article"
+ hide_form: "Masquer le formulaire courant (recherche ou nouvel article)"
+ arrows_navigation: "Naviguer à travers les articles"
+ open_article: "Afficher l’article sélectionné"
quickstart:
page_title: "Pour bien débuter"
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."
see_untagged_entries: "Voir les articles sans tag"
new:
- add: 'Ajouter'
- placeholder: 'Vous pouvez ajouter plusieurs tags, séparés par une virgule.'
+ add: "Ajouter"
+ placeholder: "Vous pouvez ajouter plusieurs tags, séparés par une virgule."
import:
page_title: "Importer"
how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l’importer."
worker:
enabled: "Les imports sont asynchrones. Une fois l’import commencé un worker externe traitera les messages un par un. Le service activé est :"
- download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l'import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d'activer les imports asynchrones."
+ download_images_warning: "Vous avez configuré le téléchagement des images pour vos articles. Combiné à l’import classique, cette opération peut être très très longue (voire échouer). Nous vous conseillons <strong>vivement</strong> d’activer les imports asynchrones."
firefox:
page_title: "Import > Firefox"
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>"
back: "Retour"
user:
- page_title: Gestion des utilisateurs
- new_user: Créer un nouvel utilisateur
- edit_user: Éditer un utilisateur existant
- description: Ici vous pouvez gérer vos utilisateurs (création, mise à jour et suppression)
+ page_title: "Gestion des utilisateurs"
+ new_user: "Créer un nouvel utilisateur"
+ edit_user: "Éditer un utilisateur existant"
+ description: "Ici vous pouvez gérer vos utilisateurs (création, mise à jour et suppression)"
list:
- actions: Actions
- edit_action: Éditer
- yes: Oui
- no: Non
- create_new_one: Créer un nouvel utilisateur
+ actions: "Actions"
+ edit_action: "Éditer"
+ yes: "Oui"
+ no: "Non"
+ create_new_one: "Créer un nouvel utilisateur"
form:
username_label: "Nom d’utilisateur"
name_label: "Nom"
delete: "Supprimer"
delete_confirm: "Voulez-vous vraiment ?"
back_to_list: "Revenir à la liste"
+ search:
+ placeholder: "Filtrer par nom d’utilisateur ou email"
error:
- page_title: Une erreur est survenue
+ page_title: "Une erreur est survenue"
flashes:
config:
tagging_rules_updated: "Règles mises à jour"
tagging_rules_deleted: "Règle supprimée"
rss_token_updated: "Jeton RSS mis à jour"
- annotations_reset: Annotations supprimées
- tags_reset: Tags supprimés
- entries_reset: Articles supprimés
+ annotations_reset: "Annotations supprimées"
+ tags_reset: "Tags supprimés"
+ entries_reset: "Articles supprimés"
+ archived_reset: "Articles archivés supprimés"
entry:
notice:
entry_already_saved: "Article déjà sauvegardé le %date%"
client_deleted: "Client %name% supprimé"
user:
notice:
- added: 'Utilisateur "%username%" ajouté'
- updated: 'Utilisateur "%username%" mis à jour'
- deleted: 'Utilisateur "%username%" supprimé'
+ added: "Utilisateur \"%username%\" ajouté"
+ updated: "Utilisateur \"%username%\" mis à jour"
+ deleted: "Utilisateur \"%username%\" supprimé"
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
or: "Una regola O un'altra"
and: "Una regola E un'altra"
matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'E-mail'
# public_link: 'public link'
# delete_public_link: 'delete public link'
- download: 'Download'
+ export: 'Esporta'
print: 'Stampa'
problem:
label: 'Problemi?'
original_article: 'originale'
annotations_on_the_entry: '{0} Nessuna annotazione|{1} Una annotazione|]1,Inf[ %count% annotazioni'
created_at: 'Data di creazione'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Salva un nuovo contenuto'
placeholder: 'http://website.com'
page_title: 'Modifica voce'
title_label: 'Titolo'
url_label: 'Url'
- is_public_label: 'Pubblico'
save_label: 'Salva'
public:
# shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Contenuto già salvato in data %date%'
annotations: Levar TOTAS las anotacions
tags: Levar TOTAS las etiquetas
entries: Levar TOTES los articles
+ archived: Levar TOTES los articles archivats
confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE)
form_password:
description: "Podètz cambiar vòstre senhal aquí. Vòstre senhal deu èsser long d'almens 8 caractèrs."
not_equal_to: 'Diferent de…'
or: "Una règla O l'autra"
and: "Una règla E l'autra"
- matches: 'Teste se un <i>subjècte</i> correspond a una <i>recerca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>'
+ matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple : <code>title matches \"football\"</code>'
+ notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example : <code>title notmatches "football"</code>'
entry:
page_titles:
archived_label: 'Legits'
starred_label: 'Favorits'
unread_label: 'Pas legits'
- preview_picture_label: 'A una fotò'
- preview_picture_help: 'Fotò'
+ preview_picture_label: 'A un imatge'
+ preview_picture_help: 'Imatge'
language_label: 'Lenga'
http_status_label: 'Estatut HTTP'
reading_time:
share_email_label: 'Corrièl'
public_link: 'ligam public'
delete_public_link: 'suprimir lo ligam public'
- download: 'Telecargar'
+ export: 'Exportar'
print: 'Imprimir'
problem:
label: 'Un problèma ?'
original_article: 'original'
annotations_on_the_entry: "{0} Pas cap d'anotacion|{1} Una anotacion|]1,Inf[ %count% anotacions"
created_at: 'Data de creacion'
+ published_at: 'Data de publicacion'
+ published_by: 'Publicat per'
new:
page_title: 'Enregistrar un novèl article'
placeholder: 'http://website.com'
page_title: 'Modificar un article'
title_label: 'Títol'
url_label: 'Url'
- is_public_label: 'Public'
save_label: 'Enregistrar'
public:
shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>"
new_user: 'Crear un novèl utilizaire'
analytics: 'Configurar las estadisticas'
sharing: 'Activar de paramètres de partatge'
- export: 'Configurar los expòrt'
- import: 'Configurar los impòrt'
+ export: 'Configurar los expòrts'
+ import: 'Configurar los impòrts'
first_steps:
title: 'Primièrs passes'
description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam."
action: 'Suprimir aqueste client'
client:
page_title: 'Gestion dels clients API > Novèl client'
- page_description: "Anatz crear un novèl client. Mercés de cumplir l'url de redireccion cap a vòstra aplicacion."
+ page_description: "Anatz crear un novèl client. Mercés de garnir l'url de redireccion cap a vòstra aplicacion."
form:
name_label: "Nom del client"
redirect_uris_label: 'URLs de redireccion'
page_description: 'Vaquí los paramètres de vòstre client.'
field_name: 'Nom del client'
field_id: 'ID Client'
- field_secret: 'Clau secreta'
+ field_secret: 'Clau secrèta'
back: 'Retour'
read_howto: 'Legir "cossí crear ma primièra aplicacion"'
howto:
delete: 'Suprimir'
delete_confirm: 'Sètz segur ?'
back_to_list: 'Tornar a la lista'
+ search:
+ placeholder: "Filtrar per nom d'utilizaire o corrièl"
error:
page_title: Una error s'es produsida
annotations_reset: Anotacions levadas
tags_reset: Etiquetas levadas
entries_reset: Articles levats
+ archived_reset: Articles archivat suprimits
entry:
notice:
entry_already_saved: 'Article ja salvargardat lo %date%'
annotations: Usuń WSZYSTKIE adnotacje
tags: Usuń WSZYSTKIE tagi
entries: usuń WSZYTSTKIE wpisy
+ # archived: Remove ALL archived entries
confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć)
form_password:
description: "Tutaj możesz zmienić swoje hasło. Twoje nowe hasło powinno mieć conajmniej 8 znaków."
or: 'Jedna reguła LUB inna'
and: 'Jedna reguła I inna'
matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'Adres email'
public_link: 'Publiczny link'
delete_public_link: 'Usuń publiczny link'
- download: 'Pobierz'
+ export: 'Export'
print: 'Drukuj'
problem:
label: 'Problemy'
original_article: 'oryginalny'
annotations_on_the_entry: '{0} Nie ma adnotacji |{1} Jedna adnotacja |]1,Inf[ %count% adnotacji'
created_at: 'Czas stworzenia'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Zapisz nowy wpis'
placeholder: 'http://website.com'
page_title: 'Edytuj wpis'
title_label: 'Tytuł'
url_label: 'Adres URL'
- is_public_label: 'Publiczny'
save_label: 'Zapisz'
public:
shared_by_wallabag: "Ten artykuł został udostępniony przez <a href='%wallabag_instance%'>wallabag</a>"
delete: Usuń
delete_confirm: Jesteś pewien?
back_to_list: Powrót do listy
+ search:
+ # placeholder: Filter by username or email
error:
page_title: Wystąpił błąd
annotations_reset: Zresetuj adnotacje
tags_reset: Zresetuj tagi
entries_reset: Zresetuj wpisy
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Wpis już został dodany %date%'
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
or: 'Uma regra OU outra'
and: 'Uma regra E outra'
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>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'E-mail'
public_link: 'link público'
delete_public_link: 'apagar link público'
- download: 'Download'
+ export: 'Exportar'
print: 'Imprimir'
problem:
label: 'Problemas?'
original_article: 'original'
annotations_on_the_entry: '{0} Sem anotações|{1} Uma anotação|]1,Inf[ %nbAnnotations% anotações'
created_at: 'Data de criação'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Salvar nova entrada'
placeholder: 'http://website.com'
page_title: 'Editar uma entrada'
title_label: 'Título'
url_label: 'Url'
- is_public_label: 'Público'
save_label: 'Salvar'
public:
shared_by_wallabag: "Este artigo foi compartilhado pelo <a href='%wallabag_instance%'>wallabag</a>"
delete: 'Apagar'
delete_confirm: 'Tem certeza?'
back_to_list: 'Voltar para a lista'
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Entrada já foi salva em %date%'
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
# or: 'One rule OR another'
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'E-mail'
# public_link: 'public link'
# delete_public_link: 'delete public link'
- download: 'Descarcă'
+ export: 'Descarcă'
# print: 'Print'
problem:
label: 'Probleme?'
original_article: 'original'
# annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
created_at: 'Data creării'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Salvează un nou articol'
placeholder: 'http://website.com'
# page_title: 'Edit an entry'
# title_label: 'Title'
url_label: 'Url'
- # is_public_label: 'Public'
save_label: 'Salvează'
public:
# shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
# entry_already_saved: 'Entry already saved on %date%'
# annotations: Remove ALL annotations
# tags: Remove ALL tags
# entries: Remove ALL entries
+ # archived: Remove ALL archived entries
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
form_password:
# description: "You can change your password here. Your new password should by at least 8 characters long."
or: 'Bir kural veya birbaşkası'
and: 'Bir kural ve diğeri'
# matches: 'Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
+ # notmatches: 'Tests that a <i>subject</i> is not matches a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
entry:
page_titles:
share_email_label: 'E-posta'
# public_link: 'public link'
# delete_public_link: 'delete public link'
- download: 'İndir'
+ export: 'Dışa Aktar'
# print: 'Print'
problem:
label: 'Bir sorun mu var?'
original_article: 'orijinal'
# annotations_on_the_entry: '{0} No annotations|{1} One annotation|]1,Inf[ %count% annotations'
created_at: 'Oluşturulma tarihi'
+ # published_at: 'Publication date'
+ # published_by: 'Published by'
new:
page_title: 'Yeni makaleyi kaydet'
placeholder: 'http://website.com'
page_title: 'Makaleyi düzenle'
title_label: 'Başlık'
url_label: 'Url'
- is_public_label: 'Herkes tarafından erişime açık olsun mu?'
save_label: 'Kaydet'
public:
# shared_by_wallabag: "This article has been shared by <a href='%wallabag_instance%'>wallabag</a>"
# delete: Delete
# delete_confirm: Are you sure?
# back_to_list: Back to list
+ search:
+ # placeholder: Filter by username or email
error:
# page_title: An error occurred
# annotations_reset: Annotations reset
# tags_reset: Tags reset
# entries_reset: Entries reset
+ # archived_reset: Archived entries deleted
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'
<nav class="hide-on-large-only">
<div class="nav-wrapper cyan darken-1">
<ul>
+ <li>
+ <a href="#" data-activates="slide-out" class="button-collapse">
+ <i class="material-icons">menu</i>
+ </a>
+ </li>
<li>
<a class="waves-effect" href="{{ path('homepage') }}">
<i class="material-icons">exit_to_app</i>
<i class="material-icons small">{% if entry.isStarred == 0 %}star_outline{% else %}star{% endif %}</i>
</a>
</li>
- <li>
- <a href="#" data-activates="slide-out" class="button-collapse right">
- <i class="material-icons">menu</i>
- </a>
- </li>
</ul>
</div>
</nav>
{% endif %}
{% if craue_setting('share_shaarli') %}
<li>
- <a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}&tags={{ entry.tags|join(',')|striptags|url_encode }}" target="_blank">
- <i class="tool icon-image icon-image--shaarli" title="shaarli"></i>
+ <a href="{{ craue_setting('shaarli_url') }}/index.php?post={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}&tags={{ entry.tags|join(',')|striptags|url_encode }}" target="_blank" title="shaarli" class="tool icon-image shaarli">
<span>shaarli</span>
</a>
</li>
{% endif %}
+ {% if craue_setting('share_scuttle') %}
+ <li>
+ <a href="{{ craue_setting('scuttle_url') }}/bookmarks.php?action=add&address={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}&tags={{ entry.tags|join(',')|striptags|url_encode }}" target="_blank" title="scuttle" class="tool icon-image scuttle">
+ <span>scuttle</span>
+ </a>
+ </li>
+ {% endif %}
{% if craue_setting('share_diaspora') %}
<li>
- <a href="{{ craue_setting('diaspora_url') }}/bookmarklet?url={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}&notes=&v=1&noui=1&jump=doclose" target="_blank">
- <i class="tool icon-image icon-image--diaspora" title="diaspora"></i>
+ <a href="{{ craue_setting('diaspora_url') }}/bookmarklet?url={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}&notes=&v=1&noui=1&jump=doclose" target="_blank" class="tool icon-image diaspora" title="diaspora">
<span>diaspora*</span>
</a>
</li>
{% endif %}
{% if craue_setting('share_unmark') %}
<li>
- <a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&title={{entry.title|striptags|url_encode}}&v=6" target="_blank">
- <i class="tool icon-image icon-image--unmark" title="unmark"></i>
+ <a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&title={{entry.title|striptags|url_encode}}&v=6" target="_blank" class="tool icon-image unmark" title="unmark">
<span>unmark.it</span>
</a>
</li>
{% endif %}
{% if craue_setting('carrot') %}
<li>
- <a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}" target="_blank" title="carrot">
- <i class="tool icon-image icon-image--carrot"></i>
+ <a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|striptags|url_encode }}" target="_blank" title="carrot" class="tool icon-image carrot">
<span>Carrot</span>
</a>
</li>
{% endif %}
{% if craue_setting('share_mail') %}
<li>
- <a href="mailto:?subject={{ entry.title|striptags|url_encode }}&body={{ entry.url|url_encode }}%20via%20@wallabagapp" title="{{ 'entry.view.left_menu.share_email_label'|trans }}" class="tool email icon icon-mail">
+ <a href="mailto:?subject={{ entry.title|striptags|url_encode }}&body={{ entry.url|url_encode }}%20via%20@wallabagapp" title="{{ 'entry.view.left_menu.share_email_label'|trans }}" class="tool icon">
+ <i class="material-icons vertical-align-middle">mail</i>
<span>{{ 'entry.view.left_menu.share_email_label'|trans }}</span>
</a>
</li>
<li class="bold">
<a class="waves-effect collapsible-header">
<i class="material-icons small">file_download</i>
- <span>{{ 'entry.view.left_menu.download'|trans }}</span>
+ <span>{{ 'entry.view.left_menu.export'|trans }}</span>
</a>
<div class="collapsible-body">
<ul>
<h1>{{ entry.title|striptags|raw }} <a href="{{ path('edit', { 'id': entry.id }) }}" title="{{ 'entry.view.edit_title'|trans }}">✎</a></h1>
</header>
<aside>
- <ul class="tools">
- <li>
- {% include "@WallabagCore/themes/material/Entry/_reading_time.html.twig" with {'entry': entry} only %}
- </li>
- <li>
- <i class="material-icons" title="{{ 'entry.view.created_at'|trans }}">today</i>
- {{ entry.createdAt|date('Y-m-d') }}
- </li>
- <li>
- <i class="material-icons link">link</i>
- <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|striptags }}" class="tool">
- {{ entry.domainName|removeWww }}
- </a>
- </li>
- <li>
- <i class="material-icons link">comment</i>
- {{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}
- </li>
- <li id="list">
+ <div class="tools">
+ <ul class="stats">
+ <li>
+ {% include "@WallabagCore/themes/material/Entry/_reading_time.html.twig" with {'entry': entry} only %}
+ </li>
+ <li>
+ <i class="material-icons" title="{{ 'entry.view.created_at'|trans }}">today</i>
+ {{ entry.createdAt|date('Y-m-d H:i') }}
+ </li>
+ {% if entry.publishedAt is not null %}
+ <li>
+ <i class="material-icons" title="{{ 'entry.view.published_at'|trans }}">create</i>
+ {{ entry.publishedAt|date('Y-m-d H:i') }}
+ </li>
+ {% endif %}
+ {% if entry.publishedBy is not empty %}
+ <li>
+ <i class="material-icons" title="{{ 'entry.view.published_by'|trans }}">person</i>
+ {% for author in entry.publishedBy %}
+ {{ author }}{% if not loop.last %}, {% endif %}
+ {% endfor %}
+ </li>
+ {% endif %}
+ <li>
+ <i class="material-icons link">link</i>
+ <a href="{{ entry.url|e }}" target="_blank" title="{{ 'entry.view.original_article'|trans }} : {{ entry.title|striptags }}" class="tool">
+ {{ entry.domainName|removeWww }}
+ </a>
+ </li>
+ <li>
+ <i class="material-icons link">comment</i>
+ {{ 'entry.view.annotations_on_the_entry'|transchoice(entry.annotations | length) }}
+ </li>
+ </ul>
+ <ul class="tags">
{% for tag in entry.tags %}
- <div class="chip">
- <a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a> <a href="{{ path('remove_tag', { 'entry': entry.id, 'tag': tag.id }) }}"><i class="material-icons">delete</i></a>
- </div>
+ <li class="chip">
+ <a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{ tag.label }}</a> <a href="{{ path('remove_tag', { 'entry': entry.id, 'tag': tag.id }) }}"><i class="material-icons vertical-align-middle">delete</i></a>
+ </li>
{% endfor %}
- </li>
- </ul>
+ </ul>
+ </div>
<div class="input-field nav-panel-add-tag" style="display: none">
{{ render(controller( "WallabagCoreBundle:Tag:addTagForm", { 'id': entry.id } )) }}
use Tests\Wallabag\ApiBundle\WallabagApiTestCase;
use Wallabag\CoreBundle\Entity\Tag;
+ use Wallabag\CoreBundle\Helper\ContentProxy;
class EntryRestControllerTest extends WallabagApiTestCase
{
$entry = $this->client->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('WallabagCoreBundle:Entry')
- ->findOneByUser(1);
+ ->findOneByUser(1, ['id' => 'asc']);
if (!$entry) {
$this->markTestSkipped('No content found in db.');
$this->assertEquals(false, $content['is_starred']);
$this->assertEquals('New title for my article', $content['title']);
$this->assertEquals(1, $content['user_id']);
- $this->assertCount(1, $content['tags']);
+ $this->assertCount(2, $content['tags']);
}
public function testPostSameEntry()
$this->assertEquals('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']);
$this->assertEquals(true, $content['is_archived']);
$this->assertEquals(false, $content['is_starred']);
- $this->assertCount(2, $content['tags']);
+ $this->assertCount(3, $content['tags']);
}
+ public function testPostEntryWhenFetchContentFails()
+ {
+ /** @var \Symfony\Component\DependencyInjection\Container $container */
+ $container = $this->client->getContainer();
+ $contentProxy = $this->getMockBuilder(ContentProxy::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['updateEntry'])
+ ->getMock();
+ $contentProxy->expects($this->any())
+ ->method('updateEntry')
+ ->willThrowException(new \Exception('Test Fetch content fails'));
+ $container->set('wallabag_core.content_proxy', $contentProxy);
+
+ try {
+ $this->client->request('POST', '/api/entries.json', [
+ 'url' => 'http://www.example.com/',
+ ]);
+
+ $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+ $content = json_decode($this->client->getResponse()->getContent(), true);
+ $this->assertGreaterThan(0, $content['id']);
+ $this->assertEquals('http://www.example.com/', $content['url']);
+ } finally {
+ // Remove the created entry to avoid side effects on other tests
+ if (isset($content['id'])) {
+ $em = $this->client->getContainer()->get('doctrine.orm.entity_manager');
+ $entry = $em->getReference('WallabagCoreBundle:Entry', $content['id']);
+ $em->remove($entry);
+ $em->flush();
+ }
+ }
+ }
+
public function testPostArchivedAndStarredEntry()
{
$this->client->request('POST', '/api/entries.json', [
$content = json_decode($this->client->getResponse()->getContent(), true);
- $this->assertEquals(true, $content['exists']);
+ $this->assertEquals(2, $content['exists']);
}
public function testGetEntriesExistsWithManyUrls()
$this->assertArrayHasKey($url1, $content);
$this->assertArrayHasKey($url2, $content);
- $this->assertEquals(true, $content[$url1]);
+ $this->assertEquals(2, $content[$url1]);
$this->assertEquals(false, $content[$url2]);
}
$this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type'));
}
+
+ public function testPostEntriesTagsListAction()
+ {
+ $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findByUrlAndUserId('http://0.0.0.0/entry4', 1);
+
+ $tags = $entry->getTags();
+
+ $this->assertCount(2, $tags);
+
+ $list = [
+ [
+ 'url' => 'http://0.0.0.0/entry4',
+ 'tags' => 'new tag 1, new tag 2',
+ ],
+ ];
+
+ $this->client->request('POST', '/api/entries/tags/lists?list='.json_encode($list));
+
+ $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+ $content = json_decode($this->client->getResponse()->getContent(), true);
+
+ $this->assertInternalType('int', $content[0]['entry']);
+ $this->assertEquals('http://0.0.0.0/entry4', $content[0]['url']);
+
+ $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findByUrlAndUserId('http://0.0.0.0/entry4', 1);
+
+ $tags = $entry->getTags();
+ $this->assertCount(4, $tags);
+ }
+
+ public function testDeleteEntriesTagsListAction()
+ {
+ $entry = $this->client->getContainer()->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findByUrlAndUserId('http://0.0.0.0/entry4', 1);
+
+ $tags = $entry->getTags();
+
+ $this->assertCount(4, $tags);
+
+ $list = [
+ [
+ 'url' => 'http://0.0.0.0/entry4',
+ 'tags' => 'new tag 1, new tag 2',
+ ],
+ ];
+
+ $this->client->request('DELETE', '/api/entries/tags/list?list='.json_encode($list));
+ }
+
+ public function testPostEntriesListAction()
+ {
+ $list = [
+ 'http://www.lemonde.fr/musiques/article/2017/04/23/loin-de-la-politique-le-printemps-de-bourges-retombe-en-enfance_5115862_1654986.html',
+ 'http://0.0.0.0/entry2',
+ ];
+
+ $this->client->request('POST', '/api/entries/lists?urls='.json_encode($list));
+
+ $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+ $content = json_decode($this->client->getResponse()->getContent(), true);
+
+ $this->assertInternalType('int', $content[0]['entry']);
+ $this->assertEquals('http://www.lemonde.fr/musiques/article/2017/04/23/loin-de-la-politique-le-printemps-de-bourges-retombe-en-enfance_5115862_1654986.html', $content[0]['url']);
+
+ $this->assertInternalType('int', $content[1]['entry']);
+ $this->assertEquals('http://0.0.0.0/entry2', $content[1]['url']);
+ }
+
+ public function testDeleteEntriesListAction()
+ {
+ $list = [
+ 'http://www.lemonde.fr/musiques/article/2017/04/23/loin-de-la-politique-le-printemps-de-bourges-retombe-en-enfance_5115862_1654986.html',
+ 'http://0.0.0.0/entry3',
+ ];
+
+ $this->client->request('DELETE', '/api/entries/list?urls='.json_encode($list));
+
+ $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+ $content = json_decode($this->client->getResponse()->getContent(), true);
+
+ $this->assertTrue($content[0]['entry']);
+ $this->assertEquals('http://www.lemonde.fr/musiques/article/2017/04/23/loin-de-la-politique-le-printemps-de-bourges-retombe-en-enfance_5115862_1654986.html', $content[0]['url']);
+
+ $this->assertFalse($content[1]['entry']);
+ $this->assertEquals('http://0.0.0.0/entry3', $content[1]['url']);
+ }
+
+ public function testLimitBulkAction()
+ {
+ $list = [
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ 'http://0.0.0.0/entry1',
+ ];
+
+ $this->client->request('POST', '/api/entries/lists?urls='.json_encode($list));
+
+ $this->assertEquals(400, $this->client->getResponse()->getStatusCode());
+ $this->assertContains('API limit reached', $this->client->getResponse()->getContent());
+ }
}
->getRepository('WallabagCoreBundle:Entry')
->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
+ $author = $content->getPublishedBy();
+
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
$this->assertEquals($this->url, $content->getUrl());
$this->assertContains('Google', $content->getTitle());
+ $this->assertEquals('2015-03-28 15:37:39', $content->getPublishedAt()->format('Y-m-d H:i:s'));
+ $this->assertEquals('Morgane Tual', $author[0]);
+ $this->assertArrayHasKey('x-varnish1', $content->getHeaders());
+ }
+
+ public function testPostWithMultipleAuthors()
+ {
+ $url = 'http://www.liberation.fr/planete/2017/04/05/donald-trump-et-xi-jinping-tentative-de-flirt-en-floride_1560768';
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/new');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $form = $crawler->filter('form[name=entry]')->form();
+
+ $data = [
+ 'entry[url]' => $url,
+ ];
+
+ $client->submit($form, $data);
+
+ $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+ $content = $client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findByUrlAndUserId($url, $this->getLoggedInUserId());
+
+ $authors = $content->getPublishedBy();
+ $this->assertEquals('2017-04-05 19:26:13', $content->getPublishedAt()->format('Y-m-d H:i:s'));
+ $this->assertEquals('Raphaël Balenieri, correspondant à Pékin', $authors[0]);
+ $this->assertEquals('Frédéric Autran, correspondant à New York', $authors[1]);
}
public function testPostNewOkUrlExist()
->findOneByUrl($url);
$tags = $entry->getTags();
- $this->assertCount(1, $tags);
+ $this->assertCount(2, $tags);
$this->assertEquals('wallabag', $tags[0]->getLabel());
$em->remove($entry);
$tags = $entry->getTags();
- $this->assertCount(1, $tags);
- $this->assertEquals('wallabag', $tags[0]->getLabel());
+ $this->assertCount(2, $tags);
+ $this->assertEquals('wallabag', $tags[1]->getLabel());
$em->remove($entry);
$em->flush();
$this->assertCount(1, $crawler->filter('div[class=entry]'));
}
+ public function testFilterOnReadingTimeWithNegativeValue()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/unread/list');
+
+ $form = $crawler->filter('button[id=submit-filter]')->form();
+
+ $data = [
+ 'entry_filter[readingTime][right_number]' => -22,
+ 'entry_filter[readingTime][left_number]' => -22,
+ ];
+
+ $crawler = $client->submit($form, $data);
+
+ // forcing negative value results in no entry displayed
+ $this->assertCount(0, $crawler->filter('div[class=entry]'));
+ }
+
public function testFilterOnReadingTimeOnlyUpper()
{
$this->logInAs('admin');
$crawler = $client->submit($form, $data);
- $this->assertCount(2, $crawler->filter('div[class=entry]'));
+ $this->assertCount(3, $crawler->filter('div[class=entry]'));
}
public function testFilterOnReadingTimeOnlyLower()
$crawler = $client->submit($form, $data);
- $this->assertCount(4, $crawler->filter('div[class=entry]'));
+ $this->assertCount(5, $crawler->filter('div[class=entry]'));
}
public function testFilterOnCreationDate()
$crawler = $client->submit($form, $data);
- $this->assertCount(5, $crawler->filter('div[class=entry]'));
+ $this->assertCount(6, $crawler->filter('div[class=entry]'));
$data = [
'entry_filter[createdAt][left_date]' => date('d/m/Y'),
$crawler = $client->submit($form, $data);
- $this->assertCount(5, $crawler->filter('div[class=entry]'));
+ $this->assertCount(6, $crawler->filter('div[class=entry]'));
$data = [
'entry_filter[createdAt][left_date]' => '01/01/1970',
$form['entry_filter[previewPicture]']->tick();
$crawler = $client->submit($form);
- $this->assertCount(1, $crawler->filter('div[class=entry]'));
+ $this->assertCount(2, $crawler->filter('div[class=entry]'));
}
public function testFilterOnLanguage()
];
$crawler = $client->submit($form, $data);
- $this->assertCount(2, $crawler->filter('div[class=entry]'));
+ $this->assertCount(3, $crawler->filter('div[class=entry]'));
$form = $crawler->filter('button[id=submit-filter]')->form();
$data = [
$this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $entry);
$this->assertEquals($url, $entry->getUrl());
$this->assertContains('Perpignan', $entry->getTitle());
- $this->assertContains('/d9bc0fcd.jpeg', $entry->getContent());
+ $this->assertContains('/c4789a7f.jpeg', $entry->getContent());
$client->getContainer()->get('craue_config')->set('download_images_enabled', 0);
}
$crawler = $client->submit($form, $data);
- $this->assertCount(1, $crawler->filter('div[class=entry]'));
+ $this->assertCount(2, $crawler->filter('div[class=entry]'));
$crawler = $client->request('GET', '/all/list');
$form = $crawler->filter('button[id=submit-filter]')->form();
$crawler = $client->submit($form, $data);
- $this->assertCount(7, $crawler->filter('div[class=entry]'));
+ $this->assertCount(8, $crawler->filter('div[class=entry]'));
}
public function testSearch()