diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml index 8ee0a3035..fac3b4f87 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Download billeder på din server carrot: Aktiver deling til Carrot diaspora_url: Diaspora URL, hvis tjenesten er aktiv diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml index 73a9d640f..d382733c5 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Bilder auf den Server herunterladen carrot: Teilen zu Carrot aktivieren diaspora_url: Diaspora-URL, sofern der Service aktiviert ist diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml index c8c13805c..23de7a434 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml @@ -1,3 +1,4 @@ +settings_changed: Configuration updated download_pictures: Download pictures on your server carrot: Enable share to Carrot diaspora_url: Diaspora URL, if the service is enabled diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml index 0ea98d8f0..ff1dd04ff 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Descargar imágenes carrot: Activar compartir con Carrot diaspora_url: Diaspora URL, si el servicio está activado diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml index c527b971d..4e712fdde 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: تصاویر را در کارگزار خودتان باربگیرید carrot: فعال‌سازی هم‌رسانی به Carrot diaspora_url: نشانی Diaspora، اگر فعال بود diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml index 176e7c866..cae4c662d 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml @@ -1,3 +1,4 @@ +settings_changed: Configuration mise à jour download_pictures: Télécharger les images sur le serveur carrot: Activer le partage vers Carrot diaspora_url: URL de Diaspora, si le service Diaspora est activé diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml index 621d4dcd8..f94f834f6 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Scarica le immagini sul tuo server carrot: Abilita la condivisione con Carrot diaspora_url: Diaspora URL, se il servizio è abilitato diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml index 04accd454..de60a1948 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Telecargar los imatges sul servidor carrot: Activar lo partatge cap a Carrot diaspora_url: URL de Diaspora, se lo servici Diaspora es activat diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml index 2f4f31547..115797451 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Pobierz obrazy na swój serwer carrot: Włącz udostępnianie dla Carrot diaspora_url: Adres URL Diaspora, jeżeli usługa jest włączona diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml index 5da940e9c..74ae5a44f 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Download imagens no seu servidor carrot: Habilitar compartilhamento para o Carrot diaspora_url: URL Diaspora, se o serviço está habilitado @@ -8,7 +9,8 @@ export_csv: Habilita exportação para CSV export_json: Habilita exportação para JSON export_txt: Habilita exportação para TXT export_xml: Habilita exportação para XML -pocket_consumer_key: Chave de consumidor do Pocket para importar conteúdo (https://getpocket.com/developer/docs/authentication) +# import_with_rabbitmq: Enable RabbitMQ to import data asynchronously +# import_with_redis: Enable Redis to import data asynchronously shaarli_url: URL Shaarli, se o serviço está habilitado share_diaspora: Habilitar compartilhamento para o Diaspora share_mail: Habilitar compartilhamento por e-mail @@ -28,3 +30,5 @@ piwik_site_id: ID de seu website Piwik piwik_enabled: Habilitar Piwik demo_mode_enabled: "Habilitar modo demo? (somente usado para o demo público do wallabag)" demo_mode_username: "Usuário demo" +# share_public: Allow public url for entries +# download_images_enabled: Download images locally diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml index 6d2eaffde..5095dfa00 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated download_pictures: Descarcă poze pe server carrot: Permite share către Carrot diaspora_url: Diaspora URL, dacă serviciul este permis diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml index 9146bfb63..cd42e595d 100644 --- a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml +++ b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml @@ -1,3 +1,4 @@ +# settings_changed: Configuration updated # download_pictures: Download pictures on your server # carrot: Enable share to Carrot # diaspora_url: Diaspora URL, if the service is enabled diff --git a/docs/de/user/configuration.rst b/docs/de/user/configuration.rst index c0a8cd67a..47c60f4c9 100644 --- a/docs/de/user/configuration.rst +++ b/docs/de/user/configuration.rst @@ -52,6 +52,9 @@ Jetzt hast du drei Links, einen für jeden Status: Füge sie in deinem liebsten Du kannst auch definieren wie viele Artikel du in deinem RSS Feed (Standardwert: 50) haben willst. +There is also a pagination available for these feeds. You can add ``?page=2`` to jump to the second page. +The pagination follow `the RFC `_ about that, which means you'll find the ``next``, ``previous`` & ``last`` page link inside the `` tag of each RSS feed. + Benutzer-Informationen ---------------------- diff --git a/docs/en/user/configuration.rst b/docs/en/user/configuration.rst index a52d3ddd9..caca834f2 100644 --- a/docs/en/user/configuration.rst +++ b/docs/en/user/configuration.rst @@ -52,6 +52,9 @@ Now you have three links, one for each status: add them into your favourite RSS You can also define how many articles you want in each RSS feed (default value: 50). +There is also a pagination available for these feeds. You can add ``?page=2`` to jump to the second page. +The pagination follow `the RFC `_ about that, which means you'll find the ``next``, ``previous`` & ``last`` page link inside the `` tag of each RSS feed. + User information ---------------- diff --git a/docs/fr/user/configuration.rst b/docs/fr/user/configuration.rst index 5ce80f58a..025b05bb1 100644 --- a/docs/fr/user/configuration.rst +++ b/docs/fr/user/configuration.rst @@ -53,6 +53,9 @@ Vous avez maintenant trois liens, un par statut : ajoutez-les dans votre agrég Vous pouvez aussi définir combien d'articles vous souhaitez dans vos flux RSS (50 est la valeur par défaut). +Une pagination est aussi disponible pour ces flux. Il suffit de rajouter ``?page=2`` pour aller à la seconde page, par exemple. +Cette pagination suit `la RFC `_, ce qui signifie que vous trouverez la page suivante (``next``), précédente (``previous``) et la dernière (``last``) dans la balise `` de chaque flux RSS. + Mon compte ---------- diff --git a/src/Wallabag/CoreBundle/Controller/RssController.php b/src/Wallabag/CoreBundle/Controller/RssController.php index 38e3b5a0e..2290386f5 100644 --- a/src/Wallabag/CoreBundle/Controller/RssController.php +++ b/src/Wallabag/CoreBundle/Controller/RssController.php @@ -3,12 +3,15 @@ namespace Wallabag\CoreBundle\Controller; use Pagerfanta\Adapter\DoctrineORMAdapter; +use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\UserBundle\Entity\User; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class RssController extends Controller { @@ -20,9 +23,9 @@ class RssController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function showUnreadAction(User $user) + public function showUnreadAction(Request $request, User $user) { - return $this->showEntries('unread', $user); + return $this->showEntries('unread', $user, $request->query->get('page', 1)); } /** @@ -33,9 +36,9 @@ class RssController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function showArchiveAction(User $user) + public function showArchiveAction(Request $request, User $user) { - return $this->showEntries('archive', $user); + return $this->showEntries('archive', $user, $request->query->get('page', 1)); } /** @@ -46,9 +49,9 @@ class RssController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function showStarredAction(User $user) + public function showStarredAction(Request $request, User $user) { - return $this->showEntries('starred', $user); + return $this->showEntries('starred', $user, $request->query->get('page', 1)); } /** @@ -57,10 +60,11 @@ class RssController extends Controller * * @param string $type Entries type: unread, starred or archive * @param User $user + * @param int $page * * @return \Symfony\Component\HttpFoundation\Response */ - private function showEntries($type, User $user) + private function showEntries($type, User $user, $page = 1) { $repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry'); @@ -87,8 +91,26 @@ class RssController extends Controller $perPage = $user->getConfig()->getRssLimit() ?: $this->getParameter('wallabag_core.rss_limit'); $entries->setMaxPerPage($perPage); + $url = $this->generateUrl( + $type.'_rss', + [ + 'username' => $user->getUsername(), + 'token' => $user->getConfig()->getRssToken(), + ], + UrlGeneratorInterface::ABSOLUTE_URL + ); + + try { + $entries->setCurrentPage((int) $page); + } catch (OutOfRangeCurrentPageException $e) { + if ($page > 1) { + return $this->redirect($url.'?page='.$entries->getNbPages(), 302); + } + } + return $this->render('@WallabagCore/themes/common/Entry/entries.xml.twig', [ 'type' => $type, + 'url' => $url, 'entries' => $entries, ]); } diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig index 288bb54f8..16ecaa979 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig @@ -2,7 +2,15 @@ wallabag — {{type}} feed - {{ url('unread') }} + {{ url(type) }} + + {% if entries.hasPreviousPage -%} + + {% endif -%} + {% if entries.hasNextPage -%} + + {% endif -%} + {{ "now"|date('D, d M Y H:i:s') }} wallabag wallabag {{type}} elements diff --git a/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php b/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php index fb6fe06a6..5a59654d3 100644 --- a/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php @@ -6,7 +6,7 @@ use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; class RssControllerTest extends WallabagCoreTestCase { - public function validateDom($xml, $nb = null) + public function validateDom($xml, $type, $nb = null) { $doc = new \DOMDocument(); $doc->loadXML($xml); @@ -22,6 +22,23 @@ class RssControllerTest extends WallabagCoreTestCase $this->assertEquals(1, $xpath->query('/rss')->length); $this->assertEquals(1, $xpath->query('/rss/channel')->length); + $this->assertEquals(1, $xpath->query('/rss/channel/title')->length); + $this->assertEquals('wallabag — '.$type.' feed', $xpath->query('/rss/channel/title')->item(0)->nodeValue); + + $this->assertEquals(1, $xpath->query('/rss/channel/pubDate')->length); + + $this->assertEquals(1, $xpath->query('/rss/channel/generator')->length); + $this->assertEquals('wallabag', $xpath->query('/rss/channel/generator')->item(0)->nodeValue); + + $this->assertEquals(1, $xpath->query('/rss/channel/description')->length); + $this->assertEquals('wallabag '.$type.' elements', $xpath->query('/rss/channel/description')->item(0)->nodeValue); + + $this->assertEquals(1, $xpath->query('/rss/channel/link[@rel="self"]')->length); + $this->assertContains($type.'.xml', $xpath->query('/rss/channel/link[@rel="self"]')->item(0)->getAttribute('href')); + + $this->assertEquals(1, $xpath->query('/rss/channel/link[@rel="last"]')->length); + $this->assertContains($type.'.xml?page=', $xpath->query('/rss/channel/link[@rel="last"]')->item(0)->getAttribute('href')); + foreach ($xpath->query('//item') as $item) { $this->assertEquals(1, $xpath->query('title', $item)->length); $this->assertEquals(1, $xpath->query('source', $item)->length); @@ -77,7 +94,7 @@ class RssControllerTest extends WallabagCoreTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $this->validateDom($client->getResponse()->getContent(), 2); + $this->validateDom($client->getResponse()->getContent(), 'unread', 2); } public function testStarred() @@ -99,7 +116,7 @@ class RssControllerTest extends WallabagCoreTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode(), 1); - $this->validateDom($client->getResponse()->getContent()); + $this->validateDom($client->getResponse()->getContent(), 'starred'); } public function testArchives() @@ -121,6 +138,34 @@ class RssControllerTest extends WallabagCoreTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $this->validateDom($client->getResponse()->getContent()); + $this->validateDom($client->getResponse()->getContent(), 'archive'); + } + + public function testPagination() + { + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagUserBundle:User') + ->findOneByUsername('admin'); + + $config = $user->getConfig(); + $config->setRssToken('SUPERTOKEN'); + $config->setRssLimit(1); + $em->persist($config); + $em->flush(); + + $client = $this->getClient(); + + $client->request('GET', '/admin/SUPERTOKEN/unread.xml'); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->validateDom($client->getResponse()->getContent(), 'unread'); + + $client->request('GET', '/admin/SUPERTOKEN/unread.xml?page=2'); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->validateDom($client->getResponse()->getContent(), 'unread'); + + $client->request('GET', '/admin/SUPERTOKEN/unread.xml?page=3000'); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); } }