]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #1675 from wallabag/v2-create-api-client
authorNicolas Lœuillet <nicolas@loeuillet.org>
Tue, 8 Mar 2016 09:09:39 +0000 (10:09 +0100)
committerNicolas Lœuillet <nicolas@loeuillet.org>
Tue, 8 Mar 2016 09:09:39 +0000 (10:09 +0100)
Ability to create new client for the API

42 files changed:
.github/ISSUE_TEMPLATE.md
README.md
RELEASE_PROCESS.md [new file with mode: 0644]
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml [new file with mode: 0644]
app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml [new file with mode: 0644]
app/config/config.yml
docs/en/index.rst
docs/en/user/filters.rst
docs/en/user/installation.rst
docs/fr/user/configuration.rst
docs/fr/user/create_account.rst
docs/fr/user/download_articles.rst
docs/fr/user/errors_during_fetching.rst
docs/fr/user/filters.rst
docs/fr/user/first_article.rst
docs/fr/user/import.rst
docs/fr/user/installation.rst
docs/fr/user/login.rst
docs/img/user/filters.png [new file with mode: 0644]
src/Wallabag/ApiBundle/Controller/WallabagRestController.php
src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/validators.es.yml [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/base.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/quickstart.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Static/quickstart.html.twig
src/Wallabag/ImportBundle/Controller/PocketController.php
src/Wallabag/ImportBundle/Controller/WallabagV1Controller.php
src/Wallabag/ImportBundle/Controller/WallabagV2Controller.php
src/Wallabag/ImportBundle/Form/Type/UploadImportType.php
src/Wallabag/ImportBundle/Import/PocketImport.php
src/Wallabag/ImportBundle/Import/WallabagV1Import.php
src/Wallabag/ImportBundle/Import/WallabagV2Import.php
src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig
src/Wallabag/ImportBundle/Resources/views/WallabagV1/index.html.twig
src/Wallabag/ImportBundle/Tests/Controller/WallabagV1ControllerTest.php
src/Wallabag/ImportBundle/Tests/Import/PocketImportTest.php
src/Wallabag/ImportBundle/Tests/Import/WallabagV1ImportTest.php
src/Wallabag/ImportBundle/Tests/Import/WallabagV2ImportTest.php
src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v1-read.json [new file with mode: 0644]
src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v2-read.json [new file with mode: 0644]

index 41e11054ebbe6b2c72f8ac23be4b032b8f899d36..87e1d42f49c1b52c30247c1ed3cec1384e0cbe57 100644 (file)
@@ -6,6 +6,7 @@ Remember, this is _not_ a place to ask questions. For that, go to http://gitter.
 ### Environment
 
 * wallabag version (or git revision) that exhibits the issue:
+* How did you install wallabag? Via `composer create-project` or by downloading the package?
 * Last wallabag version that did not exhibit the issue (if applicable):
 * php version:
 * OS:
index b1086885f4ca75b5eab547388982e6195c403aac..b7940b36c8b2857963b59f1af0aa1bbc1fa695a2 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Keep in mind it's an **unstable** branch, everything can be broken :)
 If you don't have it yet, please [install composer](https://getcomposer.org/download/). Then you can install wallabag by executing the following commands:
 
 ```
-SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.*@alpha" --no-dev
+SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
 php bin/console wallabag:install --env=prod
 php bin/console server:run --env=prod
 ```
diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md
new file mode 100644 (file)
index 0000000..45e6054
--- /dev/null
@@ -0,0 +1,67 @@
+## Definition
+
+A release is mostly a git tag of http://github.com/wallabag/wallabag, following [semantic versioning](http://semver.org).
+The last release at the time of writing is 2.0.0-alpha.2, from the v2 branch.
+
+### Steps to release
+
+During this documentation, we assume the release is `release-2.0.0-beta.1`.
+
+#### Files to edit
+
+- `app/config/config.yml` (`wallabag_core.version`)
+- `README.md` (`composer create-project` command)
+- `docs/en/user/installation.rst` and its translations (`composer create-project` command)
+
+#### Create release on GitHub
+
+- Run these commands to create the tag:
+
+```
+    git checkout v2
+    git pull origin v2
+    git checkout -b release-2.0.0-beta.1
+    SYMFONY_ENV=prod composer up --no-dev
+    git add --force composer.lock
+    git add README.md
+    git commit -m "Release wallabag 2.0.0-beta.1"
+    git push origin release-2.0.0-beta.1
+```
+
+- Create a new pull request with this title `DON'T MERGE Release wallabag 2.0.0-beta.1`. This pull request is used to launch builds on Travis-CI.
+- Run these commands to create the package:
+
+```
+    git clone git@github.com:wallabag/wallabag.git -b release-2.0.0-beta.1 release-2.0.0-beta.1
+    SYMFONY_ENV=prod composer up -d=release-2.0.0-beta.1 --no-dev
+    tar czf wallabag-release-2.0.0-beta.1.tar.gz --exclude="var/*" --exclude=".git" release-2.0.0-beta.1
+```
+
+- [Create the new release on GitHub](https://github.com/wallabag/wallabag/releases/new). You have to upload on this page the package.
+- Delete the `release-2.0.0-beta.1` branch and close the pull request (**DO NOT MERGE IT**).
+- Update the URL shortener (used on `wllbg.org` to generate links like `http://wllbg.org/latest-v2-package` or `http://wllbg.org/latest-v2`)
+- Update [the downloads page](https://github.com/wallabag/wallabag.org/blob/master/content/pages/download.md) on the website (MD5 sum, release date)
+- Drink a beer!
+
+### `composer.lock`
+A release tag must contain a `composer.lock` file. It sets which dependencies were available at the time a release was done,
+making it easier to fix issues after the release. It also speeds up `composer install` on stable versions a LOT, by skipping the
+dependencies resolution part.
+
+Since `composer.lock` is ignored by default, either it must be removed from `.gitignore` _in the release branch_,
+or it must be added using `git add --force composer.lock`.
+
+### Target PHP version
+`composer.lock` is _always_ built for a particular version, by default the one it is generated (with `composer update`).
+
+If the PHP version used to generate the .lock isn't a widely available one (like PHP 7), a more common one should
+be locally specified in `composer.lock`:
+
+```json
+    "config": {
+        "platform": {
+            "php": "5.5.9",
+            "ext-something": "4.0"
+        }
+    }
+```
diff --git a/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml b/app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
new file mode 100644 (file)
index 0000000..9c9a480
--- /dev/null
@@ -0,0 +1,29 @@
+download_pictures: Descagar imagenes
+carrot: Activar compartir con Carrot
+diaspora_url: Diaspora URL, si el servicio esta activado
+export_epub: Activar exportación a ePub
+export_mobi: Activar exportación a .mobi
+export_pdf: Activar exportación a PDF
+export_csv: Activar exportación a CSV
+export_json: Activar exportación a JSON
+export_txt: Activar exportación a TXT
+export_xml: Activar exportación a XML
+pocket_consumer_key: Consumer key for Pocket to import contents (https://getpocket.com/developer/docs/authentication)
+shaarli_url: Shaarli URL, si el servicio está activado
+share_diaspora: Activar compartir con Diaspora
+share_mail: Activar compartir con email
+share_shaarli: Activar compartir con Shaarli
+share_twitter: Activar compartir con Twitter
+show_printlink: Mostrar un link para imprimir contenido
+wallabag_support_url: URL de soporte de wallabag
+wallabag_url: URL de *tu* instancia de wallabag
+entry: "artículo"
+export: "exportar"
+import: "importar"
+misc: "misc"
+modify_settings: "modificar configuración"
+piwik_host: Host de tu website de Piwik
+piwik_site_id: ID de tu website de Piwik
+piwik_enabled: Activar Piwik
+demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)"
+demo_mode_username: "Nombre de usuario demo"
diff --git a/app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml b/app/Resources/FOSUserBundle/translations/FOSUserBundle.es.yml
new file mode 100644 (file)
index 0000000..968eb24
--- /dev/null
@@ -0,0 +1,2 @@
+Login: "Logearse"
+Enter your email address below and we'll send you password reset instructions.: "Introduzca su dirección de email y le enviaremos las instrucciones para resetear su contraseña."
index 51cc049eb577e9f982fe8e71781b807f697e2b44..25ecabe759ca4706cfd6a00a5fdb71c92e551f1e 100644 (file)
@@ -28,7 +28,7 @@ framework:
     assets: ~
 
 wallabag_core:
-    version: 2.0.0-alpha.2
+    version: 2.0.0-beta.1
     paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb"
     languages:
         en: 'English'
@@ -39,6 +39,7 @@ wallabag_core:
         ro: 'Română'
         pl: 'Polish'
         da: 'Dansk'
+        es: 'Español'
     items_on_page: 12
     theme: material
     language: en
index 54d79e0cc7c486cf0a250877eed710afbecb3dfb..3367c8a96b5b7c4c1e650c36d71fb53fa07ce79f 100644 (file)
@@ -44,3 +44,4 @@ The main documentation for this application is organized into a couple sections:
    developer/docker
    developer/translate
    developer/maintenance
+   developer/releasing
index 65fdedcba0e452dbe3772b729bf950b1f6083cd2..ad06819bb06c54ae780651bcee02ea6666f8f091 100644 (file)
@@ -1,2 +1,49 @@
 Filters
-=======
\ No newline at end of file
+=======
+
+To retrieve articles easier, you can use filters.
+Click on the third icon in the top bar.
+
+.. image:: ../../img/user/topbar.png
+   :alt: Top bar
+   :align: center
+
+All these filters can be combined.
+
+.. image:: ../../img/user/filters.png
+   :alt: Combine all filters
+   :align: center
+
+Status
+------
+
+Use these checkboxes to find archived or starred articles.
+
+Preview picture
+---------------
+
+Check this filter if you want to retrieve articles with a preview picture.
+
+Language
+--------
+
+wallabag (via graby) can detect article language. It's easy to you to retrieve articles
+written in a specific language.
+
+Reading time
+------------
+
+wallabag estimates how many time you need to read an article. With this filter,
+you can for example find the articles with a reading time between 2 and 5 minutes.
+
+Domain name
+-----------
+
+Thanks to this filter, you can retrieve the articles from the same domain name.
+For example, in this field, type ``bbc.co.uk`` to retrieve the articles of this website.
+
+Creation date
+-------------
+
+When you save an article, wallabag stored the current date. So handful to retrieve articles written
+between 1st and 31th January for example.
index 760fd4d2fa4b94ab91158ccf16aa64a77459b9d1..385d6595b9ddcb1b8d38557a6652367e0a31a0e3 100644 (file)
@@ -11,7 +11,7 @@ You'll need the following extensions for wallabag to work. Some of these may alr
 - php-session
 - php-ctype
 - php-dom
-- pĥp-hash
+- php-hash
 - php-simplexml
 - php-json
 - php-gd
@@ -48,7 +48,7 @@ To install wallabag itself, you must run these two commands:
 
 ::
 
-    SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.*@alpha" --no-dev
+    SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
     php bin/console wallabag:install --env=prod
 
 To start php's build-in server and test if everything did install correctly, you can do:
index f8bb6d42ee1c7afb9559307608b42b8b4ee2188e..ee5be052106ce5b15fbc257120f847e6b880f3a8 100644 (file)
@@ -1,9 +1,9 @@
 Configuration
 =============
 
-Maintenant que vous êtes connecté, il est temps de confirurer votre compte.
+Maintenant que vous êtes connecté, il est temps de configurer votre compte.
 
-Cliquez sur le menu ``Configuration``. Vous avez accès à 5 onglets:
+Cliquez sur le menu ``Configuration``. Vous avez accès à 5 onglets :
 ``Paramètres``, ``RSS``, ``Mon compte``, ``Mot de passe`` and ``Règles de tag automatiques``.
 
 Paramètres
@@ -14,7 +14,7 @@ Thème
 
 L'affichage de wallabag est personnalisable. C'est ici que vous choisissez le thème
 que vous préférez. Vous pouvez aussi en créer un nouveau, une documentation sera
-disponible pour apprendre comment. Le thème par défaut ``Material``, c'est ce thème
+disponible pour guider. Le thème par défaut est ``Material``, c'est celui
 qui est utilisé dans les captures d'écran de la documentation.
 
 Nombre d'articles par page
@@ -31,12 +31,12 @@ pour que la nouvelle langue soit prise en compte.
 RSS
 ---
 
-wallabag propose un flux RSS for chaque statut d'article : non lus, favoris and lus.
+wallabag propose un flux RSS pour chaque statut d'article : non lus, favoris et lus.
 
-Tout d'abord, vous devez vous créer un jeton personnel : cliquez sur ``Créez votre jeton``.
-C'est possible de regénérer votre jeton en cliquant sur ``Réinitialisez votre jeton``.
+Tout d'abord, vous devez vous créer un jeton personnel : cliquez sur ``Créez votre jeton``.
+Il est possible de regénérer votre jeton en cliquant sur ``Réinitialisez votre jeton``.
 
-Vous avez maintenant trois liens, un par statut : ajoutez les dans votre agrégateur de flux RSS préféré.
+Vous avez maintenant trois liens, un par statut : ajoutez-les dans votre agrégateur de flux RSS préféré.
 
 Vous pouvez aussi définir combien d'articles vous souhaitez dans vos flux RSS
 (50 est la valeur par défaut).
@@ -49,16 +49,16 @@ Vous pouvez ici modifier votre nom, votre adresse email et activer la ``Double a
 Double authentification (2FA)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    Two-factor authentication (also known as 2FA) is a technology patented in
-    1984 that provides identification of users by means of the combination of two different components.
+    L'authentification à deux facteurs (également appelée 2FA) est une technologie brevetée en 1984
+    qui fournit l'identification des utilisateurs au moyen de la combinaison de deux composants différents .
 
-https://en.wikipedia.org/wiki/Two-factor_authentication
+https://fr.wikipedia.org/wiki/Authentification_forte
 
-Si vous activer 2FA, à chaque tentative de connexion à wallabag, vous recevrez
+Si vous activez 2FA, à chaque tentative de connexion à wallabag, vous recevrez
 un code par email. Vous devez renseigner ce code dans le formulaire suivant :
 
 .. image:: ../../img/user/2FA_form.png
-    :alt: Two factor authentication
+    :alt: Authentification à deux facteurs
     :align: center
 
 Si vous ne souhaitez pas recevoir un code à chaque fois que vous vous connectez,
@@ -89,15 +89,15 @@ Comment les utiliser ?
 
 Admettons que vous voulez ajouter comme tag *« lecture rapide »* quand le temps de lecture
 d'un article est inférieur à 3 minutes.
-Dans ce cas, vous devez ajouter « readingTime <= 3 » dans le champ **Règle** et *« lecture rapide »* dans le champ **Tags**.
-Plusieurs tags peuvent être ajoutés en même temps en les séparant par une virgule : *« lecture rapide, à lire »*.
+Dans ce cas, vous devez ajouter « readingTime <= 3 » dans le champ **Règle** et *« lecture rapide »* dans le champ **Tags**.
+Plusieurs tags peuvent être ajoutés en même temps en les séparant par une virgule : *« lecture rapide, à lire »*.
 Des règles complexes peuvent être écrites en utilisant les opérateurs pré-définis :
 if *« readingTime >= 5 AND domainName = "github.com" »* then tag as *« long reading, github »*.
 
 Quels variables et opérateurs puis-je utiliser pour écrire mes règles ?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Les variables et opérateurs suivants peuvent être utilisés lors de la création de vos règles :
+Les variables et opérateurs suivants peuvent être utilisés lors de la création de vos règles :
 
 ===========  ==============================================  ==========  ==========
 Variable     Sens                                            Opérateur   Sens
@@ -110,5 +110,5 @@ content      Le contenu de l'article                         =           Égal 
 language     La langue de l'article                          !=          Différent de …
 mimetype     The type MIME de l'article                      OR          Telle règle ou telle autre règle
 readingTime  Le temps de lecture de l'article, en minutes    AND         Telle règle et telle règle
-domainName   Le nom de domaine de l'article                  matches     Contient telle chaine de caractère (insensible à la casse). Exemple : title matches "football"
+domainName   Le nom de domaine de l'article                  matches     Contient telle chaîne de caractère (insensible à la casse). Exemple : title matches "football"
 ===========  ==============================================  ==========  ==========
index 4fc9806992e6855b15b1d2989d73d6b7fd9458f2..7f29b0f00bf70bdb9ccb2e0e3528164672ff184c 100644 (file)
@@ -4,14 +4,14 @@ Se créer un compte
 Sur la page de connexion, cliquez sur le bouton ``Créer un compte``.
 
 .. image:: ../../img/user/registration_form.png
-   :alt: Registration form
+   :alt: Formulaire de création de compte
    :align: center
 
 Vous devez renseigner le formulaire. Faites attention de bien renseigner une adresse
 email valide, nous allons vous envoyer un email d'activation.
 
 .. image:: ../../img/user/sent_email.png
-   :alt: Email was sent to activate account
+   :alt: Un email a été envoyé pour activer votre compte
    :align: center
 
 Vérifiez votre boite de réception, vous avez un nouvel email avec un lien comme celui-ci
@@ -21,7 +21,7 @@ Cliquez dessus pour activer votre compte.
 Votre compte est maintenant actif.
 
 .. image:: ../../img/user/activated_account.png
-   :alt: Welcome on board!
+   :alt: Bienvenue à bord !
    :align: center
 
 Foire aux questions
index dafeba37aee0b8838fb35781d86f0c37047b65a4..39c98206a5bdf56e6023dae5288e8a35b9f5dd51 100644 (file)
@@ -6,12 +6,12 @@ Vous pouvez télécharger chaque article dans plusieurs formats : ePUB, MOBI, PD
 Lorsque vous lisez un article, cliquez sur cette icône dans la barre latérale :
 
 .. image:: ../../img/user/download_article.png
-   :alt: download article
+   :alt: Télécharger l'article
    :align: center
 
 Vous pouvez aussi télécharger une catégorie (non lus, favoris, lus) dans ces formats.
 Par exemple, dans la vue **Non lus**, cliquez sur cette icône dans la barre supérieure :
 
 .. image:: ../../img/user/download_articles.png
-   :alt: download articles
+   :alt: Télécharger l'article
    :align: center
index b20e5973736ecc3317bd03bc85ff8118cee841ab..34a6ce186b6c1420586447bb6c68212bf3dbf8c2 100644 (file)
@@ -23,5 +23,5 @@ Si wallabag échoue en récupérant l'article, vous pouvez cliquer sur le bouton
 (le troisième sur l'image ci-dessous).
 
 .. image:: ../../img/user/refetch.png
-   :alt: Refetch content
+   :alt: Réessayer de récupérer le contenu
    :align: center
index ecb29948cd62cedeb3d06e7f4c5f8c6fec6e96ea..6592f140454cc8da2fddb96e6cc7a4c115edb4e6 100644 (file)
@@ -1,2 +1,50 @@
 Filtres
 =======
+
+Pour retrouver plus facilement vos articles, vous pouvez utiliser les filtres.
+Cliquez sur la troisième icône de la barre supérieure.
+
+.. image:: ../../img/user/topbar.png
+   :alt: Barre supérieure
+   :align: center
+
+Tous ces filtres peuvent être combinés.
+
+.. image:: ../../img/user/filters.png
+   :alt: Combine all filters
+   :align: center
+
+Statut
+------
+
+Utilisez ces cases à cocher pour retrouver les articles lus ou mis en favori.
+
+Image de prévisualisation
+-------------------------
+
+Cochez ce filtre si vous voulez retrouver les articles avec une image de prévisualisation.
+
+Langage
+-------
+
+wallabag (via graby) peut détecter la langue dans laquelle l'article est écrit.
+C'est ainsi facile pour vous de retrouver des articles écrits dans une langue spécifique.
+
+Temps de lecture
+----------------
+
+wallabag estime combien de temps vous avez besoin pour lire un article.
+Avec ce filtre, vous pouvez par exemple retrouver les articles qui ont une estimation
+entre 2 et 5 minutes.
+
+Nom de domaine
+--------------
+
+Grâce à ce filtre, vous pouvez retrouver les articles venant d'un même nom de domaine.
+Par exemple, dans ce champ, saisissez ``lemonde.fr`` pour retrouver les articles de ce site.
+
+Date de création
+----------------
+
+Quand vous ajoutez un article, wallabag stocke la date courante.
+C'est très pratique pour retrouver les articles ajoutés entre le 1er et le 31 janvier par exemple.
index 90c45a44061afe9d8ac440f5f7e0abadf0116e04..f482badc9a6aa6d776d8190e4b898363a6c63974 100644 (file)
@@ -25,7 +25,7 @@ Dans la barre haut de wallabag, vous avez trois icônes. Avec la première icôn
 un signe plus, vous pouvez facilement ajouter un nouvel article.
 
 .. image:: ../../img/user/topbar.png
-   :alt: Top bar
+   :alt: Barre supérieure
    :align: center
 
 Cliquez dessus pour afficher un nouveau champ, collez-y l'URL de l'article et appuyez
index c95f175d06ee512bba78b11665659b2dc4a1edc1..967df1f60eb3f2d95c01837d535ba3b595448ea9 100644 (file)
@@ -10,7 +10,7 @@ Exportez vos données de wallabag 1.x
 Sur la page de configuration, cliquez sur ``Export JSON`` dans la section ``Exportez vos données wallabag``.
 
 .. image:: ../../img/user/export_wllbg_1.png
-   :alt: Export from wallabag 1.x
+   :alt: Export depuis wallabag 1.x
    :align: center
 
 Vous obtiendrez un fichier ``wallabag-export-1-1970-01-01.json``.
@@ -21,7 +21,7 @@ Exportez vos données de wallabag 2.x
 Dans la barre latérale de téléchargement, cliquez sur ``JSON``.
 
 .. image:: ../../img/user/export_wllbg_2.png
-   :alt: Export from wallabag 2.x
+   :alt: Export depuis wallabag 2.x
    :align: center
 
 Vous obtiendrez un fichier ``Unread articles.json``.
@@ -33,7 +33,7 @@ Cliquez sur le lien ``Importer`` dans le menu, choisissez la version de wallabag
 sélectionnez votre fichier d'export sur votre ordinateur et importez-le.
 
 .. image:: ../../img/user/import_wllbg.png
-   :alt: Import from wallabag 1.x
+   :alt: Import depuis wallabag 1.x
    :align: center
 
 Tous vos articles wallabag seront importés.
index e4ff49ceae7ce639160d5d176f78157994461b14..a2a5dabf5c9de7b315e768ad7b8e85510ec4376d 100644 (file)
@@ -46,7 +46,7 @@ Pour installer wallabag, vous devez exécuter ces deux commandes :
 
 ::
 
-    SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.*@alpha" --no-dev
+    SYMFONY_ENV=prod composer create-project wallabag/wallabag wallabag "2.0.0-beta.1" --no-dev
     php bin/console wallabag:install --env=prod
 
 Pour démarrer le serveur interne à php et vérifier que tout s'est installé correctement, vous pouvez exécuter :
index 7ef705691277f3afb7d56d93ef52475cc8012dcc..3a02d1d51ed9f4c5c6aeaf7c7599e26c5dbedbe9 100644 (file)
@@ -9,7 +9,7 @@ Si vous êtes sur un ordinateur de confiance et que vous souhaitez rester connec
 vous pouvez cocher la case ``Restez connecté`` : wallabag se souviendra de vous pour un an.
 
 .. image:: ../../img/user/login_form.png
-   :alt: Login form
+   :alt: Formulaire de connexion
    :align: center
 
 Foire aux questions
diff --git a/docs/img/user/filters.png b/docs/img/user/filters.png
new file mode 100644 (file)
index 0000000..1e566bd
Binary files /dev/null and b/docs/img/user/filters.png differ
index 03990088218971850a9c87240381e911c3a1a2e0..35a90edde12bee3bc8b923edda9fa7311a4ff963 100644 (file)
@@ -97,6 +97,8 @@ class WallabagRestController extends FOSRestController
      *          {"name"="url", "dataType"="string", "required"=true, "format"="http://www.test.com/article.html", "description"="Url for the entry."},
      *          {"name"="title", "dataType"="string", "required"=false, "description"="Optional, we'll get the title from the page."},
      *          {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
+     *          {"name"="starred", "dataType"="boolean", "required"=false, "format"="true or false", "description"="entry already starred"},
+     *          {"name"="archive", "dataType"="boolean", "required"=false, "format"="true or false", "description"="entry already archived"},
      *       }
      * )
      *
@@ -107,6 +109,8 @@ class WallabagRestController extends FOSRestController
         $this->validateAuthentication();
 
         $url = $request->request->get('url');
+        $isArchived = $request->request->get('archive');
+        $isStarred = $request->request->get('starred');
 
         $entry = $this->get('wallabag_core.content_proxy')->updateEntry(
             new Entry($this->getUser()),
@@ -118,8 +122,17 @@ class WallabagRestController extends FOSRestController
             $this->get('wallabag_core.content_proxy')->assignTagsToEntry($entry, $tags);
         }
 
+        if (true === (bool) $isStarred) {
+            $entry->setStarred(true);
+        }
+
+        if (true === (bool) $isArchived) {
+            $entry->setArchived(true);
+        }
+
         $em = $this->getDoctrine()->getManager();
         $em->persist($entry);
+
         $em->flush();
 
         $json = $this->get('serializer')->serialize($entry, 'json');
index 22894a77f756e6ededda60123699abeb30b80b21..630b75bfe62adb2bbd21d387635e8613a027a587 100644 (file)
@@ -162,6 +162,24 @@ class WallabagRestControllerTest extends WallabagApiTestCase
         $this->assertCount(1, $content['tags']);
     }
 
+    public function testPostArchivedEntry()
+    {
+        $this->client->request('POST', '/api/entries.json', array(
+            'url' => 'http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html',
+            'archive' => true,
+            'starred' => false,
+        ));
+
+        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
+
+        $content = json_decode($this->client->getResponse()->getContent(), true);
+
+        $this->assertGreaterThan(0, $content['id']);
+        $this->assertEquals('http://www.lemonde.fr/idees/article/2016/02/08/preserver-la-liberte-d-expression-sur-les-reseaux-sociaux_4861503_3232.html', $content['url']);
+        $this->assertEquals(true, $content['is_archived']);
+        $this->assertEquals(false, $content['is_starred']);
+    }
+
     public function testPatchEntry()
     {
         $entry = $this->client->getContainer()
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
new file mode 100644 (file)
index 0000000..b666f2d
--- /dev/null
@@ -0,0 +1,242 @@
+#Login
+Keep me logged in: 'Mantenme conectado'
+Forgot your password?: '¿Ha olvidado su contraseña?'
+Login: 'Conectarse'
+Back to login: 'Revenir au formulaire de connexion'
+Send: 'Envíar'
+"Enter your email address below and we'll send you password reset instructions.": "Introduce tu dirección de email y le enviaremos las instrucciones para resetear la contraseña"
+Register: 'Registrarse'
+
+# Menu
+unread: 'Sin leer'
+starred: 'Favoritos'
+archive: 'Archivo'
+all: 'Todos los artículos'
+tags: 'Tags'
+config: 'Configuración'
+internal settings: 'Configuración interna'
+import: 'Importar'
+howto: 'Ayuda'
+logout: 'Desconectarse'
+Filtered: 'Articulos filtrados'
+About: 'Acerca de'
+
+# Header
+Back to unread articles: 'Volver a los artículos sin leer'
+Add a new entry: 'Añadir un nuevo artículo'
+Search: 'Buscar'
+Filter entries: 'Filtrar los artículos'
+Enter your search here: 'Introduce tu búsqueda aquí'
+Save new entry: 'Guardar un nuevo artículo'
+Export: 'Exportar'
+
+# Config screen
+Settings: 'Configuración'
+User information: 'Información de usuario'
+Password: 'Contraseña'
+RSS: 'RSS'
+Add a user: 'Añadir un usuario'
+Theme: 'Tema'
+Items per page: "Número de artículos por página"
+Language: 'Idioma'
+Save: 'Enregistrer'
+RSS token: 'RSS token'
+RSS token updated: 'RSS token actualizado '
+Name: 'Nombre'
+Email: 'Direccion e-mail'
+No token: 'Aucun jeton généré'
+Reset your token: 'Resetear token'
+Create your token: 'Crear token'
+Rss limit: "Límite de artículos en feed RSS"
+RSS links: 'URL de su feed RSS'
+"RSS feeds provided by wallabag allow you to read your saved articles with your favourite RSS reader. You need to generate a token first.": "Los feeds RSS de wallabag permiten leer los artículos guardados con su lector RSS favorito. Necesita generar un token primero"
+Old password: 'Contraseña actual'
+New password: 'Nueva contraseña'
+Repeat new password: 'Confirmar la nueva contraseña'
+Username: "Nombre de usuario"
+Two factor authentication: "Autentificación de dos factores"
+"Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion": "Con la autentificación de dos factores recibirá código mediante email en cada nueva conexión que no sea de confianza"
+
+# Tagging rules
+Tagging rules: "Reglas de etiquetado automáticas"
+What does « tagging rules » mean?: "¿Qué significa reglas de etiquetado autómaticas?"
+"They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.": "Son las reglas usadas por Wallabag para etiquetar automáticamente los nuevos artículos.<br />Cáda vez que un nuevo artículo es añadido, todas las reglas de etiquetado automáticas serán usadas para etiquetarlo, ayudandote a clasificar automáticamente los artículos."
+How do I use them?: "¿Cómo se utilizan?"
+"Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » then tag as « <i>long reading, github </i> »": "Imaginons que voulez attribuer aux nouveaux articles le tag « <i>lecture courte</i> » lorsque le temps de lecture est inférieur à 3 minutes.<br />Dans ce cas, vous devriez mettre « readingTime &lt;= 3 » dans le champ <i>Règle</i> et « <i>lecture courte</i> » dans le champ <i>Tag</i>.<br />Plusieurs tags peuvent être ajoutés simultanément en les séparant par des virgules : « <i>lecture courte, à lire</i> »<br />Des règles complexes peuvent être créées en utilisant des opérateurs prédéfinis: si « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » alors attribuer les tags « <i>lecteur longue, github </i> »"
+Which variables and operators can I use to write rules?: "¿Qué variables y operadores se pueden utilizar para escribir las reglas?"
+The following variables and operators can be used to create tagging rules:: "Las siguientes variables y operadores se pueden utilizar para crear las reglas de etiquetado automáticas:"
+Variable: "Variable"
+Meaning: "Significado"
+Operator: "Operador"
+Title of the entry: "Titúlo del artículo"
+Less than…: "Menos que…"
+URL of the entry: "URL del artículo"
+Strictly less than…: "Estrictámente menos que…"
+Whether the entry is archived or not: "El artículo está guardado o no"
+Greater than…: "Más que…"
+Whether the entry is starred or not: "Si el artículo es un favorito o no"
+Strictly greater than…: "Estrictámente mas que…"
+The entry's content: "El contenido del artículo"
+Equal to…: "Egual a…"
+The entry's language: "El idoma del artículo"
+Not equal to…: "Diferente de…"
+The entry's mime-type: "Tipo MIME del artículo"
+One rule or another: "Una regla o otra"
+The estimated entry's reading time, in minutes: "El tiempo estimado de lectura del artículo, en minutos"
+One rule and another: "Una regla y la otra"
+The domain name of the entry: "El dominio del artículo"
+"Tests that a <i>subject</i> is matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches \"football\"</code>": "Prueba si un <i>sujeto</i> corresponde a una <i>busqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>título coincide \"football\"</code>"
+Rule: "Regla"
+FAQ: "FAQ"
+
+# Entries
+"estimated reading time: %readingTime% min": "tiempo estimado de lectura: %readingTime% min"
+"estimated reading time: %inferior% 1 min": "tiempo estimado de lectura: %inferior% 1 min"
+original: "original"
+Toggle mark as read: 'Marcar cómo leído/ no leído'
+Toggle favorite: 'Marcar cómo favorito/ no favorito'
+Delete: 'Suprimir'
+"{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.": "{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos."
+http://website: "http://website"
+"{0} No annotations|{1} One annotation|]1,Inf[ %nbAnnotations% annotations": "{0} Sin anotaciones|{1} Una anotación|]1,Inf[ %nbAnnotations% anotaciones"
+
+# Edit entry
+Edit an entry: "Editar una artículo"
+Title: "Título"
+Is public: "Es Público"
+
+# tag
+Tags: Tags
+"{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.": "{0} No hay ningun tag.|{1} Hay un tag.|]1,Inf[ Hay %count% tags."
+
+# Filters
+Filters: 'Filtros'
+Status: 'Estatus'
+Archived: 'Archivado'
+Starred: 'Favorito'
+Preview picture: 'Foto de preview'
+Has a preview picture: 'Hay una foto'
+Reading time in minutes: 'Duración de  lectura en minutos'
+from: 'de'
+to: 'a'
+website.com: 'website.com'
+Domain name: 'Nombre de dominio'
+Creation date: 'Fecha de creación'
+dd/mm/yyyy: 'dd/mm/aaaa'
+Clear: 'Limpiar'
+Filter: 'Filtrar'
+website.com: "website.com"
+
+# About
+About: "Acerca de"
+Who is behind wallabag: "Equipo de desarrollo de wallabag"
+Getting help: "Conseguir ayuda"
+Helping wallabag: "Ayudar a wallabag"
+Developed by: "Desarrollado por"
+website: "Sitio web"
+And many others contributors ♥: "Y muchos otros contribuidores ♥"
+on GitHub: "en GitHub"
+Project website: "Web del proyecto"
+License: "Licencia"
+Version: "Versión"
+Documentation: "Documentación"
+Bug reports: "Reporte de errores"
+On our support website: "En nuestra web de soporte"
+or: "o"
+"wallabag is free and opensource. You can help us:": "wallabag es libre y gratuito. Usted puede ayudarnos :"
+"by contributing to the project:": "contribuyendo al proyecto :"
+an issue lists all our needs: "nuestras necesidades están en un ticket"
+via Paypal: "via Paypal"
+Take wallabag with you: "Llevate wallabag contigo"
+Social: "Social"
+powered by: "propulsé par"
+Contributors: "Contribuidores"
+Thank you to contributors on wallabag web application: "Gradias a los contribuidores de la aplicación web de wallabag"
+Third-party libraries: "Librerías de terceeros"
+"Here are the list of third-party libraries used in wallabag (with their licenses):": "Aquí está la lista de las dependencias utilizadas por wallabag (con sus licencias):"
+Package: Paquete
+License: Licencia
+
+# Howto
+Form: "Formulario"
+Thanks to this form: "Gracias a este formulario"
+Browser addons: "Extensiones de navigador"
+Mobile apps: "Applicaciones para smartphone"
+Bookmarklet: "Bookmarklet"
+Standard Firefox Add-On: "Extensión Firefox"
+Chrome Extension: "Extensión Chrome"
+download the application: "descargar la aplicación"
+"Drag &amp; drop this link to your bookmarks bar:": "Desplazar y soltar este link en la barra de marcadores :"
+
+# Flash messages
+Information updated: "Su información personal ha sido actualizada"
+"Config saved. Some parameters will be considered after disconnection.": "Configuración guardada. Algunos parámetros serán recargados cuando se vuelva a conectar."
+RSS information updated: "La configuración de los feeds RSS ha sido actualizada"
+Password updated: "Contraseña actualizada"
+Entry starred: "Artículo guardado en los favoritos"
+Entry unstarred: "Artículo retirado de los favoritos"
+Entry archived: "Artículo archivado"
+Entry unarchived: "Artículo desarchivado"
+Entry deleted: "Artículo suprimido"
+Tagging rule deleted: "Regla de etiquetado borrada"
+Tagging rules updated: "Regla de etiquetado actualizada"
+User "%username%" added: 'Usuario "%username%" añadido'
+In demonstration mode, you can't change password for this user.: 'En modo demo, no puedes cambiar la contraseña del usuario.'
+
+# Entry
+Mark as read: 'Marcar como leído'
+Favorite: 'Marcar cómo favorito'
+back: 'Volver'
+original article: 'Artículo original'
+Add a tag: 'Añadir una etiqueta'
+Share: 'Compartir'
+Download: 'Descargar'
+Does this article appear wrong?: "¿Este artículo no se muestra bien?"
+Problems?: '¿Algún problema?'
+Edit title: "Modificar el título"
+Re-fetch content: "Redescargar el contenido"
+Tag added: "Etiqueta añadida"
+
+# Import
+Welcome to wallabag importer. Please select your previous service that you want to migrate.: "Bienvenido al útil de migración de wallabag. Seleccione el servicio previo del que usted quiera migrar."
+"This importer will import all your Pocket data. Pocket doesn't allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag.": "Va a importar sus datos de Pocket. Pocket no nos permite descargar el contenido de su servicio, así que el contenido de cada artículo será redescargado por wallabag."
+"This importer will import all your wallabag v1 articles. On your config page, click on \"JSON export\" in the \"Export your wallabag data\" section. You will have a \"wallabag-export-1-xxxx-xx-xx.json\" file.": "Va a importar sus artículos de wallabag v1. En su configuración de wallabag v1, pulse sobre \"Exportar JSON\" dentro de la sección \"Exportar sus datos de wallabag\". Usted tendrá un fichero \"wallabag-export-1-xxxx-xx-xx.json\"."
+"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.": "Va a importar sus artículos de otra instancia de wallabag v2. Vaya a Todos los artículos, entonces, en la barra lateral, clickee en \"JSON\". Usted tendrá un fichero \"All articles.json\""
+"You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.": "Puedes importar sus datos desde su cuenta de Pocket. Sólo tienes que pulsar en el botón para autrizar que wallabag se conecte a getpocket.com."
+Import > Pocket: "Importar > Pocket"
+Pocket import isn't configured.: "La importación de Pocket no está configurada."
+You need to define %keyurls% a pocket_consumer_key %keyurle%.: "Debe definir %keyurls% una clava del API Pocket %keyurle%."
+Your server admin needs to define an API Key for Pocket.: "El administrador de vuestro servidor debe definir una clave API Pocket."
+Connect to Pocket and import data: "Conectese a Pocket para importar los datos"
+Please select your wallabag export and click on the below button to upload and import it.: "Seleccione el fichero de su exportación de wallabag v1 y puelse en el botón para subirla y importarla."
+File: "Fichero"
+Upload file: "Importar el fichero"
+Import contents: "Importar los contenidos"
+Import: "Importar"
+Import > Wallabag v1: "Importar > Wallabag v1"
+Import > Wallabag v2: "Importar > Wallabag v2"
+
+# Quickstart
+Quickstart: Comienzo rápido
+Welcome to wallabag!: "Bienvenido a wallabag !"
+We'll accompany you to visit wallabag and show you some features which can interess you.: "Le acompañaremos a su visita de wallabag y le mostraremos algunas características que le pueden interesar."
+Follow us!: "¡Siganos!"
+Configure the application: "Configure la aplicación"
+Change language and design: "Cambie el idoma y el diseño de la aplicación"
+Enable RSS feeds: "Activar los feeds RSS"
+First steps: "Prieros pasos"
+Save your first article: "Guarde su primer artículo"
+And classify it!: "¡Y clasifiquelo!"
+Migrate from an existing service: "Migrar de un servicio existente"
+You're using an other service? We'll help you to retrieve your data on wallabag.: "¿Está usando otro servicio? Le ayudaremos a migrar sus datos a wallabag."
+Migrate from Pocket: "Migrar desde Pocket"
+Migrate from wallabag v1: "Migrar desde wallabag v1"
+Full documentation: "Documentación completa"
+Convert your articles into ePUB or PDF: "Convierta sus artículos a ePub o a PDF"
+See how you can look for an article by using search engine and filters: "Aprenda a utilizar el buscador y los filtros para encontrar el artículo que le interese"
+And so many other articles!: "¡Y muchos más artículos!"
+Support: "Soporte"
+If you need some help, we are here for you.: "Sí necesita ayuda, estamos disponibles para usted."
+On GitHub: "En GitHub"
+By email: "Por email"
+On Gitter: "On Gitter"
index 1de8d20f7a91e4961f29921fa97b4c698e68312f..b809f1ab8a483e5aa84c977538c1d18f4ea251da 100644 (file)
@@ -54,13 +54,13 @@ Old password: 'Mot de passe actuel'
 New password: 'Nouveau mot de passe'
 Repeat new password: 'Confirmez votre nouveau mot de passe'
 Username: "Nom d'utilisateur"
-Two factor authentication: Double authentification
-Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion: Activer l'authentification double-facteur veut dire que vous allez recevoir un code par email à chaque nouvelle connexion non approuvée.
+Two factor authentication: "Double authentification"
+"Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion": "Activer l'authentification double-facteur veut dire que vous allez recevoir un code par email à chaque nouvelle connexion non approuvée."
 
 # Tagging rules
 Tagging rules: "Règles de tag automatiques"
 What does « tagging rules » mean?: "Que signifient les règles de tag automatiques ?"
-"They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.": "Ce sont des règles utilisées par wallabag pour classer automatiquement vos nouveaux articles.<br />À chaque fois qu'un nouvel article est ajouté, toutes les règles de tag automatiques seront utilisées afin d'ajouter les tags que vous avez configuré, vous épargnant ainsi l'effort de classifier vos articles manuellement."
+"They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.": "Ce sont des règles utilisées par wallabag pour classer automatiquement vos nouveaux articles.<br />À chaque fois qu'un nouvel article est ajouté, toutes les règles de tag automatiques seront utilisées afin d'ajouter les tags que vous avez configurés, vous épargnant ainsi l'effort de classifier vos articles manuellement."
 How do I use them?: "Comment les utiliser ?"
 "Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » then tag as « <i>long reading, github </i> »": "Imaginons que voulez attribuer aux nouveaux articles le tag « <i>lecture courte</i> » lorsque le temps de lecture est inférieur à 3 minutes.<br />Dans ce cas, vous devriez mettre « readingTime &lt;= 3 » dans le champ <i>Règle</i> et « <i>lecture courte</i> » dans le champ <i>Tag</i>.<br />Plusieurs tags peuvent être ajoutés simultanément en les séparant par des virgules : « <i>lecture courte, à lire</i> »<br />Des règles complexes peuvent être créées en utilisant des opérateurs prédéfinis: si « <i>readingTime &gt;= 5 AND domainName = \"github.com\"</i> » alors attribuer les tags « <i>lecteur longue, github </i> »"
 Which variables and operators can I use to write rules?: "Quelles variables et opérateurs puis-je utiliser pour écrire des règles ?"
@@ -194,14 +194,14 @@ Download: 'Télécharger'
 Does this article appear wrong?: "Est-ce que cet article s'affiche mal ?"
 Problems?: 'Un problème ?'
 Edit title: "Modifier le titre"
-Re-fetch content: Recharger le contenu
-Tag added: Tag ajouté
+Re-fetch content: "Recharger le contenu"
+Tag added: "Tag ajouté"
 
 # Import
 Welcome to wallabag importer. Please select your previous service that you want to migrate.: "Bienvenue dans l'outil de migration de wallabag. Choisissez ci-dessous le service depuis lequel vous souhaitez migrer."
 "This importer will import all your Pocket data. Pocket doesn't allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag.": "Cet outil va importer toutes vos données de Pocket. Pocket ne nous autorise pas à récupérer le contenu depuis leur service, donc wallabag doit reparcourir chaque article pour récupérer son contenu."
 "This importer will import all your wallabag v1 articles. On your config page, click on \"JSON export\" in the \"Export your wallabag data\" section. You will have a \"wallabag-export-1-xxxx-xx-xx.json\" file.": "Cet outil va importer toutes vos données de wallabag v1. Sur votre page de configuration de wallabag v1, cliquez sur \"Export JSON\" dans la section \"Exporter vos données de wallabag\". Vous allez récupérer un fichier \"wallabag-export-1-xxxx-xx-xx.json\"."
-"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.": "Cet outil va importer toutes 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\""
+"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.": "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\""
 "You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.": "Vous pouvez importer vos données depuis votre compte Pocket. Vous n'avez qu'à cliquer sur le bouton ci-dessous et à autoriser wallabag à se connecter à getpocket.com."
 Import > Pocket: "Import > Pocket"
 Pocket import isn't configured.: "L'import à partir de Pocket n'est pas configuré."
@@ -215,6 +215,8 @@ Import contents: "Importer les contenus"
 Import: "Importer"
 Import > Wallabag v1: "Importer > Wallabag v1"
 Import > Wallabag v2: "Importer > Wallabag v2"
+Mark all as read ?: "Marquer tout comme lu ?"
+Mark all imported entries as read: "Marquer tous les contenus importés comme lus"
 
 # Quickstart
 Quickstart: Pour bien débuter
diff --git a/src/Wallabag/CoreBundle/Resources/translations/validators.es.yml b/src/Wallabag/CoreBundle/Resources/translations/validators.es.yml
new file mode 100644 (file)
index 0000000..5c0b6df
--- /dev/null
@@ -0,0 +1,3 @@
+# Config screen
+The password fields must match: 'Las contraseñas no coinciden'
+Password should by at least 8 chars long: 'La contraseña debe tener al menos 8 carácteres'
index 2748c7e3a295e19eda05bea535ccc9675fe1231a..4c0d4fee99470d5f5b078700acef030346bbdb9e 100644 (file)
@@ -71,7 +71,7 @@
         {% block footer %}{% endblock %}
 
         <div id="warning_message">
-            You're trying wallabag v2, which is in alpha version. If you find a bug, please have a look to <a href="https://github.com/wallabag/wallabag/issues">our issues list</a> and <a href="https://github.com/wallabag/wallabag/issues/new">open a new if necessary</a>
+            You're trying wallabag v2, which is in beta version. If you find a bug, please have a look to <a href="https://github.com/wallabag/wallabag/issues">our issues list</a> and <a href="https://github.com/wallabag/wallabag/issues/new">open a new one if necessary</a>.
         </div>
 
         {% if craue_setting('piwik_enabled') %}
index 3984081c6a007aa30b9d39f34c2b8c51a7ee9b01..319eaea392a32241aafcce87b77cc2e9b8f330e0 100644 (file)
@@ -4,32 +4,47 @@
 
 {% block content %}
 
-    <h2>{% trans %}Welcome to wallabag!{% endtrans %}</h2>
+    <h3>{% trans %}Welcome to wallabag!{% endtrans %}</h3>
     <p>{% trans %}We'll accompany you to visit wallabag and show you some features which can interess you.{% endtrans %}</p>
     <p>{% trans %}Follow us!{% endtrans %}</p>
     <h4>{% trans %}Configure the application{% endtrans %}</h4>
     <ul>
         <li><a href="{{ path('config') }}">{% trans %}Change language and design{% endtrans %}</a></li>
         <li><a href="{{ path('config') }}#set2">{% trans %}Enable RSS feeds{% endtrans %}</a></li>
+        <li><a href="{{ path('config') }}#set5">{% trans %}Write rules to automatically tag your articles{% endtrans %}</a></li>
     </ul>
-    <h3>{% trans %}First steps{% endtrans %}</h3>
+    {% if is_granted('ROLE_SUPER_ADMIN') %}
+        <h4>{% trans %}Administration{% endtrans %}</h4>
+        <p>{% trans %}As a administrator, you have privileges on wallabag. You can:{% endtrans %}</p>
+        <ul>
+            <li><a href="{{ path('config') }}#set6">{% trans %}Create a new user{% endtrans %}</a></li>
+            <li><a href="{{ path('craue_config_settings_modify') }}#set-analytics">{% trans %}Configure analytics{% endtrans %}</a></li>
+            <li><a href="{{ path('craue_config_settings_modify') }}#set-entry">{% trans %}Enable some parameters about article sharing{% endtrans %}</a></li>
+            <li><a href="{{ path('craue_config_settings_modify') }}#set-export">{% trans %}Configure export{% endtrans %}</a></li>
+            <li><a href="{{ path('craue_config_settings_modify') }}#set-import">{% trans %}Configure import{% endtrans %}</a></li>
+        </ul>
+    {% endif %}
+    <h4>{% trans %}First steps{% endtrans %}</h4>
     <ul>
         <li><a href="{{ path('new') }}">{% trans %}Save your first article{% endtrans %}</a></li>
         <li><a href="{{ path('unread') }}">{% trans %}And classify it!{% endtrans %}</a></li>
     </ul>
-    <h3>{% trans %}Migrate from an existing service{% endtrans %}</h3>
+    <h4>{% trans %}Migrate from an existing service{% endtrans %}</h4>
     <p>{% trans %}You're using an other service? We'll help you to retrieve your data on wallabag.{% endtrans %}</p>
     <ul>
         <li><a href="{{ path('import_pocket') }}">{% trans %}Migrate from Pocket{% endtrans %}</a></li>
         <li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li>
+        <li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li>
     </ul>
-    <h3>{% trans %}Full documentation{% endtrans %}</h3>
+    <h4>{% trans %}Full documentation{% endtrans %}</h4>
     <ul>
+        <li><a href="http://wallabag.readthedocs.org">{% trans %}Annotate your article{% endtrans %}</a></li>
         <li><a href="http://wallabag.readthedocs.org">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
         <li><a href="http://wallabag.readthedocs.org">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
+        <li><a href="http://wallabag.readthedocs.org">{% trans %}What can I do if an article encounters errors during fetching?{% endtrans %}</a></li>
         <li><a href="http://wallabag.readthedocs.org">{% trans %}And so many other articles!{% endtrans %}</a></li>
     </ul>
-    <h3>{% trans %}Support{% endtrans %}</h3>
+    <h4>{% trans %}Support{% endtrans %}</h4>
     <p>{% trans %}If you need some help, we are here for you.{% endtrans %}</p>
     <ul>
         <li><a href="https://github.com/wallabag/wallabag/issues/">{% trans %}On GitHub{% endtrans %}</a></li>
index 6c786951aa9d1e1f989b01cd7601e10e408cf3e3..dea4242b4491619e97d36750118b2983c58fc311 100644 (file)
                     <ul>
                         <li><a href="{{ path('config') }}">{% trans %}Change language and design{% endtrans %}</a></li>
                         <li><a href="{{ path('config') }}#set2">{% trans %}Enable RSS feeds{% endtrans %}</a></li>
+                        <li><a href="{{ path('config') }}#set5">{% trans %}Write rules to automatically tag your articles{% endtrans %}</a></li>
                     </ul>
+                    {% if is_granted('ROLE_SUPER_ADMIN') %}
+                    <h4>{% trans %}Administration{% endtrans %}</h4>
+                    <p>{% trans %}As a administrator, you have privileges on wallabag. You can:{% endtrans %}</p>
+                    <ul>
+                        <li><a href="{{ path('config') }}#set6">{% trans %}Create a new user{% endtrans %}</a></li>
+                        <li><a href="{{ path('craue_config_settings_modify') }}#set-analytics">{% trans %}Configure analytics{% endtrans %}</a></li>
+                        <li><a href="{{ path('craue_config_settings_modify') }}#set-entry">{% trans %}Enable some parameters about article sharing{% endtrans %}</a></li>
+                        <li><a href="{{ path('craue_config_settings_modify') }}#set-export">{% trans %}Configure export{% endtrans %}</a></li>
+                        <li><a href="{{ path('craue_config_settings_modify') }}#set-import">{% trans %}Configure import{% endtrans %}</a></li>
+                    </ul>
+                    {% endif %}
                     <h4>{% trans %}First steps{% endtrans %}</h4>
                     <ul>
                         <li><a href="{{ path('new') }}">{% trans %}Save your first article{% endtrans %}</a></li>
@@ -27,6 +39,7 @@
                     <ul>
                         <li><a href="{{ path('import_pocket') }}">{% trans %}Migrate from Pocket{% endtrans %}</a></li>
                         <li><a href="{{ path('import_wallabag_v1') }}">{% trans %}Migrate from wallabag v1{% endtrans %}</a></li>
+                        <li><a href="{{ path('import_wallabag_v2') }}">{% trans %}Migrate from wallabag v2{% endtrans %}</a></li>
                     </ul>
                     <h4>{% trans %}Developers{% endtrans %}</h4>
                     <ul>
                     </ul>
                     <h4>{% trans %}Full documentation{% endtrans %}</h4>
                     <ul>
+                        <li><a href="http://wallabag.readthedocs.org">{% trans %}Annotate your article{% endtrans %}</a></li>
                         <li><a href="http://wallabag.readthedocs.org">{% trans %}Convert your articles into ePUB or PDF{% endtrans %}</a></li>
                         <li><a href="http://wallabag.readthedocs.org">{% trans %}See how you can look for an article by using search engine and filters{% endtrans %}</a></li>
+                        <li><a href="http://wallabag.readthedocs.org">{% trans %}What can I do if an article encounters errors during fetching?{% endtrans %}</a></li>
                         <li><a href="http://wallabag.readthedocs.org">{% trans %}And so many other articles!{% endtrans %}</a></li>
                     </ul>
                     <h4>{% trans %}Support{% endtrans %}</h4>
index 1c1b4fa889f6a1919f722cba934d07098e8a196f..c88e115e4a426ae29b5da248092993c4a3db1965 100644 (file)
@@ -5,6 +5,8 @@ namespace Wallabag\ImportBundle\Controller;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 
 class PocketController extends Controller
 {
@@ -13,21 +15,31 @@ class PocketController extends Controller
      */
     public function indexAction()
     {
+        $pocket = $this->get('wallabag_import.pocket.import');
+        $form = $this->createFormBuilder($pocket)
+            ->add('read', CheckboxType::class, array(
+                'label' => 'Mark all as read',
+                'required' => false,
+            ))
+            ->getForm();
+
         return $this->render('WallabagImportBundle:Pocket:index.html.twig', [
             'import' => $this->get('wallabag_import.pocket.import'),
             'has_consumer_key' => '' == trim($this->get('craue_config')->get('pocket_consumer_key')) ? false : true,
+            'form' => $form->createView(),
         ]);
     }
 
     /**
      * @Route("/pocket/auth", name="import_pocket_auth")
      */
-    public function authAction()
+    public function authAction(Request $request)
     {
         $requestToken = $this->get('wallabag_import.pocket.import')
             ->getRequestToken($this->generateUrl('import', array(), UrlGeneratorInterface::ABSOLUTE_URL));
 
         $this->get('session')->set('import.pocket.code', $requestToken);
+        $this->get('session')->set('read', $request->request->get('form')['read']);
 
         return $this->redirect(
             'https://getpocket.com/auth/authorize?request_token='.$requestToken.'&redirect_uri='.$this->generateUrl('import_pocket_callback', array(), UrlGeneratorInterface::ABSOLUTE_URL),
@@ -42,6 +54,8 @@ class PocketController extends Controller
     {
         $message = 'Import failed, please try again.';
         $pocket = $this->get('wallabag_import.pocket.import');
+        $markAsRead = $this->get('session')->get('read');
+        $this->get('session')->remove('read');
 
         // something bad happend on pocket side
         if (false === $pocket->authorize($this->get('session')->get('import.pocket.code'))) {
@@ -53,7 +67,7 @@ class PocketController extends Controller
             return $this->redirect($this->generateUrl('import_pocket'));
         }
 
-        if (true === $pocket->import()) {
+        if (true === $pocket->setMarkAsRead($markAsRead)->import()) {
             $summary = $pocket->getSummary();
             $message = 'Import summary: '.$summary['imported'].' imported, '.$summary['skipped'].' already saved.';
         }
index 35fe620f8adaf83cbbb37e0953bbb34a2d83eafe..154a0769b0ac4688008e4f012b08499f28d28dda 100644 (file)
@@ -21,15 +21,18 @@ class WallabagV1Controller extends Controller
 
         if ($form->isValid()) {
             $file = $form->get('file')->getData();
+            $markAsRead = $form->get('mark_as_read')->getData();
             $name = $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 = $wallabag
                     ->setUser($this->getUser())
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
+                    ->setMarkAsRead($markAsRead)
                     ->import();
 
                 $message = 'Import failed, please try again.';
+
                 if (true === $res) {
                     $summary = $wallabag->getSummary();
                     $message = 'Import summary: '.$summary['imported'].' imported, '.$summary['skipped'].' already saved.';
index 2e6225f295ec15146e9cdb1c4dc259fd7b37e0d1..6dcd204a7240a6d15f0fc84f035c4a254e663869 100644 (file)
@@ -21,12 +21,14 @@ class WallabagV2Controller extends Controller
 
         if ($form->isValid()) {
             $file = $form->get('file')->getData();
+            $markAsRead = $form->get('mark_as_read')->getData();
             $name = $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 = $wallabag
                     ->setUser($this->getUser())
                     ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
+                    ->setMarkAsRead($markAsRead)
                     ->import();
 
                 $message = 'Import failed, please try again.';
index 2e6b59cb4ae9d65e7731d4e4bd852616e0e70e44..386703796bbcbc34218c25697e792b0a3daec521 100644 (file)
@@ -6,6 +6,7 @@ use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\FormBuilderInterface;
 use Symfony\Component\Form\Extension\Core\Type\SubmitType;
 use Symfony\Component\Form\Extension\Core\Type\FileType;
+use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
 
 class UploadImportType extends AbstractType
 {
@@ -13,6 +14,10 @@ class UploadImportType extends AbstractType
     {
         $builder
             ->add('file', FileType::class)
+            ->add('mark_as_read', CheckboxType::class, array(
+                'label' => 'Mark all as read',
+                'required' => false,
+            ))
             ->add('save', SubmitType::class)
         ;
     }
index 5dfd098caf5e0d6d01f4bbcaa7d2cba929c5c0c5..238ddbd1f71548b304a24489b095a0e98f0b6fd4 100644 (file)
@@ -22,6 +22,7 @@ class PocketImport implements ImportInterface
     private $consumerKey;
     private $skippedEntries = 0;
     private $importedEntries = 0;
+    private $markAsRead;
     protected $accessToken;
 
     public function __construct(TokenStorageInterface $tokenStorage, EntityManager $em, ContentProxy $contentProxy, Config $craueConfig)
@@ -123,6 +124,26 @@ class PocketImport implements ImportInterface
         return true;
     }
 
+    /**
+     * 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 getRead()
+    {
+        return $this->markAsRead;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -201,7 +222,7 @@ class PocketImport implements ImportInterface
             $entry = $this->contentProxy->updateEntry($entry, $url);
 
             // 0, 1, 2 - 1 if the item is archived - 2 if the item should be deleted
-            if ($pocketEntry['status'] == 1) {
+            if ($pocketEntry['status'] == 1 || $this->markAsRead) {
                 $entry->setArchived(true);
             }
 
index 05bdb4014239bc1535619e0aa1f76fd016ce11aa..1d773d3bb58e2094ac057c490121c5dc9883479d 100644 (file)
@@ -19,6 +19,7 @@ class WallabagV1Import implements ImportInterface
     protected $skippedEntries = 0;
     protected $importedEntries = 0;
     protected $filepath;
+    protected $markAsRead;
 
     public function __construct(EntityManager $em, ContentProxy $contentProxy)
     {
@@ -120,6 +121,18 @@ class WallabagV1Import implements ImportInterface
         return $this;
     }
 
+    /**
+     * Set whether articles must be all marked as read.
+     *
+     * @param bool $markAsRead
+     */
+    public function setMarkAsRead($markAsRead)
+    {
+        $this->markAsRead = $markAsRead;
+
+        return $this;
+    }
+
     /**
      * @param $entries
      */
@@ -160,7 +173,7 @@ class WallabagV1Import implements ImportInterface
                 );
             }
 
-            $entry->setArchived($importedEntry['is_read']);
+            $entry->setArchived($importedEntry['is_read'] || $this->markAsRead);
             $entry->setStarred($importedEntry['is_fav']);
 
             $this->em->persist($entry);
index 7125eabc1681bff429ce543994feac6e325e2572..c4bac561580b8338220a268156f3da01bb49364f 100644 (file)
@@ -51,7 +51,7 @@ class WallabagV2Import extends WallabagV1Import implements ImportInterface
             $entry = new Entry($this->user);
             $entry->setUrl($importedEntry['url']);
             $entry->setTitle($importedEntry['title']);
-            $entry->setArchived($importedEntry['is_archived']);
+            $entry->setArchived($importedEntry['is_archived'] || $this->markAsRead);
             $entry->setStarred($importedEntry['is_starred']);
             $entry->setContent($importedEntry['content']);
             $entry->setReadingTime($importedEntry['reading_time']);
index 8aa5da9714cb79d842a9c6db8cb1c61f0354a8bd..3365fc6af1abe0a4ee455254ddaaceb433e4b6dd 100644 (file)
             <blockquote>{{ import.description|trans }}</blockquote>
             <p>{% trans %}You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.{% endtrans %}</p>
             <form method="post" action="{{ path('import_pocket_auth') }}">
+            <div class="row">
+                <div class="input-field col s6 with-checkbox">
+                    <h6>{% trans %}Mark all as read ?{% endtrans %}</h6>
+                        {{ form_widget(form.read) }}
+                    <label for="form_read">{% trans %}Mark all imported entries as read{% endtrans %}</label>
+                </div>
+            </div>
                 <button class="btn waves-effect waves-light" type="submit" name="action">
                     {% trans %}Connect to Pocket and import data{% endtrans %}
                 </button>
index 1359f2e40b2c8577970d234f6c2c22f69aee154c..a418ed1c5585fbe6478c570926b9ac2bc4386de5 100644 (file)
                                     <input class="file-path validate" type="text">
                                 </div>
                             </div>
+                            <div class="input-field col s6 with-checkbox">
+                                <h6>{% trans %}Mark all as read ?{% endtrans %}</h6>
+                                {{ form_widget(form.mark_as_read) }}
+                                <label for="upload_import_file_mark_as_read">{% trans %}Mark all imported entries as read{% endtrans %}</label>
+                            </div>
                         </div>
                         <div class="hidden">{{ form_rest(form) }}</div>
                         <button class="btn waves-effect waves-light" type="submit" name="action">
index 819bb0e60a38bb99e9198481e7f7f0031920e39b..7f97b0f5522719505d75e323296cda498e5f6837 100644 (file)
@@ -58,6 +58,50 @@ class WallabagV1ControllerTest extends WallabagCoreTestCase
         $this->assertContains('Import summary', $alert[0]);
     }
 
+    public function testImportWallabagWithFileAndMarkAllAsRead()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $crawler = $client->request('GET', '/import/wallabag-v1');
+        $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
+
+        $file = new UploadedFile(__DIR__.'/../fixtures/wallabag-v1-read.json', 'wallabag-v1-read.json');
+
+        $data = array(
+            '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(
+                'http://gilbert.pellegrom.me/recreating-the-square-slider',
+                $this->getLoggedInUserId()
+            );
+
+        $this->assertTrue($content1->isArchived());
+
+        $content2 = $client->getContainer()
+            ->get('doctrine.orm.entity_manager')
+            ->getRepository('WallabagCoreBundle:Entry')
+            ->findByUrlAndUserId(
+                'https://www.wallabag.org/features/',
+                $this->getLoggedInUserId()
+            );
+
+        $this->assertTrue($content2->isArchived());
+
+        $this->assertContains('Import summary', $client->getResponse()->getContent());
+    }
+
     public function testImportWallabagWithEmptyFile()
     {
         $this->logInAs('admin');
index f44786b1a76d92dcc0293c3a18ffa62994bf4ddf..bc9e2f422d632e2ee0fe6d1e71b0c89201c5dd7e 100644 (file)
@@ -3,6 +3,7 @@
 namespace Wallabag\ImportBundle\Tests\Import;
 
 use Wallabag\UserBundle\Entity\User;
+use Wallabag\CoreBundle\Entity\Entry;
 use Wallabag\ImportBundle\Import\PocketImport;
 use GuzzleHttp\Client;
 use GuzzleHttp\Subscriber\Mock;
@@ -265,9 +266,7 @@ class PocketImportTest extends \PHPUnit_Framework_TestCase
             ->method('getRepository')
             ->willReturn($entryRepo);
 
-        $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
-            ->disableOriginalConstructor()
-            ->getMock();
+        $entry = new Entry($this->user);
 
         $this->contentProxy
             ->expects($this->once())
@@ -283,6 +282,95 @@ class PocketImportTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(['skipped' => 1, 'imported' => 1], $pocketImport->getSummary());
     }
 
+    /**
+     * Will sample results from https://getpocket.com/developer/docs/v3/retrieve.
+     */
+    public function testImportAndMarkAllAsRead()
+    {
+        $client = new Client();
+
+        $mock = new Mock([
+            new Response(200, ['Content-Type' => 'application/json'], Stream::factory(json_encode(['access_token' => 'wunderbar_token']))),
+            new Response(200, ['Content-Type' => 'application/json'], Stream::factory('
+                {
+                    "status": 1,
+                    "list": {
+                        "229279689": {
+                            "item_id": "229279689",
+                            "resolved_id": "229279689",
+                            "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
+                            "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
+                            "favorite": "1",
+                            "status": "1",
+                            "resolved_title": "The Massive Ryder Cup Preview",
+                            "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
+                            "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
+                            "is_article": "1",
+                            "has_video": "1",
+                            "has_image": "1",
+                            "word_count": "3197"
+                        },
+                        "229279690": {
+                            "item_id": "229279689",
+                            "resolved_id": "229279689",
+                            "given_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview/2",
+                            "given_title": "The Massive Ryder Cup Preview - The Triangle Blog - Grantland",
+                            "favorite": "1",
+                            "status": "0",
+                            "resolved_title": "The Massive Ryder Cup Preview",
+                            "resolved_url": "http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview",
+                            "excerpt": "The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.",
+                            "is_article": "1",
+                            "has_video": "0",
+                            "has_image": "0",
+                            "word_count": "3197"
+                        }
+                    }
+                }
+            ')),
+        ]);
+
+        $client->getEmitter()->attach($mock);
+
+        $pocketImport = $this->getPocketImport();
+
+        $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->exactly(2))
+            ->method('getRepository')
+            ->willReturn($entryRepo);
+
+        // check that every entry persisted are archived
+        $this->em
+            ->expects($this->any())
+            ->method('persist')
+            ->with($this->callback(function($persistedEntry) {
+                return $persistedEntry->isArchived();
+            }));
+
+        $entry = new Entry($this->user);
+
+        $this->contentProxy
+            ->expects($this->exactly(2))
+            ->method('updateEntry')
+            ->willReturn($entry);
+
+        $pocketImport->setClient($client);
+        $pocketImport->authorize('wunderbar_code');
+
+        $res = $pocketImport->setMarkAsRead(true)->import();
+
+        $this->assertTrue($res);
+        $this->assertEquals(['skipped' => 0, 'imported' => 2], $pocketImport->getSummary());
+    }
+
     public function testImportBadResponse()
     {
         $client = new Client();
index 9a563a1158eb18c3e8d506f2529517e1e66a3bf0..fbcd270d31d6a39bcf8dd5ef374b243d9e955d3b 100644 (file)
@@ -81,6 +81,39 @@ class WallabagV1ImportTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(['skipped' => 1, 'imported' => 3], $wallabagV1Import->getSummary());
     }
 
+    public function testImportAndMarkAllAsRead()
+    {
+        $wallabagV1Import = $this->getWallabagV1Import();
+        $wallabagV1Import->setFilepath(__DIR__.'/../fixtures/wallabag-v1-read.json');
+
+        $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $entryRepo->expects($this->exactly(3))
+            ->method('findByUrlAndUserId')
+            ->will($this->onConsecutiveCalls(false, false, false));
+
+        $this->em
+            ->expects($this->any())
+            ->method('getRepository')
+            ->willReturn($entryRepo);
+
+        // check that every entry persisted are archived
+        $this->em
+            ->expects($this->any())
+            ->method('persist')
+            ->with($this->callback(function($persistedEntry) {
+                return $persistedEntry->isArchived();
+            }));
+
+        $res = $wallabagV1Import->setMarkAsRead(true)->import();
+
+        $this->assertTrue($res);
+
+        $this->assertEquals(['skipped' => 0, 'imported' => 3], $wallabagV1Import->getSummary());
+    }
+
     public function testImportBadFile()
     {
         $wallabagV1Import = $this->getWallabagV1Import();
index 3268cd3e8a96057ae77b43c2c5c2757f97c837fc..c461168ce5344a52f5cf3a6954b5b5310daa93b5 100644 (file)
@@ -72,6 +72,39 @@ class WallabagV2ImportTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(['skipped' => 1, 'imported' => 2], $wallabagV2Import->getSummary());
     }
 
+    public function testImportAndMarkAllAsRead()
+    {
+        $wallabagV2Import = $this->getWallabagV2Import();
+        $wallabagV2Import->setFilepath(__DIR__.'/../fixtures/wallabag-v2-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);
+
+        // check that every entry persisted are archived
+        $this->em
+            ->expects($this->any())
+            ->method('persist')
+            ->with($this->callback(function($persistedEntry) {
+                return $persistedEntry->isArchived();
+            }));
+
+        $res = $wallabagV2Import->setMarkAsRead(true)->import();
+
+        $this->assertTrue($res);
+
+        $this->assertEquals(['skipped' => 0, 'imported' => 2], $wallabagV2Import->getSummary());
+    }
+
     public function testImportBadFile()
     {
         $wallabagV1Import = $this->getWallabagV2Import();
diff --git a/src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v1-read.json b/src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v1-read.json
new file mode 100644 (file)
index 0000000..c4d1cf5
--- /dev/null
@@ -0,0 +1,53 @@
+[
+    {
+        "0": "3",
+        "1": "Features - wallabag",
+        "2": "https://www.wallabag.org/features/",
+        "3": "0",
+        "4": "1",
+        "5": "\n\t\t<p>Here are some features. If one is missing, you can <a href=\"https://github.com/wallabag/wallabag\">open a new issue</a>.</p>\n<ul class=\"list-group\"><li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> wallabag is free and open source. Forever.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> No time to read? Save a link in your wallabag to read it later</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Read the saved articles in a comfortable view: the content, only the content</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You save all the content: text and pictures</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can easily migrate from others private services.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You like an article? Share it by email, on twitter or in your <a href=\"https://github.com/sebsauvage/Shaarli\">shaarli</a></li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Because we are increasingly mobile, wallabag fits all your devices</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Saving a link is so easy because we provide you many tools: extensions for Chrome and Firefox, iOS, Android and Windows Phone application, a bookmarklet, a simple field in your config webpage. <a title=\"Download wallabag\" href=\"https://www.wallabag.org/downloads/\">You can download third-party applications here</a>.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> RSS feeds allows you to read your saved links in your RSS agregator</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can set tags to your entries.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> wallabag is multilingual: french, english, spanish, german, italian, russian, persian, czech, polish, ukrainian and slovienian.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You’re not the only one at home to use wallabag? it’s good, wallabag is multi users</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You prefer a dark template? Perfect, many templates are available in the configuration screen</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Many storage allowed: sqlite, mysql and postgresql</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Scroll position is saved: when you return on an article, you come back where you was. So convenient!</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can flattr flattrable articles directly from your wallabag</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You want to retrieve your wallabag datas? hey, remember, wallabag is open source, you can export it</li>\n</ul>",
+        "6": "1",
+        "id": "3",
+        "title": "Features - wallabag",
+        "url": "https://www.wallabag.org/features/",
+        "is_read": "0",
+        "is_fav": "1",
+        "content": "\n\t\t<p>Here are some features. If one is missing, you can <a href=\"https://github.com/wallabag/wallabag\">open a new issue</a>.</p>\n<ul class=\"list-group\"><li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> wallabag is free and open source. Forever.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> No time to read? Save a link in your wallabag to read it later</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Read the saved articles in a comfortable view: the content, only the content</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You save all the content: text and pictures</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can easily migrate from others private services.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You like an article? Share it by email, on twitter or in your <a href=\"https://github.com/sebsauvage/Shaarli\">shaarli</a></li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Because we are increasingly mobile, wallabag fits all your devices</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Saving a link is so easy because we provide you many tools: extensions for Chrome and Firefox, iOS, Android and Windows Phone application, a bookmarklet, a simple field in your config webpage. <a title=\"Download wallabag\" href=\"https://www.wallabag.org/downloads/\">You can download third-party applications here</a>.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> RSS feeds allows you to read your saved links in your RSS agregator</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can set tags to your entries.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> wallabag is multilingual: french, english, spanish, german, italian, russian, persian, czech, polish, ukrainian and slovienian.</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You’re not the only one at home to use wallabag? it’s good, wallabag is multi users</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You prefer a dark template? Perfect, many templates are available in the configuration screen</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Many storage allowed: sqlite, mysql and postgresql</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> Scroll position is saved: when you return on an article, you come back where you was. So convenient!</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You can flattr flattrable articles directly from your wallabag</li>\n<li class=\"list-group-item\"><span class=\"glyphicon glyphicon-ok\"></span> You want to retrieve your wallabag datas? hey, remember, wallabag is open source, you can export it</li>\n</ul>",
+        "user_id": "1",
+        "tags": ""
+    },
+    {
+        "0": "10",
+        "1": "Recreating The Square Slider",
+        "2": "http://gilbert.pellegrom.me/recreating-the-square-slider",
+        "3": "0",
+        "4": "0",
+        "5": "<p>The new <a href=\"https://squareup.com\">Square</a> site is lovely and I really like the slider they have on the homepage. So I decided to try and recreate it in a simple and reusable way.</p>\n\n<p>  \n  <a href=\"http://gilbert.pellegrom.me/demo/square-slider\">Demo</a> | <a href=\"http://dev7studios.com/downloads/50\">Download</a>\n</p>\n\n\n\n<h3>The HTML</h3>\n\n<pre class=\"language-markup\"><code>&lt;div class=\"square-slider\"&gt;  \n    &lt;div class=\"slide slide1\"&gt;\n        &lt;div class=\"content light\"&gt;\n            &lt;h3&gt;Recreating The Square Slider&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset1.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;div class=\"slide slide2\"&gt;\n        &lt;div class=\"content dark\"&gt;\n            &lt;h3&gt;Looks Amazing Right?&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset2.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;div class=\"slide slide3 inverted\"&gt;\n        &lt;div class=\"content light\"&gt;\n            &lt;h3&gt;And Simple To Use&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset3.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;a href=\"#\" class=\"prev\"&gt;Prev&lt;/a&gt;\n    &lt;a href=\"#\" class=\"next\"&gt;Next&lt;/a&gt;\n    &lt;div class=\"overlay\"&gt;&lt;/div&gt;\n&lt;/div&gt;</code></pre>\n\n<h3>The CSS</h3>\n\n<pre class=\"language-css\"><code>.square-slider {  \n    overflow: hidden;\n    position: relative;\n    background: #fff;\n}\n.square-slider .slide {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    display: none;\n    opacity: 0;\n    -moz-opacity: 0;\n    -moz-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -webkit-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -o-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -moz-transform: translate3d(0, 0, 0);\n    -webkit-transform: translate3d(0, 0, 0);\n    -o-transform: translate3d(0, 0, 0);\n    -ms-transform: translate3d(0, 0, 0);\n    transform: translate3d(0, 0, 0);\n}\n.square-slider .slide:first-child { display: block; }\n.square-slider .slide:first-child,\n.square-slider .slide.active {\n    opacity: 1;\n    -moz-opacity: 1;\n}\n.square-slider .slide .content {\n    position: absolute;\n    top: 40%;\n    left: 50%;\n    margin-left: -450px;\n    width: 360px;\n    text-shadow: 0 1px 1px rgba(0,0,0,0.3);\n    z-index: 7;\n    -webkit-transition-property: -webkit-transform,opacity;\n    -moz-transition-property: -moz-transform,opacity;\n    -webkit-transition-duration: 800ms,700ms;\n    -moz-transition-duration: 800ms,700ms;\n    -webkit-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -moz-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -webkit-transform: translate3d(-30px, 0, 0);\n    -moz-transform: translate(-30px, 0);\n}\n.square-slider .slide.inverted .content {\n    left: auto;\n    right: 50%;\n    margin-left: 0;\n    margin-right: -450px;\n    -webkit-transform: translate3d(30px, 0, 0);\n    -moz-transform: translate(30px, 0);\n}\n.square-slider .slide.active .content {\n    -webkit-transform: translate3d(0, 0, 0);\n    -moz-transform: translate(0, 0);\n}\n.square-slider .slide .asset {\n    position: absolute;\n    bottom: 0;\n    left: 50%;\n    -webkit-transition-property: -webkit-transform,opacity;\n    -moz-transition-property: -moz-transform,opacity;\n    -webkit-transition-duration: 800ms,700ms;\n    -moz-transition-duration: 800ms,700ms;\n    -webkit-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -moz-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -webkit-transform: translate3d(0, 0, 0);\n    -moz-transform: translate(0, 0);\n}\n.square-slider .slide.inverted .asset {\n    left: auto;\n    right: 50%;\n}\n.square-slider .slide.active .asset {\n    -webkit-transform: translate3d(-7px, 3px, 0);\n    -moz-transform: translate(-7px, 3px);\n}\n.square-slider .slide.inverted.active .asset {\n    -webkit-transform: translate3d(7px, 3px, 0);\n    -moz-transform: translate(7px, 3px);\n}\n.square-slider .prev,\n.square-slider .next {\n    background: url(images/nav.png) no-repeat;\n    display: block;\n    width: 67px;\n    height: 67px;\n    position: absolute;\n    top: 50%;\n    margin-top: -30px;\n    z-index: 10;\n    border: 0;\n    text-indent: -9999px;\n    display: none;\n    opacity: 0.6;\n    -moz-opacity: 0.6;\n    -webkit-transition: opacity 0.5s ease-in;\n    -moz-transition: opacity 0.5s ease-in;\n    -ms-transition: opacity 0.5s ease-in;\n    -o-transition: opacity 0.5s ease-in;\n    transition: opacity 0.5s ease-in;\n}\n.square-slider .prev { \n    left: 40px; \n    background-position: 0 100%;\n}\n.square-slider .next { right: 40px; }\n.square-slider .prev:hover,\n.square-slider .next:hover {\n    opacity: 1;\n    -moz-opacity: 1;\n}\n.square-slider .overlay {\n    position: absolute;\n    top: 0;\n    left: -100%;\n    width: 300%;\n    height: 100%;\n    z-index: 5;\n    -moz-box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n    -webkit-box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n    box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n}\n\n\n.square-slider {\n    width: 100%;\n    height: 550px;\n    margin: 40px auto;\n}\n.square-slider .slide .content.light { color: #fff; }\n.square-slider .slide .content.dark { \n    color: #333; \n    text-shadow: 0 1px 1px rgba(255,255,255,0.3);\n}\n.square-slider .slide1 { background: url(images/bg1.jpg) no-repeat 50% 50%; }\n.square-slider .slide2 { background: url(images/bg2.jpg) no-repeat 50% 50%; }\n.square-slider .slide3 { background: url(images/bg3.jpg) no-repeat 50% 50%; }</code></pre>\n\n<h3>The Javascript (jQuery)</h3>\n\n<pre class=\"language-javascript\"><code>(function($){\n\n    $('.square-slider').each(function(){\n        var slider = $(this),\n            slides = slider.find('.slide'),\n            currentSlide = 0;\n\n        slides.show();\n        $(slides[currentSlide]).addClass('active');\n        $('.next,.prev', slider).show();\n\n        $('.prev', slider).on('click', function(){\n            slides.removeClass('active');\n            currentSlide--;\n            if(currentSlide &lt; 0) currentSlide = slides.length - 1;\n            $(slides[currentSlide]).addClass('active');\n            return false;\n        });\n\n        $('.next', slider).on('click', function(){\n            slides.removeClass('active');\n            currentSlide++;\n            if(currentSlide &gt; slides.length - 1) currentSlide = 0;\n            $(slides[currentSlide]).addClass('active');\n            return false;\n        });\n    });\n\n})(window.jQuery);</code></pre>\n\n<h3>A Few Notes</h3>\n\n<ul><li>Feel free to <a href=\"http://dev7studios.com/downloads/50\">download the source</a> and customise and use it in your own sites. <strong>Don’t</strong> use the images as they belong to <a href=\"https://squareup.com\">Square Inc</a>.</li>\n<li>Add the <code>.inverted</code> class to a <code>.slide</code> div to swap the position of the asset and content.</li>\n<li>Depending on the background you’ll want to use the <code>.light</code> or <code>.dark</code> class on the <code>.content</code> divs.</li>\n<li>This is pretty much cross browser (as in the slider itself will still work in most browsers, just not with the fancy transitions).</li>\n<li>If javascript is off (really?) it displays the first slide.</li>\n<li>Source code is Public domain.</li>\n</ul><p>Enjoy.</p>\n        ",
+        "6": "1",
+        "id": "10",
+        "title": "Recreating The Square Slider",
+        "url": "http://gilbert.pellegrom.me/recreating-the-square-slider",
+        "is_read": "0",
+        "is_fav": "0",
+        "content": "<p>The new <a href=\"https://squareup.com\">Square</a> site is lovely and I really like the slider they have on the homepage. So I decided to try and recreate it in a simple and reusable way.</p>\n\n<p>  \n  <a href=\"http://gilbert.pellegrom.me/demo/square-slider\">Demo</a> | <a href=\"http://dev7studios.com/downloads/50\">Download</a>\n</p>\n\n\n\n<h3>The HTML</h3>\n\n<pre class=\"language-markup\"><code>&lt;div class=\"square-slider\"&gt;  \n    &lt;div class=\"slide slide1\"&gt;\n        &lt;div class=\"content light\"&gt;\n            &lt;h3&gt;Recreating The Square Slider&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset1.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;div class=\"slide slide2\"&gt;\n        &lt;div class=\"content dark\"&gt;\n            &lt;h3&gt;Looks Amazing Right?&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset2.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;div class=\"slide slide3 inverted\"&gt;\n        &lt;div class=\"content light\"&gt;\n            &lt;h3&gt;And Simple To Use&lt;/h3&gt;\n            &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac eros et augue vulputate \n            aliquet pellentesque vitae tortor. Pellentesque mi velit, euismod nec semper&lt;/p&gt;\n        &lt;/div&gt;\n        &lt;img src=\"images/asset3.png\" alt=\"\" class=\"asset\" /&gt;\n    &lt;/div&gt;\n    &lt;a href=\"#\" class=\"prev\"&gt;Prev&lt;/a&gt;\n    &lt;a href=\"#\" class=\"next\"&gt;Next&lt;/a&gt;\n    &lt;div class=\"overlay\"&gt;&lt;/div&gt;\n&lt;/div&gt;</code></pre>\n\n<h3>The CSS</h3>\n\n<pre class=\"language-css\"><code>.square-slider {  \n    overflow: hidden;\n    position: relative;\n    background: #fff;\n}\n.square-slider .slide {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    display: none;\n    opacity: 0;\n    -moz-opacity: 0;\n    -moz-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -webkit-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -o-transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    transition: opacity 800ms cubic-bezier(0.51, 0.01, 0.37, 0.98) 100ms;\n    -moz-transform: translate3d(0, 0, 0);\n    -webkit-transform: translate3d(0, 0, 0);\n    -o-transform: translate3d(0, 0, 0);\n    -ms-transform: translate3d(0, 0, 0);\n    transform: translate3d(0, 0, 0);\n}\n.square-slider .slide:first-child { display: block; }\n.square-slider .slide:first-child,\n.square-slider .slide.active {\n    opacity: 1;\n    -moz-opacity: 1;\n}\n.square-slider .slide .content {\n    position: absolute;\n    top: 40%;\n    left: 50%;\n    margin-left: -450px;\n    width: 360px;\n    text-shadow: 0 1px 1px rgba(0,0,0,0.3);\n    z-index: 7;\n    -webkit-transition-property: -webkit-transform,opacity;\n    -moz-transition-property: -moz-transform,opacity;\n    -webkit-transition-duration: 800ms,700ms;\n    -moz-transition-duration: 800ms,700ms;\n    -webkit-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -moz-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -webkit-transform: translate3d(-30px, 0, 0);\n    -moz-transform: translate(-30px, 0);\n}\n.square-slider .slide.inverted .content {\n    left: auto;\n    right: 50%;\n    margin-left: 0;\n    margin-right: -450px;\n    -webkit-transform: translate3d(30px, 0, 0);\n    -moz-transform: translate(30px, 0);\n}\n.square-slider .slide.active .content {\n    -webkit-transform: translate3d(0, 0, 0);\n    -moz-transform: translate(0, 0);\n}\n.square-slider .slide .asset {\n    position: absolute;\n    bottom: 0;\n    left: 50%;\n    -webkit-transition-property: -webkit-transform,opacity;\n    -moz-transition-property: -moz-transform,opacity;\n    -webkit-transition-duration: 800ms,700ms;\n    -moz-transition-duration: 800ms,700ms;\n    -webkit-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -moz-transition-timing-function: cubic-bezier(0.51, 0.01, 0.37, 0.98);\n    -webkit-transform: translate3d(0, 0, 0);\n    -moz-transform: translate(0, 0);\n}\n.square-slider .slide.inverted .asset {\n    left: auto;\n    right: 50%;\n}\n.square-slider .slide.active .asset {\n    -webkit-transform: translate3d(-7px, 3px, 0);\n    -moz-transform: translate(-7px, 3px);\n}\n.square-slider .slide.inverted.active .asset {\n    -webkit-transform: translate3d(7px, 3px, 0);\n    -moz-transform: translate(7px, 3px);\n}\n.square-slider .prev,\n.square-slider .next {\n    background: url(images/nav.png) no-repeat;\n    display: block;\n    width: 67px;\n    height: 67px;\n    position: absolute;\n    top: 50%;\n    margin-top: -30px;\n    z-index: 10;\n    border: 0;\n    text-indent: -9999px;\n    display: none;\n    opacity: 0.6;\n    -moz-opacity: 0.6;\n    -webkit-transition: opacity 0.5s ease-in;\n    -moz-transition: opacity 0.5s ease-in;\n    -ms-transition: opacity 0.5s ease-in;\n    -o-transition: opacity 0.5s ease-in;\n    transition: opacity 0.5s ease-in;\n}\n.square-slider .prev { \n    left: 40px; \n    background-position: 0 100%;\n}\n.square-slider .next { right: 40px; }\n.square-slider .prev:hover,\n.square-slider .next:hover {\n    opacity: 1;\n    -moz-opacity: 1;\n}\n.square-slider .overlay {\n    position: absolute;\n    top: 0;\n    left: -100%;\n    width: 300%;\n    height: 100%;\n    z-index: 5;\n    -moz-box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n    -webkit-box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n    box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);\n}\n\n\n.square-slider {\n    width: 100%;\n    height: 550px;\n    margin: 40px auto;\n}\n.square-slider .slide .content.light { color: #fff; }\n.square-slider .slide .content.dark { \n    color: #333; \n    text-shadow: 0 1px 1px rgba(255,255,255,0.3);\n}\n.square-slider .slide1 { background: url(images/bg1.jpg) no-repeat 50% 50%; }\n.square-slider .slide2 { background: url(images/bg2.jpg) no-repeat 50% 50%; }\n.square-slider .slide3 { background: url(images/bg3.jpg) no-repeat 50% 50%; }</code></pre>\n\n<h3>The Javascript (jQuery)</h3>\n\n<pre class=\"language-javascript\"><code>(function($){\n\n    $('.square-slider').each(function(){\n        var slider = $(this),\n            slides = slider.find('.slide'),\n            currentSlide = 0;\n\n        slides.show();\n        $(slides[currentSlide]).addClass('active');\n        $('.next,.prev', slider).show();\n\n        $('.prev', slider).on('click', function(){\n            slides.removeClass('active');\n            currentSlide--;\n            if(currentSlide &lt; 0) currentSlide = slides.length - 1;\n            $(slides[currentSlide]).addClass('active');\n            return false;\n        });\n\n        $('.next', slider).on('click', function(){\n            slides.removeClass('active');\n            currentSlide++;\n            if(currentSlide &gt; slides.length - 1) currentSlide = 0;\n            $(slides[currentSlide]).addClass('active');\n            return false;\n        });\n    });\n\n})(window.jQuery);</code></pre>\n\n<h3>A Few Notes</h3>\n\n<ul><li>Feel free to <a href=\"http://dev7studios.com/downloads/50\">download the source</a> and customise and use it in your own sites. <strong>Don’t</strong> use the images as they belong to <a href=\"https://squareup.com\">Square Inc</a>.</li>\n<li>Add the <code>.inverted</code> class to a <code>.slide</code> div to swap the position of the asset and content.</li>\n<li>Depending on the background you’ll want to use the <code>.light</code> or <code>.dark</code> class on the <code>.content</code> divs.</li>\n<li>This is pretty much cross browser (as in the slider itself will still work in most browsers, just not with the fancy transitions).</li>\n<li>If javascript is off (really?) it displays the first slide.</li>\n<li>Source code is Public domain.</li>\n</ul><p>Enjoy.</p>\n        ",
+        "user_id": "1",
+        "tags": ""
+    },
+    {
+        "0": "11",
+        "1": "J’aime le logiciel libre",
+        "2": "http://framablog.org/2015/02/14/jaime-le-logiciel-libre/",
+        "3": "0",
+        "4": "0",
+        "5": "\n      <p>Aujourd’hui, c’est la <em>Saint Valentin</em>, et l’occasion de déclarer son amour des logiciels libres !</p>\n<p><a href=\"https://fsfe.org/campaigns/ilovefs/ilovefs.fr.html\"><img src=\"http://framablog.org/wp-content/uploads/2015/02/ilovefs-banner-extralarge.png\" alt=\"ilovefs-banner-extralarge\" width=\"627\" height=\"105\" class=\"aligncenter size-full wp-image-3239\" /></a></p>\n<p>Framasoft vous a déjà proposé <a href=\"http://framablog.org/2015/02/14/on-love-logiciel-libre/\">son adaptation délirante de poèmes</a> pour l’occasion, et voici une petite bande-dessinée qui synthétise l’événement :</p>\n<p><a href=\"http://framablog.org/wp-content/uploads/2015/02/dm_001_jaime_le_logiciel_libre.jpg\"><img src=\"http://framablog.org/wp-content/uploads/2015/02/dm_001_jaime_le_logiciel_libre.jpg\" alt=\"dm_001_jaime_le_logiciel_libre\" width=\"800\" height=\"1200\" class=\"aligncenter size-full wp-image-3265\" /></a></p>\n<p>Cette bande-dessinée est extraite du nouveau blog <a href=\"http://grisebouille.net/\">Grise Bouille</a> hébergé par Framasoft.</p>\n<p><em>Crédit : <a href=\"http://grisebouille.net/\">Simon Gee Giraudot</a> (Creative Commons By-Sa)</em></p>\n<div title=\"Diaspora*\"><a><span><img src=\"http://www.framablog.org/wp-content/uploads/2015/01/diaspora.jpg\" alt=\"\" /></span></a></div><div class=\"twoclick-js\"></div><div><h3><a href=\"http://framablog.org/author/gee/\" title=\"All posts by Gee\">Gee</a></h3><div class=\"bio-gravatar\"><img alt=\"\" src=\"http://0.gravatar.com/avatar/4f71e4ffe5d4d9d89b16949563cd41f3?s=90&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D90&amp;r=G\" class=\"avatar pull-left media-object avatar-90 photo\" height=\"90\" width=\"90\" /></div><a href=\"http://ptilouk.net/\" class=\"bio-icon bio-icon-website\"></a><a href=\"https://framasphere.org/u/gee\" class=\"bio-icon bio-icon-facebook\"></a><a href=\"https://twitter.com/ptilouk\" class=\"bio-icon bio-icon-twitter\"></a><p class=\"bio-description\">Auteur/dessinateur de bandes dessinées (Le Geektionnerd, Superflu, Bastards Inc, etc.) et doctorant en informatique sur son temps salarié.</p></div>    ",
+        "6": "1",
+        "id": "11",
+        "title": "J’aime le logiciel libre",
+        "url": "http://framablog.org/2015/02/14/jaime-le-logiciel-libre/",
+        "is_read": "0",
+        "is_fav": "0",
+        "content": "\n      <p>Aujourd’hui, c’est la <em>Saint Valentin</em>, et l’occasion de déclarer son amour des logiciels libres !</p>\n<p><a href=\"https://fsfe.org/campaigns/ilovefs/ilovefs.fr.html\"><img src=\"http://framablog.org/wp-content/uploads/2015/02/ilovefs-banner-extralarge.png\" alt=\"ilovefs-banner-extralarge\" width=\"627\" height=\"105\" class=\"aligncenter size-full wp-image-3239\" /></a></p>\n<p>Framasoft vous a déjà proposé <a href=\"http://framablog.org/2015/02/14/on-love-logiciel-libre/\">son adaptation délirante de poèmes</a> pour l’occasion, et voici une petite bande-dessinée qui synthétise l’événement :</p>\n<p><a href=\"http://framablog.org/wp-content/uploads/2015/02/dm_001_jaime_le_logiciel_libre.jpg\"><img src=\"http://framablog.org/wp-content/uploads/2015/02/dm_001_jaime_le_logiciel_libre.jpg\" alt=\"dm_001_jaime_le_logiciel_libre\" width=\"800\" height=\"1200\" class=\"aligncenter size-full wp-image-3265\" /></a></p>\n<p>Cette bande-dessinée est extraite du nouveau blog <a href=\"http://grisebouille.net/\">Grise Bouille</a> hébergé par Framasoft.</p>\n<p><em>Crédit : <a href=\"http://grisebouille.net/\">Simon Gee Giraudot</a> (Creative Commons By-Sa)</em></p>\n<div title=\"Diaspora*\"><a><span><img src=\"http://www.framablog.org/wp-content/uploads/2015/01/diaspora.jpg\" alt=\"\" /></span></a></div><div class=\"twoclick-js\"></div><div><h3><a href=\"http://framablog.org/author/gee/\" title=\"All posts by Gee\">Gee</a></h3><div class=\"bio-gravatar\"><img alt=\"\" src=\"http://0.gravatar.com/avatar/4f71e4ffe5d4d9d89b16949563cd41f3?s=90&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D90&amp;r=G\" class=\"avatar pull-left media-object avatar-90 photo\" height=\"90\" width=\"90\" /></div><a href=\"http://ptilouk.net/\" class=\"bio-icon bio-icon-website\"></a><a href=\"https://framasphere.org/u/gee\" class=\"bio-icon bio-icon-facebook\"></a><a href=\"https://twitter.com/ptilouk\" class=\"bio-icon bio-icon-twitter\"></a><p class=\"bio-description\">Auteur/dessinateur de bandes dessinées (Le Geektionnerd, Superflu, Bastards Inc, etc.) et doctorant en informatique sur son temps salarié.</p></div>    ",
+        "user_id": "1",
+        "tags": "framasoft,tag"
+    }
+]
diff --git a/src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v2-read.json b/src/Wallabag/ImportBundle/Tests/fixtures/wallabag-v2-read.json
new file mode 100644 (file)
index 0000000..3fa0bdd
--- /dev/null
@@ -0,0 +1,28 @@
+[
+    {
+        "id": 4668,
+        "title": "Wikimedia Foundation removes The Diary of Anne Frank due to copyright law requirements « Wikimedia blog",
+        "url": "https://blog.wikimedia.org/2016/02/10/anne-frank-diary-removal/",
+        "is_archived": true,
+        "is_starred": false,
+        "content": "<p><a href=\"https://commons.wikimedia.org/wiki/File:AnneFrankSchoolPhoto.jpg\" rel=\"attachment wp-att-45105\"><img class=\"alignnone size-full wp-image-45105\" src=\"https://wikimediablog.files.wordpress.com/2016/02/annefrankschoolphoto.jpg?w=316&amp;h=520\" alt=\"AnneFrankSchoolPhoto\" width=\"316\" height=\"520\"/></a><br/><small><i>Anne Frank in 1940. <a href=\"https://commons.wikimedia.org/wiki/File:AnneFrankSchoolPhoto.jpg\">Photo</a> by Collectie Anne Frank Stichting Amsterdam, public domain.</i></small></p>\n<p>Today, in an unfortunate example of the overreach of the United States’ current copyright law, the Wikimedia Foundation removed the Dutch-language text of <a href=\"https://en.wikipedia.org/wiki/The_Diary_of_a_Young_Girl\"><em>The Diary of a Young Girl</em></a>—more commonly known in English as the <em>Diary of Anne Frank—</em>from Wikisource.<sup id=\"one\"><a href=\"https://blog.wikimedia.org/2016/02/10/anne-frank-diary-removal/#cite1\">[1]</a></sup></p>\n<p>We took this action to comply with the United States’ <a href=\"https://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act\">Digital Millennium Copyright Act</a> (DMCA), as we believe the diary is still under US copyright protection under the law as it is currently written. Nevertheless, our removal serves as an excellent example of why the law should be changed to prevent repeated extensions of copyright terms, an issue that has plagued our communities <a href=\"https://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/2014-02-26/News_and_notes\">for years</a>.</p>\n<h3>What prompted us to remove the diary?</h3>\n<p>The deletion was required because the Foundation is under the jurisdiction of US law and is therefore subject to the DMCA, specifically <a href=\"https://www.law.cornell.edu/uscode/text/17/512\" target=\"_blank\">title 17, chapter 5, section 512 of the United States Code</a>. As we <a href=\"https://meta.wikimedia.org/wiki/Legal/URAA_Statement\" target=\"_blank\">noted</a> in 2013, “The location of the servers, incorporation, and headquarters are just three of many factors that establish US jurisdiction … if infringing content is linked to or embedded in Wikimedia projects, then  the Foundation may still be subject to liability for such use—either as a direct or contributory infringer.</p>\n<p>Based on email discussions sent to the Wikimedia Foundation at legal[at]wikimedia.org, we determined that the Wikimedia Foundation had either “actual knowledge” (i in the statute quoted below) or what is commonly called “red flag knowledge” (ii in the statute quoted below) that the Anne Frank text was hosted on Wikisource and was under copyright. The statute section states that a service provider is only protected by the DMCA when it:</p>\n<p><strong>(i) </strong>does not have actual knowledge that the material or an activity using the material on the system or network is infringing;</p>\n<p><strong>(ii) </strong>in the absence of such actual knowledge, is not aware of facts or circumstances from which infringing activity is apparent; or</p>\n<p>(The rest applies when we get a proper DMCA takedown notice.)</p>\n<p>Of particular concern, the US’ <a href=\"https://en.wikipedia.org/wiki/United_States_Court_of_Appeals_for_the_Ninth_Circuit\">9th Circuit Court of Appeals</a> stated in their ruling for <a href=\"http://law.justia.com/cases/federal/appellate-courts/ca9/09-55902/09-55902-2013-03-14.html\"><em>UMG Recordings, Inc. v. Shelter Capital Partners LLC</em></a> that in circumstances where a hosting provider (like the Wikimedia Foundation) is informed by a third party (like an unrelated user) about infringing copyrighted content, that would likely constitute either actual or red flag knowledge under the DMCA.</p>\n<p>We believe, based on the detail and specificity contained in the emails, that we received that we had actual knowledge sufficient for the DMCA to require us to perform a takedown even in the absence of a demand letter.</p>\n<h3>How is the diary still copyrighted?</h3>\n<p>You may wonder why or how the Anne Frank text is copyrighted at all, as <a href=\"https://en.wikipedia.org/wiki/Anne_Frank\">Anne Frank</a> died in February 1945. With 70 years having passed since her death, the text may have passed into public domain in the Netherlands on January 1, 2016, where it was first published, although <a href=\"http://www.npr.org/sections/thetwo-way/2015/12/31/461606275/mein-kampf-enters-public-domain-arguably-anne-franks-diary-may-too\">there is still some dispute about this</a>.</p>\n<p>However, in the United States, the Anne Frank original text will be under copyright until 2042. This is the result of several factors coming together, and the English-language Wikipedia has actually covered this issue with a multi-part test on its <a href=\"https://en.wikipedia.org/wiki/Wikipedia:Non-U.S._copyrights\">non-US copyrights content guideline.</a></p>\n<p>In short, there are three major laws that together make the diary still copyrighted:</p>\n<ol><li>In general, the U.S. copyright for works published before 1978 is 95 years from date of publication. This came about because copyrights in the U.S. were originally for 28 years, with the ability to then extend that for a second 28 years (making a total of 56). Starting with the <a href=\"https://en.wikipedia.org/wiki/Copyright_Act_of_1976\">1976 Copyright Act</a> and extending to several more acts, the renewal became automatic and was extended. Today, the total term of works published before 1978 is 95 years from date of publication.</li>\n<li>Foreign works of countries that are treaty partners to the United States are covered as if they were US works.</li>\n<li>Even if a country was not a treaty partner under copyright law at the time of a publication, the <a href=\"https://en.wikipedia.org/wiki/Uruguay_Round_Agreements_Act\">1994 Uruguay Round Agreements Act</a> (URAA) restored copyright to works that:\n<ul><li>had been published in a foreign country</li>\n<li>were still under copyright in that country in 1996</li>\n<li>and would have had U.S. copyright but for the fact they were published abroad.</li>\n</ul></li>\n</ol>\n<p>Court challenges to the URAA have all failed, with the most notable (<a href=\"https://en.wikipedia.org/wiki/Golan_v._Holder\"><em>Golan v. Holder</em></a>) resulting in a Supreme Court ruling that upheld the URAA.</p>\n<p>What that means for Anne Frank’s diary is unfortunately simple: no matter how it wound up in the United States and regardless of what formal copyright notices they used, the US grants it copyright until the year 2042, or 95 years after its original publication in 1947.</p>\n<p>Under current copyright law, this remains true regardless of its copyright status anywhere else in the world and regardless of whether it may have been in the public domain in the United States in the past.</p>\n<p><a href=\"https://wikimediafoundation.org/wiki/User:Jrogers_(WMF)\"><em>Jacob Rogers</em></a><em>, Legal Counsel*<br/>Wikimedia Foundation</em></p>\n<p><em>*Special thanks to </em><a href=\"https://wikimediafoundation.org/wiki/User:AMangalick_(WMF)\"><em>Anisha Mangalick</em></a><em>, Legal Fellow, for her assistance in this matter.</em></p>\n<p><a href=\"https://blog.wikimedia.org/2016/02/10/anne-frank-diary-removal/#one\">[1]</a> The diary text was originally located at <a href=\"https://nl.wikisource.org/wiki/Het_Achterhuis_(Anne_Frank)\" rel=\"nofollow\">https://nl.wikisource.org/wiki/Het_Achterhuis_(Anne_Frank)</a>.</p>\n<p><em>This article was edited to clarify that it is not just the location of the Wikimedia Foundation’s servers that determine whether we fall in US jurisdiction.</em></p>\n\t\t\t\t\t\t\t\t\t\t\t",
+        "mimetype": "text/html",
+        "language": "en",
+        "reading_time": 4,
+        "domain_name": "blog.wikimedia.org",
+        "tags": []
+    },
+    {
+        "id": 4667,
+        "title": "Tails - Tails 2.0.1 is out",
+        "url": "https://tails.boum.org/news/version_2.0.1/index.en.html",
+        "is_archived": false,
+        "is_starred": false,
+        "content": "<div id=\"pagebody\" readability=\"39\">\n<p>This release fixes <a href=\"https://tails.boum.org/security/Numerous_security_holes_in_2.0/index.en.html\">numerous security issues</a>. All users must upgrade as soon as possible.</p>\n<div class=\"toc\">\n<ol><li class=\"L1\"><a href=\"https://tails.boum.org/news/version_2.0.1/index.en.html#index1h1\">Changes</a></li>\n<li class=\"L1\"><a href=\"https://tails.boum.org/news/version_2.0.1/index.en.html#index2h1\">Known issues</a></li>\n<li class=\"L1\"><a href=\"https://tails.boum.org/news/version_2.0.1/index.en.html#index3h1\">Download or upgrade</a></li>\n<li class=\"L1\"><a href=\"https://tails.boum.org/news/version_2.0.1/index.en.html#index4h1\">What's coming up?</a></li>\n</ol></div>\n<h2>New features</h2>\n<ul><li readability=\"11\">\n<p>Tails now uses the GNOME Shell desktop environment, in its Classic mode. GNOME Shell provides a modern, simple, and actively developed desktop environment. The Classic mode keeps the traditional Applications, Places menu, and windows list. Accessibility and non-Latin input sources are also better integrated.</p>\n<p>To find your way around, <a href=\"https://tails.boum.org/doc/first_steps/introduction_to_gnome_and_the_tails_desktop/index.en.html\">read our introduction to GNOME and the Tails desktop.</a></p>\n<table class=\"img\"><caption>The desktop and Applications menu</caption>\n<tr><td><img alt=\"Tails 2.0 desktop with applications menu unfolded\" class=\"img\" height=\"384\" src=\"https://tails.boum.org/inc/release_notes/2.0/applications_menu.png\" width=\"512\"/></td>\n</tr></table><table class=\"img\"><caption>The activities overview</caption>\n<tr><td><img alt=\"Tails 2.0 activities overview\" class=\"img\" height=\"384\" src=\"https://tails.boum.org/inc/release_notes/2.0/activities_overview.png\" width=\"512\"/></td>\n</tr></table></li>\n</ul><h2>Upgrades and changes</h2>\n<ul><li readability=\"2\">\n<p>Debian 8 upgrades most included software, for example:</p>\n<ul><li>Many core GNOME utilities from 3.4 to 3.14: Files, Disks, Videos, etc.</li>\n<li>LibreOffice from 3.5 to 4.3</li>\n<li>PiTiVi from 0.15 to 0.93</li>\n<li>Git from 1.7.10 to 2.1.4</li>\n<li>Poedit from 1.5.4 to 1.6.10</li>\n<li>Liferea from 1.8.6 to 1.10</li>\n</ul></li>\n<li readability=\"1\">\n<p>Update Tor Browser to 5.5 (based on Firefox 38.6.0 ESR):</p>\n<ul><li>Add Japanese support.</li>\n</ul></li>\n<li readability=\"2\">\n<p>Remove the Windows camouflage which is currently broken in GNOME Shell. We started working on <a href=\"https://labs.riseup.net/code/issues/10830\">adding it back</a> but <a href=\"https://tails.boum.org/news/windows_camouflage_jessie/index.en.html\">your help is needed</a>!</p>\n</li>\n<li readability=\"1\">\n<p>Change to <code>systemd</code> as init system and use it to:</p>\n<ul><li>Sandbox many services using Linux namespaces and make them harder to exploit.</li>\n<li>Make the launching of Tor and the memory wipe on shutdown more robust.</li>\n<li>Sanitize our code base by replacing many custom scripts.</li>\n</ul></li>\n<li readability=\"1\">\n<p>Update most firmware packages which might improve hardware compatibility.</p>\n</li>\n<li readability=\"1\">\n<p>Notify the user if Tails is running from a non-free virtualization software.</p>\n</li>\n<li readability=\"3\">\n<p>Remove Claws Mail, replaced by <a href=\"https://tails.boum.org/doc/anonymous_internet/icedove/index.en.html\">Icedove</a>, a rebranded version of Mozilla Thunderbird.</p>\n</li>\n</ul><h2>Fixed problems</h2>\n<ul><li readability=\"1\">\n<p>HiDPI displays are better supported. (<a href=\"https://labs.riseup.net/code/issues/8659\">#8659</a>)</p>\n</li>\n<li readability=\"3\">\n<p>Remove the option to open a download with an external application in Tor Browser as this is usually impossible due to the AppArmor confinement. (<a href=\"https://labs.riseup.net/code/issues/9285\">#9285</a>)</p>\n</li>\n<li readability=\"1\">\n<p>Close Vidalia before restarting Tor.</p>\n</li>\n<li readability=\"2\">\n<p>Allow Videos to access the DVD drive. (<a href=\"https://labs.riseup.net/code/issues/10455\">#10455</a>, <a href=\"https://labs.riseup.net/code/issues/9990\">#9990</a>)</p>\n</li>\n<li readability=\"1\">\n<p>Allow configuring printers without administration password. (<a href=\"https://labs.riseup.net/code/issues/8443\">#8443</a>)</p>\n</li>\n</ul>\n<p>See the current list of <a href=\"https://tails.boum.org/support/known_issues/index.en.html\">known issues</a>.</p>\n<p>Go to the <a href=\"https://tails.boum.org/download/index.en.html\">download</a> or <a href=\"https://tails.boum.org/doc/first_steps/upgrade/index.en.html\">upgrade</a> page.</p>\n<p>If your Tails does not boot after an automatic upgrade, please <a href=\"https://tails.boum.org/doc/first_steps/upgrade/index.en.html#manual\">upgrade your Tails manually</a>.</p>\n<p>The next Tails release is <a href=\"https://tails.boum.org/contribute/calendar/\">scheduled</a> for March 08.</p>\n<p>Have a look at our <a href=\"https://labs.riseup.net/code/projects/tails/roadmap\">roadmap</a> to see where we are heading to.</p>\n<p>We need your help and there are many ways to <a href=\"https://tails.boum.org/contribute/index.en.html\">contribute to Tails</a> (<a href=\"https://tails.boum.org/contribute/how/donate/index.en.html\">donating</a> is only one of them). Come <a href=\"https://tails.boum.org/contribute/talk/\">talk to us</a>!</p>\n</div><div id=\"footer\" class=\"pagefooter\" role=\"contentinfo\" readability=\"15\">\n<p>Tags: <a href=\"https://tails.boum.org/tags/announce/\" rel=\"tag\">announce</a></p>\n<p>Pages linking to this one: <a href=\"https://tails.boum.org/inc/stable_i386_release_notes/index.en.html\">inc/stable i386 release notes</a> <a href=\"https://tails.boum.org/security/Numerous_security_holes_in_2.0/index.en.html\">security/Numerous security holes in 2.0</a></p>\n<p>Last edited Sat 13 Feb 2016 02:23:58 PM CET </p>\n</div>",
+        "mimetype": "text/html",
+        "language": "en",
+        "reading_time": 1,
+        "domain_name": "tails.boum.org",
+        "tags": []
+    }
+]