]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #2242 from wallabag/fix-minor-css
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Thu, 1 Sep 2016 20:23:45 +0000 (22:23 +0200)
committerGitHub <noreply@github.com>
Thu, 1 Sep 2016 20:23:45 +0000 (22:23 +0200)
Fix print / article views

45 files changed:
.travis.yml
app/Resources/static/themes/material/css/main.css
docs/de/conf.py [new file with mode: 0644]
docs/de/requirements.txt [new file with mode: 0644]
docs/de/user/errors_during_fetching.rst
docs/en/user/errors_during_fetching.rst
docs/en/user/import.rst
docs/fr/user/errors_during_fetching.rst
docs/fr/user/import.rst
src/Wallabag/CoreBundle/Controller/EntryController.php
src/Wallabag/CoreBundle/Controller/ExportController.php
src/Wallabag/CoreBundle/Repository/EntryRepository.php
src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.js [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.min.js [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/_title.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/quickstart.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
src/Wallabag/ImportBundle/Controller/ReadabilityController.php [new file with mode: 0644]
src/Wallabag/ImportBundle/Import/ReadabilityImport.php [new file with mode: 0644]
src/Wallabag/ImportBundle/Resources/config/services.yml
src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml [new file with mode: 0644]
src/Wallabag/UserBundle/Resources/views/Security/login.html.twig
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php
tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php [new file with mode: 0644]
tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php [new file with mode: 0644]
tests/Wallabag/ImportBundle/fixtures/readability-read.json [new file with mode: 0644]
tests/Wallabag/ImportBundle/fixtures/readability.json [new file with mode: 0644]

index 65e7e3047520236450f84b824093b53187e5feba..c343d5ae4f9020126109df2b3d118a42440e380c 100644 (file)
@@ -62,6 +62,7 @@ matrix:
           env: DB=sqlite ASSETS=build
     allow_failures:
         - php: hhvm-3.12
+        - php: 7.1
         - php: nightly
 
 # exclude v1 branches
index b81335eb8257275feb2ba27649f4ca979ff4cbab..d3cd1244fc3887e1ec644728429d8ea065975da5 100755 (executable)
@@ -91,6 +91,7 @@ body {
 
 body.login main {
   padding: 0;
+  min-height: 100vh;
 }
 
 .border-bottom {
@@ -256,6 +257,10 @@ nav input {
   display: none;
 }
 
+input-field.nav-panel-add, .input-field.nav-panel-add form {
+    height: 100%;
+}
+
 /* ==========================================================================
    2 = Side-nav
    ========================================================================== */
@@ -342,6 +347,12 @@ main ul.row {
 
 .card .card-content .card-title {
   line-height: 32px;
+  max-height: 64px;
+  display: block;
+}
+
+.card .card-content i.right, .card .card-reveal i.right {
+    margin-left: 0;
 }
 
 .card .card-entry-labels {
diff --git a/docs/de/conf.py b/docs/de/conf.py
new file mode 100644 (file)
index 0000000..8f2d130
--- /dev/null
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#
+# wallabag documentation build configuration file, created by
+# sphinx-quickstart on Fri Oct 16 06:47:23 2015.
+
+import sys
+import os
+
+extensions = []
+templates_path = ['_templates']
+source_suffix = '.rst'
+master_doc = 'index'
+project = u'wallabag-fr'
+copyright = u'2013-2016, Nicolas Lœuillet - MIT Licence'
+version = '2.0.0'
+release = version
+exclude_patterns = ['_build']
+pygments_style = 'sphinx'
+html_theme = 'default'
+html_static_path = ['_static']
+htmlhelp_basename = 'wallabagdedoc'
+
+latex_elements = {
+}
+
+latex_documents = [
+  ('index', 'wallabag-de.tex', u'wallabag Documentation',
+   u'Nicolas Lœuillet', 'manual'),
+]
+
+man_pages = [
+    ('index', 'wallabagde', u'wallabag Documentation',
+     [u'Nicolas Lœuillet'], 1)
+]
+
+texinfo_documents = [
+  ('index', 'wallabag', u'wallabag Documentation',
+   u'Nicolas Lœuillet', 'wallabag', 'wallabag is an opensource read-it-later.',
+   'Miscellaneous'),
+]
+
+##### Guzzle sphinx theme
+
+import guzzle_sphinx_theme
+html_translator_class = 'guzzle_sphinx_theme.HTMLTranslator'
+html_theme_path = guzzle_sphinx_theme.html_theme_path()
+html_theme = 'guzzle_sphinx_theme'
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+    '**': ['logo-text.html', 'globaltoc.html', 'searchbox.html']
+}
+
+# Register the theme as an extension to generate a sitemap.xml
+extensions.append("guzzle_sphinx_theme")
diff --git a/docs/de/requirements.txt b/docs/de/requirements.txt
new file mode 100644 (file)
index 0000000..06fc897
--- /dev/null
@@ -0,0 +1,2 @@
+Sphinx>=1.3.0,<1.4.0
+guzzle_sphinx_theme>=0.7.0,<0.8.0
index b8e3e9999733292cb7b5c117b2b0ea103a61a60b..296215598da436877c50e341669c046e7ba40170 100644 (file)
@@ -12,7 +12,7 @@ Das kann verschiedene Ursachen haben:
 Wie kann ich helfen das zu beheben?
 -----------------------------------
 
-- `indem du uns eine Mail mit der URL des Artikels sendest <mailto:hello\@wallabag.org>`_
+- `indem du uns eine Mail mit der URL des Artikels sendest <mailto:hello@wallabag.org>`_
 - indem du versuchst das Laden des Artikels durch Erstellen einer Datei für den Artikel
   selbst zu beheben
   Du kannst `dieses Tool <http://siteconfig.fivefilters.org/>`__ nutzen.
index da6ee7450720cf88de219e198835227804a009d5..68892750350409d837bdc3db42f54395d6c1efef 100644 (file)
@@ -12,7 +12,7 @@ There may be several reasons:
 How can I help to fix that?
 ---------------------------
 
-- `by sending us an email with the article's URL <mailto:hello\@wallabag.org>`_
+- `by sending us an email with the article's URL <mailto:hello@wallabag.org>`_
 - by trying to fix this article by yourself :) by creating a file for the article.
   You can use `this tool <http://siteconfig.fivefilters.org/>`__.
 
index 63210484700ccafb0b503707a67b416d9198124d..e6c37d722c48a746357ce408367c477462317337 100644 (file)
@@ -30,14 +30,25 @@ You need to authorize wallabag to interact with your Pocket account.
 Your data will be imported. Data import can be a demanding process for your server
 (we need to work on this import to improve it).
 
-From Instapaper
----------------
-
-*Feature not yet implemented in wallabag v2.*
-
 From Readability
 ----------------
 
+Export your Readability data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On the tools (`https://www.readability.com/tools/<https://www.readability.com/tools/>`_) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).
+
+Import your data into wallabag 2.x
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Click on  ``Import`` link in the menu, on ``Import contents`` in Readability section
+and then select your json file and upload it.
+
+Your data will be imported. Data import can be a demanding process for your server (we need to work on this import to improve it).
+
+From Instapaper
+---------------
+
 *Feature not yet implemented in wallabag v2.*
 
 From HTML or JSON file
index 0f26fbc805df7f11a475aca0e66c5a2129fc8ef7..74290bef405f9dc78d24771b2f32e82fa57021ce 100644 (file)
@@ -12,7 +12,7 @@ Il peut y avoir plusieurs raisons :
 Comment puis-je aider pour réparer ça ?
 ---------------------------------------
 
-- `en nous envoyant un email avec l'URL de l'article <mailto:hello\@wallabag.org>`_
+- `en nous envoyant un email avec l'URL de l'article <mailto:hello@wallabag.org>`_
 - en essayant de réparer cet article par vous-même :) en créant un fichier pour l'article.
   Vous pouvez utiliser `cet outil <http://siteconfig.fivefilters.org/>`__.
 
index e6c2fa02d2092b8baf3e0694ac78b4a360c4c953..99ac602b6313c9f11127b294ff529b39ac507472 100644 (file)
@@ -30,15 +30,27 @@ Vous devez autoriser wallabag à se connecter à votre compte Pocket.
 Vos données vont être importées. L'import de données est une action qui peut être couteuse
 pour votre serveur (nous devons encore travailler pour améliorer cet import).
 
+Depuis Readability
+------------------
+
+Exportez vos données de Readability
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sur la page des outils (`https://www.readability.com/tools/<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.
+
+Importez vos données dans wallabag 2.x
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Cliquez sur le lien ``Importer`` dans le menu, sur  ``Importer les contenus`` dans
+la section Readability et ensuite sélectionnez votre fichier json pour l'uploader.
+
+Vos données vont être importées. L'import de données est une action qui peut être couteuse pour votre serveur (nous devons encore travailler pour améliorer cet import).
+
 Depuis Instapaper
 -----------------
 
 *Fonctionnalité pas encore implémentée dans wallabag v2.*
 
-Depuis Readability
-------------------
-
-*Fonctionnalité pas encore implémentée dans wallabag v2.*
 
 Depuis un fichier HTML ou JSON
 ------------------------------
index d71ba6cd5858df70dbe9afdf7e7a318274b7bc19..624576b5bee67a43be98418a72e5c4ce93831233 100644 (file)
@@ -226,6 +226,10 @@ class EntryController extends Controller
         $repository = $this->get('wallabag_core.entry_repository');
 
         switch ($type) {
+            case 'untagged':
+                $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId());
+
+                break;
             case 'starred':
                 $qb = $repository->getBuilderForStarredByUser($this->getUser()->getId());
                 break;
@@ -523,4 +527,19 @@ class EntryController extends Controller
             ['entry' => $entry]
         );
     }
+
+    /**
+     * Shows untagged articles for current user.
+     *
+     * @param Request $request
+     * @param int     $page
+     *
+     * @Route("/untagged/list/{page}", name="untagged", defaults={"page" = "1"})
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function showUntaggedEntriesAction(Request $request, $page)
+    {
+        return $this->showEntries('untagged', $request, $page);
+    }
 }
index 959b308d8bc0e5cff8bfce213b9e8f50c2970e19..6191d5d7973241f4582007b1db063766856e9f9b 100644 (file)
@@ -46,7 +46,7 @@ class ExportController extends Controller
      *
      * @Route("/export/{category}.{format}", name="export_entries", requirements={
      *     "format": "epub|mobi|pdf|json|xml|txt|csv",
-     *     "category": "all|unread|starred|archive|tag_entries"
+     *     "category": "all|unread|starred|archive|tag_entries|untagged"
      * })
      *
      * @return \Symfony\Component\HttpFoundation\Response
index fada40bbd4c5c8e24010c0b2140e23a6b03ecb35..e5c21679935a51035a9df97a88486a27a6864e0e 100644 (file)
@@ -84,6 +84,22 @@ class EntryRepository extends EntityRepository
         ;
     }
 
+    /**
+     * Retrieves untagged entries for a user.
+     *
+     * @param int $userId
+     *
+     * @return QueryBuilder
+     */
+    public function getBuilderForUntaggedByUser($userId)
+    {
+        return $this
+            ->getBuilderByUser($userId)
+            ->leftJoin('e.tags', 't')
+            ->groupBy('e.id')
+            ->having('count(t.id) = 0');
+    }
+
     /**
      * Find Entries.
      *
diff --git a/src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.js b/src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.js
new file mode 100644 (file)
index 0000000..bf9eade
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *    jQuery tinydot 0.2.0
+ *
+ *    Copyright (c) Alexander Danilov
+ *    modos189.ru
+ *
+ *    Plugin website:
+ *    tinydot.modos189.ru
+ *
+ *    Licensed under the MIT license.
+ *    http://en.wikipedia.org/wiki/MIT_License
+ */
+
+(function( $, undef )
+{
+    if ( $.fn.tinydot )
+    {
+            return;
+    }
+
+    $.fn.tinydot = function( o ) {
+        
+        var $dot = this;
+        $dot.child = getChildOrDie($dot);
+        $dot.orgContent = $($dot.child).html();
+        ellipsis( $dot );
+
+        $dot.watch = function()
+        {
+            $(window).on('resize', function(){
+                if ( watchInt )
+                {
+                    clearInterval( watchInt );
+                }
+                watchInt = setTimeout(
+                    function()
+                    {
+                        reinitialize($dot);
+                    }, 100
+                );
+            });
+            
+            return $dot;
+        };
+    
+        var opts = $.extend( true, {}, $.fn.tinydot.defaults, o ),
+            watchInt = null;
+
+        if ( opts.watch )
+        {
+            $dot.watch();
+        }
+    }
+    
+    // public
+    $.fn.tinydot.defaults = {
+        'watch'               : false
+    };
+    
+    function getChildOrDie( $elem )
+    {
+        var childrens = $elem.children();
+        if (childrens.length == 0) {
+            // create children
+            var data = $($elem).html();
+            $elem.html('');
+            $elem.append('<span />');
+            return $elem.children('span').html(data);
+        } else {
+            return childrens[0];
+        }
+    }
+    
+    function reinitialize( $elem )
+    {
+        $($elem.child).html($elem.orgContent);
+        ellipsis( $elem );
+    }
+    
+    function ellipsis( $elem ) {
+        var divh=$($elem).height();
+        while ($($elem.child).outerHeight()>divh) {
+            $($elem.child).html(function (index, html) {
+                return html.replace(/\W*\s(\S)*$/, '...');
+            });
+        }
+    }
+    
+})( jQuery );
+
+jQuery(document).ready(function($) {
+    //We only invoke jQuery.tinydot on elements that have dot-ellipsis class
+    $(".dot-ellipsis").each(function(){
+        //Checking if update on window resize required
+        var watch_window=$(this).hasClass("dot-resize-update");
+
+        //Invoking jQuery.tinydot
+        var x = new Object();
+        if (watch_window)
+                x.watch='window';
+        $(this).tinydot(x);
+    });
+});
diff --git a/src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.min.js b/src/Wallabag/CoreBundle/Resources/public/themes/material/js/jquery.tinydot.min.js
new file mode 100644 (file)
index 0000000..7475462
--- /dev/null
@@ -0,0 +1 @@
+!function(a,b){function c(b){var c=b.children();if(0==c.length){var d=a(b).html();return b.html(""),b.append("<span />"),b.children("span").html(d)}return c[0]}function d(b){a(b.child).html(b.orgContent),e(b)}function e(b){for(var c=a(b).height();a(b.child).outerHeight()>c;)a(b.child).html(function(a,b){return b.replace(/\W*\s(\S)*$/,"...")})}a.fn.tinydot||(a.fn.tinydot=function(b){var f=this;f.child=c(f),f.orgContent=a(f.child).html(),e(f),f.watch=function(){return a(window).on("resize",function(){h&&clearInterval(h),h=setTimeout(function(){d(f)},100)}),f};var g=a.extend(!0,{},a.fn.tinydot.defaults,b),h=null;g.watch&&f.watch()},a.fn.tinydot.defaults={watch:!1})}(jQuery),jQuery(document).ready(function(a){a(".dot-ellipsis").each(function(){var b=a(this).hasClass("dot-resize-update"),c=new Object;b&&(c.watch="window"),a(this).tinydot(c)})});
index f9b7bfacdac8c9a93aeb541527f77eaf1dbb5e94..073dee28e674ac1c6bdd335f5fc5ec99ae13ae4a 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'estimeret læsetid'
@@ -291,6 +292,7 @@ quickstart:
     #     pocket: 'Migrate from Pocket'
     #     wallabag_v1: 'Migrate from wallabag v1'
     #     wallabag_v2: 'Migrate from wallabag v2'
+    #     readability: 'Migrate from Readability'
     # developer:
     #     title: 'Developers'
     #     create_application: 'Create your third application'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tags'
     list:
         # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     # page_title: 'Import'
@@ -339,6 +342,10 @@ import:
     # wallabag_v2:
     #     page_title: 'Import > Wallabag v2'
     #     description: 'This importer will import all your wallabag v2 articles. Go to All articles, then, on the export sidebar, click on "JSON". You will have a "All articles.json" file.'
+    # readability:
+    #     page_title: 'Import > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     # page_title: 'Developer'
index 79d03286bdc7e989784168b8dc534fcd0b686cc8..4cfd240f46b0e33438b73f807a5c05fbaf9f7dd9 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Archivierte Einträge'
         filtered: 'Gefilterte Einträge'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
         reading_time: 'geschätzte Lesezeit'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'von Pocket migrieren'
         wallabag_v1: 'von wallabag v1 migrieren'
         wallabag_v2: 'von wallabag v2 migrieren'
+        readability: 'von Readability migrieren'
     developer:
         title: 'Entwickler'
         create_application: 'Erstelle eine Anwendung und nutze die wallabag API'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: '{0} Es gibt keine Tags.|{1} Es gibt einen Tag.|]1,Inf[ Es gibt %count% Tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importieren'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Aus wallabag v2 importieren'
         description: 'Dieser Import wird all deine Artikel aus wallabag v2 importieren. Gehe auf "Alle Artikel" und dann, in der Exportieren-Seitenleiste auf "JSON". Dabei erhältst du eine "All articles.json"-Datei.'
+    readability:
+        page_title: 'Aus Readability importieren'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     page_title: 'Entwickler'
index d921b39f9579a9cac1123a45dc3f7d96fe8d71ef..42374b40e9e211fd025a07541907bf7763664cb8 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Archived entries'
         filtered: 'Filtered entries'
         filtered_tags: 'Filtered by tags'
+        untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'estimated reading time'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'Migrate from Pocket'
         wallabag_v1: 'Migrate from wallabag v1'
         wallabag_v2: 'Migrate from wallabag v2'
+        readability: 'Migrate from Readability'
     developer:
         title: 'Developers'
         create_application: 'Create your third application'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Import'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Import > Wallabag v2'
         description: 'This importer will import all your wallabag v2 articles. Go to All articles, then, on the export sidebar, click on "JSON". You will have a "All articles.json" file.'
+    readability:
+        page_title: 'Import > Readability'
+        description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+        how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     page_title: 'Developer'
index c2ec4dbd77fae8227a168c2420cde87737d4ae70..ee84cc62ff0e2196363eddafe95876ad3244b5d0 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Artículos archivados'
         filtered: 'Artículos filtrados'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
         reading_time: 'tiempo estimado de lectura'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'Migrar desde Pocket'
         wallabag_v1: 'Migrar desde wallabag v1'
         wallabag_v2: 'Migrar desde wallabag v2'
+        readability: 'Migrar desde Readability'
     developer:
         title: 'Promotores'
         create_application: 'Cree su tercera aplicación'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Etiquetas'
     list:
         number_on_the_page: '{0} No hay ninguna etiqueta.|{1} Hay una etiqueta.|]1,Inf[ Hay %count% etiquetas.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importar'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Importar > Wallabag v2'
         description: 'Va a importar sus artículos de otra instancia de wallabag v2. Vaya a Todos los artículos, entonces, en la barra lateral, oprima en "JSON". Usted tendrá un fichero "All articles.json"'
+    readability:
+        page_title: 'Importar > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     page_title: 'Promotor'
index 561ed907487675070e5677cbffc0e84780f85100..e9af1e8d139e2b1b0af45b916164451a6782e3d1 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'مقاله‌های بایگانی‌شده'
         filtered: 'مقاله‌های فیلترشده'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
         reading_time: 'زمان تخمینی برای خواندن'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'مهاجرت از Pocket'
         wallabag_v1: 'مهاجرت از نسخهٔ یکم wallabag'
         wallabag_v2: 'مهاجرت از نسخهٔ دوم wallabag'
+        readability: 'مهاجرت از نسخهٔ دوم Readability'
     developer:
         title: 'برنامه‌نویسان'
         create_application: 'برنامهٔ wallabag خود را بسازید'
@@ -312,18 +314,19 @@ tag:
     page_title: 'برچسب‌ها'
     list:
         number_on_the_page: '{0} هیچ برچسبی نیست.|{1} یک برچسب هست.|]1,Inf[ %count% برچسب هست.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
-     page_title: 'درون‌ریزی'
-     page_description: 'به درون‌ریز wallabag خوش آمدید. لطفاً سرویس قبلی خود را که می‌خواهید از آن مهاجرت کنید انتخاب کنید.'
-     action:
+    page_title: 'درون‌ریزی'
+    page_description: 'به درون‌ریز wallabag خوش آمدید. لطفاً سرویس قبلی خود را که می‌خواهید از آن مهاجرت کنید انتخاب کنید.'
+    action:
         import_contents: 'درون‌ریزی مقاله‌ها'
-     form:
+    form:
         mark_as_read_title: 'علامت‌زدن همه به عنوان خوانده‌شده؟'
         mark_as_read_label: 'همهٔ مقاله‌های درون‌ریزی شده را به عنوان خوانده‌شده علامت بزن'
         file_label: 'پرونده'
         save_label: 'بارگذاری پرونده'
-     pocket:
+    pocket:
         page_title: 'درون‌ریزی > Pocket'
         description: "این برنامه همهٔ داده‌های Pocket شما را درون‌ریزی می‌کند. سرویس Pocket اجازه نمی‌دهد که متن مقاله‌ها را درون‌ریزی کنیم، بنابراین wallabag متن مقاله‌ها را دوباره از اینترنت دریافت می‌کند."
         config_missing:
@@ -332,13 +335,17 @@ import:
            user_message: 'مدیر سرور شما باید یک API Key برای Pocket تعریف کند.'
         authorize_message: 'شما می‌توانید داده‌هایتان را از حساب Pocket خود درون‌ریزی کنید. روی دکمهٔ زیر کلیک کنید و به برنامه اجازه دهید تا به getpocket.com وصل شود.'
         connect_to_pocket: 'به Pocket وصل شو و داده‌ها را دریافت کن'
-     wallabag_v1:
+    wallabag_v1:
         page_title: 'درون‌ریزی > Wallabag v1'
         description: 'این برنامه همهٔ داده‌های شما را در نسخهٔ ۱ wallabag درون‌ریزی می‌کند. در صفحهٔ تنظیمات، روی "JSON export" در بخش "Export your wallabag data" کلیک کنید. با این کار شما پرونده‌ای به شکل "wallabag-export-1-xxxx-xx-xx.json" دریافت خواهید کرد.'
         how_to: 'لطفاً پرونده را انتخاب کنید و روی دکمهٔ زیر کلیک کنید تا بارگذاری و درون‌ریزی شود.'
-     wallabag_v2:
+    wallabag_v2:
         page_title: 'درون‌ریزی > Wallabag v2'
         description: 'این برنامه همهٔ داده‌های شما را در نسخهٔ ۲ wallabag درون‌ریزی می‌کند. به بخش «همهٔ مقاله‌ها» بروید و در بخش «برون‌ریزی» روی "JSON" کلیک کنید. با این کار شما پرونده‌ای به شکل "All articles.json" دریافت خواهید کرد.'
+    readability:
+        page_title: 'درون‌ریزی > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     # page_title: 'Developer'
index c0671883ab9432c86d85d8a396f7ab226eb1261f..402cdf4a6736b6d430e7c3caeaf0f1bf74d79285 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Articles lus'
         filtered: 'Articles filtrés'
         filtered_tags: 'Articles filtrés par tags'
+        untagged: 'Article sans tag'
     list:
         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."
         reading_time: 'durée de lecture'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'Migrer depuis Pocket'
         wallabag_v1: 'Migrer depuis wallabag v1'
         wallabag_v2: 'Migrer depuis wallabag v2'
+        readability: 'Migrer depuis Readability'
     developer:
         title: 'Pour les développeurs'
         create_application: 'Créer votre application tierce'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tags'
     list:
         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'
 
 import:
     page_title: 'Importer'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Importer > Wallabag v2'
         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\""
+    readability:
+        page_title: 'Importer > Readability'
+        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.'
+        how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l'importer."
 
 developer:
     page_title: 'Développeur'
index 2e3dd08b0c82680b706badc54e1d7039367691d1..3aee4816727db48824101bcedfa0eabe33613dbc 100644 (file)
@@ -139,6 +139,8 @@ entry:
         starred: 'Contenuti preferiti'
         archived: 'Contenuti archiviati'
         filtered: 'Contenuti filtrati'
+        # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
         reading_time: 'tempo di lettura stimato'
@@ -289,6 +291,7 @@ quickstart:
         pocket: 'Trasferisci da Pocket'
         wallabag_v1: 'Trasferisci da wallabag v1'
         wallabag_v2: 'Trasferisci da wallabag v2'
+        readability: 'Trasferisci da Readability'
     developer:
         title: 'Sviluppatori'
         create_application: 'Crea la tua applicazione'
@@ -310,6 +313,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag."
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importa'
@@ -337,6 +341,10 @@ import:
     wallabag_v2:
         page_title: 'Importa da > Wallabag v2'
         description: 'Questo importatore copierà tutti i tuoi dati da un wallabag v2. Vai in "Tutti i contenuti", e, nella sidebar di esportazione, clicca su "JSON". Otterrai un file "Tutti i contenuti.json".'
+    readability:
+        page_title: 'Importa da > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     page_title: 'Sviluppatori'
index 7b978a609eadf0abaccb477ea746e3ace0dc8922..855f236152b7cb86fdfa73287b4d3b05fad88e26 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Articles legits'
         filtered: 'Articles filtrats'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
         reading_time: 'durada de lectura'
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'Migrar dempuèi Pocket'
         wallabag_v1: 'Migrar dempuèi wallabag v1'
         wallabag_v2: 'Migrar dempuèi wallabag v2'
+        readability: 'Migrar dempuèi Readability'
     developer:
         title: 'Pels desvolopadors'
         create_application: 'Crear vòstra aplicacion tèrça'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Etiquetas'
     list:
         number_on_the_page: "{0} I a pas cap d'etiquetas.|{1} I a una etiqueta.|]1,Inf[ I a %count% etiquetas."
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importar'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Importer > Wallabag v2'
         description: "Aquesta aisina importarà totas vòstras donadas d'una instància mai de wallabag v2. Anatz dins totes vòstres articles, puèi, sus la barra laterala, clicatz sus \"JSON\". Traparatz un fichièr \"All articles.json\""
+    readability:
+        page_title: 'Importer > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     page_title: 'Desvolopador'
index da170e4d64cd50459bdadfebd43842d947a24407..da50cd4cd84e7b5ee9569cc91d18f7f0b8e80455 100644 (file)
@@ -139,13 +139,14 @@ entry:
         starred: 'Wpisy oznaczone gwiazdką'
         archived: 'Zarchiwizowane wpisy'
         filtered: 'Odfiltrowane wpisy'
-        # filtered_tags: 'Filtered by tags'
+        filtered_tags: 'Filtrowane po tagach'
+        untagged: 'Odtaguj wpisy'
     list:
         number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
         reading_time: 'szacunkowy czas czytania'
         reading_time_minutes: 'szacunkowy czas czytania: %readingTime% min'
         reading_time_less_one_minute: 'szacunkowy czas czytania: <small class="inferieur">&lt;</small> 1 min'
-        # number_of_tags: '{1}and one other tag|]1,Inf[and %count% other tags'
+        number_of_tags: '{1} i inny tag|]1,Inf[i %count% innych tagów'
         reading_time_minutes_short: '%readingTime% min'
         reading_time_less_one_minute_short: '<small class="inferieur">&lt;</small> 1 min'
         original_article: 'oryginał'
@@ -187,8 +188,8 @@ entry:
             add_a_tag: 'Dodaj tag'
             share_content: 'Udostępnij'
             share_email_label: 'Adres email'
-            # public_link: 'public link'
-            # delete_public_link: 'delete public link'
+            public_link: 'Publiczny link'
+            delete_public_link: 'Usuń publiczny link'
             download: 'Pobierz'
             print: 'Drukuj'
             problem:
@@ -291,6 +292,7 @@ quickstart:
         pocket: 'Migruj z Pocket'
         wallabag_v1: 'Migruj z wallabag v1'
         wallabag_v2: 'Migruj z wallabag v2'
+        readability: 'Migruj z Readability'
     developer:
         title: 'Deweloperzy'
         create_application: 'Stwórz swoją aplikację'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tagi'
     list:
         number_on_the_page: '{0} Nie ma tagów.|{1} Jest jeden tag.|]1,Inf[ Są %count% tagi.'
+        see_untagged_entries: 'Zobacz nieotagowane wpisy'
 
 import:
     page_title: 'Import'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'Import > Wallabag v2'
         description: 'Ten importer, zaimportuje wszystkie twoje artykułu z wallabag v2. Idź do wszystkich artykułów, a następnie na panelu exportu kliknij na "JSON". Otrzymasz plik "All articles.json".'
+    readability:
+        page_title: 'Import > Readability'
+        description: 'Ten importer, zaimportuje wszystkie twoje artykuły z Readability. Na stronie narzędzi (https://www.readability.com/tools/), kliknij na "Export your data" w sekcji "Data Export". Otrzymach email z plikiem JSON (plik nie będzie zawierał rozszerzenia .json).'
+        how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.'
 
 developer:
     page_title: 'Deweloper'
@@ -346,7 +353,7 @@ developer:
     documentation: 'Dokumentacja'
     how_to_first_app: 'Jak stworzyć moją pierwszą aplikację'
     full_documentation: 'Pokaż pełne API'
-    # list_methods: 'List API methods'
+    list_methods: 'Lista metod API'
     clients:
          title: 'Klienci'
          create_new: 'Utwórz nowego klienta'
@@ -404,7 +411,7 @@ flashes:
         notice:
             entry_already_saved: 'Wpis już został dodany %date%'
             entry_saved: 'Wpis zapisany'
-            # entry_saved_failed: 'Failed to save entry'
+            entry_saved_failed: 'Zapis artykułu się nie powiódł'
             entry_updated: 'Wpis zaktualizowany'
             entry_reloaded: 'Wpis ponownie załadowany'
             entry_reload_failed: 'Błąd ponownego załadowania'
index fa2d6468cd8b253c1e6031c5b83c99bbf008d3eb..f41609d02db0427f0d6a3579d2b1a36cb42a2639 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'timp estimat de citire'
@@ -291,6 +292,7 @@ quickstart:
     #     pocket: 'Migrate from Pocket'
     #     wallabag_v1: 'Migrate from wallabag v1'
     #     wallabag_v2: 'Migrate from wallabag v2'
+    #     readability: 'Migrate from Readability'
     # developer:
     #     title: 'Developers'
     #     create_application: 'Create your third application'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Tag-uri'
     list:
         # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     # page_title: 'Import'
@@ -339,6 +342,10 @@ import:
     # wallabag_v2:
     #     page_title: 'Import > Wallabag v2'
     #     description: 'This importer will import all your wallabag v2 articles. Go to All articles, then, on the export sidebar, click on "JSON". You will have a "All articles.json" file.'
+    # readability:
+    #     page_title: 'Import > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     # page_title: 'Developer'
index 05c31336fb8d8f204b7ec47e349c53a288cbfac1..6dfbfa8960afbe5369bc2ebfd89a150ecb6b7cbe 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
         reading_time: 'tahmini okuma süresi'
@@ -291,6 +292,7 @@ quickstart:
         pocket: "Pocket üzerindeki verilerinizi wallabag'e aktarın"
         wallabag_v1: "wallabag v1 üzerindeki verilerinizi wallabag'in yeni sürümüne aktarın"
         wallabag_v2: "wallabag v2 üzerindeki verilerinizi wallabag'in yeni sürümüne aktarın"
+        readability: "Readability üzerindeki verilerinizi wallabag'e aktarın'"
     developer:
         # title: 'Developers'
         # create_application: 'Create your third application'
@@ -312,6 +314,7 @@ tag:
     page_title: 'Etiketler'
     list:
         number_on_the_page: '{0} Herhangi bir etiket yok.|{1} Burada bir adet etiket var.|]1,Inf[ Burada %count% adet etiket var.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'İçe Aktar'
@@ -339,6 +342,10 @@ import:
     wallabag_v2:
         page_title: 'İçe Aktar > Wallabag v2'
         # description: 'This importer will import all your wallabag v2 articles. Go to All articles, then, on the export sidebar, click on "JSON". You will have a "All articles.json" file.'
+    readability:
+        page_title: 'İçe Aktar > Readability'
+    #     description: 'This importer will import all your Readability articles. On the tools (https://www.readability.com/tools/) page, click on "Export your data" in the "Data Export" section. You will received an email to download a json (which does not end with .json in fact).'
+    #     how_to: 'Please select your Readability export and click on the below button to upload and import it.'
 
 developer:
     # page_title: 'Developer'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/_title.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/_title.html.twig
new file mode 100644 (file)
index 0000000..d1c2f20
--- /dev/null
@@ -0,0 +1,15 @@
+{% set currentRoute = app.request.attributes.get('_route') %}
+
+{% if currentRoute == 'starred' %}
+    {{ 'entry.page_titles.starred'|trans }}
+{% elseif currentRoute == 'archive' %}
+    {{ 'entry.page_titles.archived'|trans }}
+{% elseif currentRoute == 'all' %}
+    {{ 'entry.page_titles.filtered'|trans }}
+{% elseif currentRoute == 'tag_entries' %}
+    {{ 'entry.page_titles.filtered_tags'|trans }}
+{% elseif currentRoute == 'untagged' %}
+    {{ 'entry.page_titles.untagged'|trans }}
+{% else %}
+    {{ 'entry.page_titles.unread'|trans }}
+{% endif %}
index 9380e67afbf38ba548a6014bb00946be39898107..1554cce4789b33c9cebaee7f3394e5573feadd5f 100644 (file)
@@ -1,19 +1,7 @@
 {% extends "WallabagCoreBundle::layout.html.twig" %}
 
 {% block title %}
-    {% set currentRoute = app.request.attributes.get('_route') %}
-
-    {% if currentRoute == 'starred' %}
-        {{ 'entry.page_titles.starred'|trans }}
-    {% elseif currentRoute == 'archive' %}
-        {{ 'entry.page_titles.archived'|trans }}
-    {% elseif currentRoute == 'all' %}
-        {{ 'entry.page_titles.filtered'|trans }}
-    {% elseif currentRoute == 'tag_entries' %}
-        {{ 'entry.page_titles.filtered_tags'|trans }}
-    {% else %}
-        {{ 'entry.page_titles.unread'|trans }}
-    {% endif %}
+    {% include "@WallabagCore/themes/_title.html.twig" %}
 {% endblock %}
 
 {% block content %}
index b3d3d5a08cb7305ad656744781292cda3237a5fc..ea1c1cbec6189e593f7b0ada7271a171b09db302 100644 (file)
@@ -39,6 +39,7 @@
         <li><a href="{{ path('import_pocket') }}">{{ 'quickstart.migrate.pocket'|trans }}</a></li>
         <li><a href="{{ path('import_wallabag_v1') }}">{{ 'quickstart.migrate.wallabag_v1'|trans }}</a></li>
         <li><a href="{{ path('import_wallabag_v2') }}">{{ 'quickstart.migrate.wallabag_v2'|trans }}</a></li>
+        <li><a href="{{ path('import_readability') }}">{{ 'quickstart.migrate.readability'|trans }}</a></li>
     </ul>
 
     <h4>{{ 'quickstart.developer.title'|trans }}</h4>
index 739e14864e1ab79b06165e55858f5a8b3ceae45a..50043907a1ee54d5f86d615f3d848d931cc15e43 100644 (file)
@@ -12,4 +12,8 @@
         <li id="tag-{{ tag.id|e }}"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li>
     {% endfor %}
     </ul>
+
+    <div>
+        <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a>
+    </div>
 {% endblock %}
index 2a972e1cf17edb9707b572a03611b6a5a239439e..806a4eefe795473bb3d882c06c20d524efd9a443 100644 (file)
@@ -1,19 +1,7 @@
 {% extends "WallabagCoreBundle::layout.html.twig" %}
 
 {% block title %}
-  {% set currentRoute = app.request.attributes.get('_route') %}
-
-  {% if currentRoute == 'starred' %}
-    {{ 'entry.page_titles.starred'|trans }}
-  {% elseif currentRoute == 'archive' %}
-    {{ 'entry.page_titles.archived'|trans }}
-  {% elseif currentRoute == 'all' %}
-    {{ 'entry.page_titles.filtered'|trans }}
-  {% elseif currentRoute == 'tag_entries' %}
-      {{ 'entry.page_titles.filtered_tags'|trans }}
-  {% else %}
-    {{ 'entry.page_titles.unread'|trans }}
-  {% endif %}
+  {% include "@WallabagCore/themes/_title.html.twig" %}
 {% endblock %}
 
 {% block content %}
@@ -41,7 +29,7 @@
                                 <i class="card-title grey-text text-darken-4 activator material-icons right">more_vert</i>
                             {% endif %}
 
-                            <span class="card-title"><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|striptags }}">{{ entry.title|striptags|raw }}</a></span>
+                            <span class="card-title dot-ellipsis dot-resize-update"><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|raw }}">{{ entry.title|striptags|raw }}</a></span>
 
                             <div class="estimatedTime grey-text">
                                 <span class="tool reading-time">
index 59dd037b85bcbe85009d4957633506683dc9f45c..8cbf4ab40b82c574db6f504b3a8b23982b73e594 100644 (file)
@@ -44,6 +44,7 @@
                         <li><a href="{{ path('import_pocket') }}">{{ 'quickstart.migrate.pocket'|trans }}</a></li>
                         <li><a href="{{ path('import_wallabag_v1') }}">{{ 'quickstart.migrate.wallabag_v1'|trans }}</a></li>
                         <li><a href="{{ path('import_wallabag_v2') }}">{{ 'quickstart.migrate.wallabag_v2'|trans }}</a></li>
+                        <li><a href="{{ path('import_readability') }}">{{ 'quickstart.migrate.readability'|trans }}</a></li>
                     </ul>
 
                     <h4>{{ 'quickstart.developer.title'|trans }}</h4>
index 9495f5436d2f996f1ceee825fb75fd2f83d4fde4..1690633a531150656a2c388a5c2574899f35e6c2 100644 (file)
@@ -12,4 +12,7 @@
         <li id="tag-{{ tag.id|e }}" class="col l4 m6 s12"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li>
     {% endfor %}
     </ul>
+    <div>
+        <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a>
+    </div>
 {% endblock %}
index 50134357f942a47327a10b8c146f80c3244d94ea..6e95345ce6459ccd6281832487762edbebf93ad1 100644 (file)
@@ -7,7 +7,9 @@
 
 {% block scripts %}
     {{ parent() }}
-    <script src="{{ asset('bundles/wallabagcore/themes/material/js/material.min.js') }}"></script>
+    <script src="{{ asset('bundles/wallabagcore/themes/material/js/jquery.tinydot.min.js') }}"></script>
+    <script src="{{ asset('bundles/wallabagcore/themes/material/js/materialize.min.js') }}"></script>
+    <script src="{{ asset('bundles/wallabagcore/themes/material/js/init.js') }}"></script>
 {% endblock %}
 
 {% block header %}
diff --git a/src/Wallabag/ImportBundle/Controller/ReadabilityController.php b/src/Wallabag/ImportBundle/Controller/ReadabilityController.php
new file mode 100644 (file)
index 0000000..b61aa99
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wallabag\ImportBundle\Controller;
+
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Symfony\Component\HttpFoundation\Request;
+use Wallabag\ImportBundle\Form\Type\UploadImportType;
+
+class ReadabilityController extends Controller
+{
+    /**
+     * @Route("/readability", name="import_readability")
+     */
+    public function indexAction(Request $request)
+    {
+        $form = $this->createForm(UploadImportType::class);
+        $form->handleRequest($request);
+
+        $readability = $this->get('wallabag_import.readability.import');
+
+        if ($form->isValid()) {
+            $file = $form->get('file')->getData();
+            $markAsRead = $form->get('mark_as_read')->getData();
+            $name = 'readability_'.$this->getUser()->getId().'.json';
+
+            if (in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
+                $res = $readability
+                    ->setUser($this->getUser())
+                    ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
+                    ->setMarkAsRead($markAsRead)
+                    ->import();
+
+                $message = 'flashes.import.notice.failed';
+
+                if (true === $res) {
+                    $summary = $readability->getSummary();
+                    $message = $this->get('translator')->trans('flashes.import.notice.summary', [
+                        '%imported%' => $summary['imported'],
+                        '%skipped%' => $summary['skipped'],
+                    ]);
+
+                    unlink($this->getParameter('wallabag_import.resource_dir').'/'.$name);
+                }
+
+                $this->get('session')->getFlashBag()->add(
+                    'notice',
+                    $message
+                );
+
+                return $this->redirect($this->generateUrl('homepage'));
+            } else {
+                $this->get('session')->getFlashBag()->add(
+                    'notice',
+                    'flashes.import.notice.failed_on_file'
+                );
+            }
+        }
+
+        return $this->render('WallabagImportBundle:Readability:index.html.twig', [
+            'form' => $form->createView(),
+            'import' => $readability,
+        ]);
+    }
+}
diff --git a/src/Wallabag/ImportBundle/Import/ReadabilityImport.php b/src/Wallabag/ImportBundle/Import/ReadabilityImport.php
new file mode 100644 (file)
index 0000000..37b160c
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+
+namespace Wallabag\ImportBundle\Import;
+
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\UserBundle\Entity\User;
+
+class ReadabilityImport extends AbstractImport
+{
+    private $user;
+    private $skippedEntries = 0;
+    private $importedEntries = 0;
+    private $filepath;
+    private $markAsRead;
+
+    /**
+     * We define the user in a custom call because on the import command there is no logged in user.
+     * So we can't retrieve user from the `security.token_storage` service.
+     *
+     * @param User $user
+     */
+    public function setUser(User $user)
+    {
+        $this->user = $user;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'Readability';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getUrl()
+    {
+        return 'import_readability';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDescription()
+    {
+        return 'import.readability.description';
+    }
+
+    /**
+     * Set file path to the json file.
+     *
+     * @param string $filepath
+     */
+    public function setFilepath($filepath)
+    {
+        $this->filepath = $filepath;
+
+        return $this;
+    }
+
+    /**
+     * Set whether articles must be all marked as read.
+     *
+     * @param bool $markAsRead
+     */
+    public function setMarkAsRead($markAsRead)
+    {
+        $this->markAsRead = $markAsRead;
+
+        return $this;
+    }
+
+    /**
+     * Get whether articles must be all marked as read.
+     */
+    public function getMarkAsRead()
+    {
+        return $this->markAsRead;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSummary()
+    {
+        return [
+            'skipped' => $this->skippedEntries,
+            'imported' => $this->importedEntries,
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function import()
+    {
+        if (!$this->user) {
+            $this->logger->error('ReadabilityImport: user is not defined');
+
+            return false;
+        }
+
+        if (!file_exists($this->filepath) || !is_readable($this->filepath)) {
+            $this->logger->error('ReadabilityImport: unable to read file', ['filepath' => $this->filepath]);
+
+            return false;
+        }
+
+        $data = json_decode(file_get_contents($this->filepath), true);
+
+        if (empty($data) || empty($data['bookmarks'])) {
+            return false;
+        }
+
+        $this->parseEntries($data['bookmarks']);
+
+        return true;
+    }
+
+    /**
+     * Parse and insert all given entries.
+     *
+     * @param $entries
+     */
+    protected function parseEntries($entries)
+    {
+        $i = 1;
+
+        foreach ($entries as $importedEntry) {
+            $existingEntry = $this->em
+                ->getRepository('WallabagCoreBundle:Entry')
+                ->findByUrlAndUserId($importedEntry['article__url'], $this->user->getId());
+
+            if (false !== $existingEntry) {
+                ++$this->skippedEntries;
+                continue;
+            }
+
+            $data = [
+                'title' => $importedEntry['article__title'],
+                'url' => $importedEntry['article__url'],
+                'content_type' => '',
+                'language' => '',
+                'is_archived' => $importedEntry['archive'] || $this->markAsRead,
+                'is_starred' => $importedEntry['favorite'],
+            ];
+
+            $entry = $this->fetchContent(
+                new Entry($this->user),
+                $data['url'],
+                $data
+            );
+
+            // jump to next entry in case of problem while getting content
+            if (false === $entry) {
+                ++$this->skippedEntries;
+                continue;
+            }
+            $entry->setArchived($data['is_archived']);
+            $entry->setStarred($data['is_starred']);
+
+            $this->em->persist($entry);
+            ++$this->importedEntries;
+
+            // flush every 20 entries
+            if (($i % 20) === 0) {
+                $this->em->flush();
+                $this->em->clear($entry);
+            }
+            ++$i;
+        }
+
+        $this->em->flush();
+    }
+}
index 86b44cb3e8fbf0bebac1fc4741983efc20c5094f..520d43aff9d0a30519d67923b8b2cc5ea2b22e65 100644 (file)
@@ -43,3 +43,13 @@ services:
             - [ setLogger, [ "@logger" ]]
         tags:
             -  { name: wallabag_import.import, alias: wallabag_v2 }
+
+    wallabag_import.readability.import:
+        class: Wallabag\ImportBundle\Import\ReadabilityImport
+        arguments:
+            - "@doctrine.orm.entity_manager"
+            - "@wallabag_core.content_proxy"
+        calls:
+            - [ setLogger, [ "@logger" ]]
+        tags:
+            -  { name: wallabag_import.import, alias: readability }
diff --git a/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Readability/index.html.twig
new file mode 100644 (file)
index 0000000..f527d30
--- /dev/null
@@ -0,0 +1,43 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'import.readability.page_title'|trans }}{% endblock %}
+
+{% block content %}
+<div class="row">
+    <div class="col s12">
+        <div class="card-panel settings">
+            <div class="row">
+                <blockquote>{{ import.description|trans }}</blockquote>
+                <p>{{ 'import.readability.how_to'|trans }}</p>
+
+                <div class="col s12">
+                    {{ form_start(form, {'method': 'POST'}) }}
+                        {{ form_errors(form) }}
+                        <div class="row">
+                            <div class="file-field input-field col s12">
+                                {{ form_errors(form.file) }}
+                                <div class="btn">
+                                    <span>{{ form.file.vars.label|trans }}</span>
+                                    {{ form_widget(form.file) }}
+                                </div>
+                                <div class="file-path-wrapper">
+                                    <input class="file-path validate" type="text">
+                                </div>
+                            </div>
+                            <div class="input-field col s6 with-checkbox">
+                                <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6>
+                                {{ form_widget(form.mark_as_read) }}
+                                {{ form_label(form.mark_as_read) }}
+                            </div>
+                        </div>
+
+                        {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }}
+
+                        {{ form_rest(form) }}
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+{% endblock %}
diff --git a/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml b/src/Wallabag/UserBundle/Resources/translations/wallabag_user.oc.yml
new file mode 100644 (file)
index 0000000..53a1afd
--- /dev/null
@@ -0,0 +1,11 @@
+# Two factor mail
+auth_code:
+    on: 'sus'
+    mailer:
+        subject: "Còdi d'autentificacion wallabag"
+        body:
+            hello: "Bonjorn %user%,"
+            first_para: "Estant qu'avètz activat la dobla autentificacion sus vòtre compte wallabag e que venètz de vos conectar dempuèi un novèl aparelh (ordinador, mobil, etc.) vos mandem un còdi per validar la connexion."
+            second_para: "Vaquí lo còdi a dintrar :"
+            support: "S'avètz un problèma de connexion, dobtetz pas a contacter l'assisténcia : "
+            signature: "La còla de wallabag"
index 13a903ab67ca2407514e3f62cc5f6f469024d440..938f1a31a6367da9d69e461e4bdbd710fa23cd50 100644 (file)
@@ -41,7 +41,7 @@
             <i class="material-icons right">send</i>
         </button>
     </div>
-    <div class="center">
+    <div class="row center">
         <a href="{{ path('fos_user_resetting_request') }}">{{ 'security.login.forgot_password'|trans }}</a>
     </div>
 </form>
index f9ac28c3ac3fc125bc324d8e189db3283ac1e7b5..a74c17d9549372324632edbf5910765c9d6a8087 100644 (file)
@@ -236,6 +236,16 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
     }
 
+    public function testUntagged()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $client->request('GET', '/untagged/list');
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+    }
+
     public function testStarred()
     {
         $this->logInAs('admin');
index 96b5300ba3531c3378841d7544943871898fe99d..d869cdf9c56bc34f68cdaeae9fdb16eaf8a34096 100644 (file)
@@ -24,6 +24,6 @@ class ImportControllerTest extends WallabagCoreTestCase
         $crawler = $client->request('GET', '/import/');
 
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
-        $this->assertEquals(3, $crawler->filter('blockquote')->count());
+        $this->assertEquals(4, $crawler->filter('blockquote')->count());
     }
 }
diff --git a/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php
new file mode 100644 (file)
index 0000000..92cf4bf
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+
+namespace Tests\Wallabag\ImportBundle\Controller;
+
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+class ReadabilityControllerTest extends WallabagCoreTestCase
+{
+    public function testImportReadability()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/import/readability');
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+        $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
+        $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
+    }
+
+    public function testImportReadabilityWithFile()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/import/readability');
+        $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
+
+        $file = new UploadedFile(__DIR__.'/../fixtures/readability.json', 'readability.json');
+
+        $data = [
+            'upload_import_file[file]' => $file,
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $content = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findByUrlAndUserId(
+                'https://venngage.com/blog/hashtags-are-worthless/',
+                $this->getLoggedInUserId()
+            );
+
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('flashes.import.notice.summary', $body[0]);
+    }
+
+    public function testImportReadabilityWithFileAndMarkAllAsRead()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/import/readability');
+        $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
+
+        $file = new UploadedFile(__DIR__.'/../fixtures/readability-read.json', 'readability-read.json');
+
+        $data = [
+            'upload_import_file[file]' => $file,
+            'upload_import_file[mark_as_read]' => 1,
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $content1 = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findByUrlAndUserId(
+                'https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/',
+                $this->getLoggedInUserId()
+            );
+
+        $this->assertTrue($content1->isArchived());
+
+        $content2 = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findByUrlAndUserId(
+                'https://facebook.github.io/graphql/',
+                $this->getLoggedInUserId()
+            );
+
+        $this->assertTrue($content2->isArchived());
+
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('flashes.import.notice.summary', $body[0]);
+    }
+
+    public function testImportReadabilityWithEmptyFile()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/import/readability');
+        $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
+
+        $file = new UploadedFile(__DIR__.'/../fixtures/test.txt', 'test.txt');
+
+        $data = [
+            'upload_import_file[file]' => $file,
+        ];
+
+        $client->submit($form, $data);
+
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+        $crawler = $client->followRedirect();
+
+        $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
+        $this->assertContains('flashes.import.notice.failed', $body[0]);
+    }
+}
diff --git a/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php b/tests/Wallabag/ImportBundle/Import/ReadabilityImportTest.php
new file mode 100644 (file)
index 0000000..706d707
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+
+namespace Tests\Wallabag\ImportBundle\Import;
+
+use Wallabag\ImportBundle\Import\ReadabilityImport;
+use Wallabag\UserBundle\Entity\User;
+use Wallabag\CoreBundle\Entity\Entry;
+use Monolog\Logger;
+use Monolog\Handler\TestHandler;
+
+class ReadabilityImportTest extends \PHPUnit_Framework_TestCase
+{
+    protected $user;
+    protected $em;
+    protected $logHandler;
+    protected $contentProxy;
+
+    private function getReadabilityImport($unsetUser = false)
+    {
+        $this->user = new User();
+
+        $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $wallabag = new ReadabilityImport($this->em, $this->contentProxy);
+
+        $this->logHandler = new TestHandler();
+        $logger = new Logger('test', [$this->logHandler]);
+        $wallabag->setLogger($logger);
+
+        if (false === $unsetUser) {
+            $wallabag->setUser($this->user);
+        }
+
+        return $wallabag;
+    }
+
+    public function testInit()
+    {
+        $readabilityImport = $this->getReadabilityImport();
+
+        $this->assertEquals('Readability', $readabilityImport->getName());
+        $this->assertNotEmpty($readabilityImport->getUrl());
+        $this->assertEquals('import.readability.description', $readabilityImport->getDescription());
+    }
+
+    public function testImport()
+    {
+        $readabilityImport = $this->getReadabilityImport();
+        $readabilityImport->setFilepath(__DIR__.'/../fixtures/readability.json');
+
+        $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $entryRepo->expects($this->exactly(2))
+            ->method('findByUrlAndUserId')
+            ->will($this->onConsecutiveCalls(false, true));
+
+        $this->em
+            ->expects($this->any())
+            ->method('getRepository')
+            ->willReturn($entryRepo);
+
+        $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->contentProxy
+            ->expects($this->exactly(1))
+            ->method('updateEntry')
+            ->willReturn($entry);
+
+        $res = $readabilityImport->import();
+
+        $this->assertTrue($res);
+        $this->assertEquals(['skipped' => 1, 'imported' => 1], $readabilityImport->getSummary());
+    }
+
+    public function testImportAndMarkAllAsRead()
+    {
+        $readabilityImport = $this->getReadabilityImport();
+        $readabilityImport->setFilepath(__DIR__.'/../fixtures/readability-read.json');
+
+        $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $entryRepo->expects($this->exactly(2))
+            ->method('findByUrlAndUserId')
+            ->will($this->onConsecutiveCalls(false, false));
+
+        $this->em
+            ->expects($this->any())
+            ->method('getRepository')
+            ->willReturn($entryRepo);
+
+        $this->contentProxy
+            ->expects($this->exactly(2))
+            ->method('updateEntry')
+            ->willReturn(new Entry($this->user));
+
+        // check that every entry persisted are archived
+        $this->em
+            ->expects($this->any())
+            ->method('persist')
+            ->with($this->callback(function ($persistedEntry) {
+                return $persistedEntry->isArchived();
+            }));
+
+        $res = $readabilityImport->setMarkAsRead(true)->import();
+
+        $this->assertTrue($res);
+
+        $this->assertEquals(['skipped' => 0, 'imported' => 2], $readabilityImport->getSummary());
+    }
+
+    public function testImportBadFile()
+    {
+        $readabilityImport = $this->getReadabilityImport();
+        $readabilityImport->setFilepath(__DIR__.'/../fixtures/wallabag-v1.jsonx');
+
+        $res = $readabilityImport->import();
+
+        $this->assertFalse($res);
+
+        $records = $this->logHandler->getRecords();
+        $this->assertContains('ReadabilityImport: unable to read file', $records[0]['message']);
+        $this->assertEquals('ERROR', $records[0]['level_name']);
+    }
+
+    public function testImportUserNotDefined()
+    {
+        $readabilityImport = $this->getReadabilityImport(true);
+        $readabilityImport->setFilepath(__DIR__.'/../fixtures/readability.json');
+
+        $res = $readabilityImport->import();
+
+        $this->assertFalse($res);
+
+        $records = $this->logHandler->getRecords();
+        $this->assertContains('ReadabilityImport: user is not defined', $records[0]['message']);
+        $this->assertEquals('ERROR', $records[0]['level_name']);
+    }
+}
diff --git a/tests/Wallabag/ImportBundle/fixtures/readability-read.json b/tests/Wallabag/ImportBundle/fixtures/readability-read.json
new file mode 100644 (file)
index 0000000..c60767d
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    "bookmarks": [
+        {
+            "article__excerpt": "This is a guest post from Moritz Beller from the Delft University of Technology in The Netherlands. His team produced amazing research on several million Travis CI builds, creating invaluable&hellip;",
+            "favorite": false,
+            "date_archived": "2016-08-02T06:49:30",
+            "article__url": "https://blog.travis-ci.com/2016-07-28-what-we-learned-from-analyzing-2-million-travis-builds/",
+            "date_added": "2016-08-01T05:24:16",
+            "date_favorited": null,
+            "article__title": "Travis",
+            "archive": true
+        },
+        {
+            "article__excerpt": "The GraphQL Type system describes the capabilities of a GraphQL server and is used to determine if a query is valid. The type system also describes the input types of query variables to determine if&hellip;",
+            "favorite": false,
+            "date_archived": "2016-07-19T06:48:31",
+            "article__url": "https://facebook.github.io/graphql/",
+            "date_added": "2016-06-24T17:50:16",
+            "date_favorited": null,
+            "article__title": "GraphQL",
+            "archive": true
+        }
+   ],
+    "recommendations": []
+}
diff --git a/tests/Wallabag/ImportBundle/fixtures/readability.json b/tests/Wallabag/ImportBundle/fixtures/readability.json
new file mode 100644 (file)
index 0000000..3437990
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    "bookmarks": [
+        {
+            "article__excerpt": "When Twitter started it had so much promise to change the way we communicate. But now it has been ruined by the amount of garbage and hate we have to wade through. It&#x2019;s like that polluted&hellip;",
+            "favorite": false,
+            "date_archived": null,
+            "article__url": "https://venngage.com/blog/hashtags-are-worthless/",
+            "date_added": "2016-08-25T12:05:00",
+            "date_favorited": null,
+            "article__title": "We Looked At 167,943 Tweets & Found Out Hashtags Are Worthless",
+            "archive": false
+        },
+        {
+            "article__excerpt": "TL;DR: Re-use your DOM elements and remove the ones that are far away from the viewport. Use placeholders to account for delayed data. Here&#x2019;s a demo and the code for the infinite&hellip;",
+            "favorite": false,
+            "date_archived": "2016-08-26T12:21:54",
+            "article__url": "https://developers.google.com/web/updates/2016/07/infinite-scroller?imm_mid=0e6839&cmp=em-webops-na-na-newsltr_20160805",
+            "date_added": "2016-08-06T05:35:26",
+            "date_favorited": null,
+            "article__title": "Complexities of an infinite scroller | Web Updates",
+            "archive": true
+        }
+   ],
+    "recommendations": []
+}