aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeremy Benoist <j0k3r@users.noreply.github.com>2016-09-26 14:47:02 +0200
committerGitHub <noreply@github.com>2016-09-26 14:47:02 +0200
commitd6de23a100221ae1afaa92a58af17a17d0c6614e (patch)
treebd105198c75ea6b8e5d37a80a9f0135942a1c5eb
parent7e98ad962680fac17b3b90ae34b9c6e5afe7636f (diff)
parentfefef9d41b4d1bd9efbd49011159bae70bf67528 (diff)
downloadwallabag-d6de23a100221ae1afaa92a58af17a17d0c6614e.tar.gz
wallabag-d6de23a100221ae1afaa92a58af17a17d0c6614e.tar.zst
wallabag-d6de23a100221ae1afaa92a58af17a17d0c6614e.zip
Merge pull request #2192 from wallabag/import-browser-bookmarks
Import Firefox & Chrome bookmarks into wallabag
-rw-r--r--app/config/config.yml26
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml10
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml8
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml8
-rw-r--r--src/Wallabag/ImportBundle/Command/ImportCommand.php20
-rw-r--r--src/Wallabag/ImportBundle/Controller/BrowserController.php90
-rw-r--r--src/Wallabag/ImportBundle/Controller/ChromeController.php41
-rw-r--r--src/Wallabag/ImportBundle/Controller/FirefoxController.php41
-rw-r--r--src/Wallabag/ImportBundle/Import/BrowserImport.php205
-rw-r--r--src/Wallabag/ImportBundle/Import/ChromeImport.php53
-rw-r--r--src/Wallabag/ImportBundle/Import/FirefoxImport.php53
-rw-r--r--src/Wallabag/ImportBundle/Resources/config/rabbit.yml14
-rw-r--r--src/Wallabag/ImportBundle/Resources/config/redis.yml40
-rw-r--r--src/Wallabag/ImportBundle/Resources/config/services.yml19
-rw-r--r--src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig43
-rw-r--r--src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig43
-rw-r--r--src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig2
-rw-r--r--tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php2
-rw-r--r--tests/Wallabag/ImportBundle/Command/ImportCommandTest.php1
-rw-r--r--tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php152
-rw-r--r--tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php165
-rw-r--r--tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php2
-rw-r--r--tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php1
-rw-r--r--tests/Wallabag/ImportBundle/Import/ChromeImportTest.php233
-rw-r--r--tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php233
-rw-r--r--tests/Wallabag/ImportBundle/fixtures/chrome-bookmarks36
-rw-r--r--tests/Wallabag/ImportBundle/fixtures/firefox-bookmarks.json63
35 files changed, 1657 insertions, 11 deletions
diff --git a/app/config/config.yml b/app/config/config.yml
index 7ee0cfb8..a4584a1b 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -246,6 +246,16 @@ old_sound_rabbit_mq:
246 exchange_options: 246 exchange_options:
247 name: 'wallabag.import.wallabag_v2' 247 name: 'wallabag.import.wallabag_v2'
248 type: topic 248 type: topic
249 import_firefox:
250 connection: default
251 exchange_options:
252 name: 'wallabag.import.firefox'
253 type: topic
254 import_chrome:
255 connection: default
256 exchange_options:
257 name: 'wallabag.import.chrome'
258 type: topic
249 consumers: 259 consumers:
250 import_pocket: 260 import_pocket:
251 connection: default 261 connection: default
@@ -279,3 +289,19 @@ old_sound_rabbit_mq:
279 queue_options: 289 queue_options:
280 name: 'wallabag.import.wallabag_v2' 290 name: 'wallabag.import.wallabag_v2'
281 callback: wallabag_import.consumer.amqp.wallabag_v2 291 callback: wallabag_import.consumer.amqp.wallabag_v2
292 import_firefox:
293 connection: default
294 exchange_options:
295 name: 'wallabag.import.firefox'
296 type: topic
297 queue_options:
298 name: 'wallabag.import.firefox'
299 callback: wallabag_import.consumer.amqp.firefox
300 import_chrome:
301 connection: default
302 exchange_options:
303 name: 'wallabag.import.chrome'
304 type: topic
305 queue_options:
306 name: 'wallabag.import.chrome'
307 callback: wallabag_import.consumer.amqp.chrome
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index c6fcb355..9eeb210b 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 #chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 # page_title: 'Developer' 362 # page_title: 'Developer'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index c0e82b59..a9ec2519 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 page_title: 'Entwickler' 362 page_title: 'Entwickler'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 6f262209..c0d8656d 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -349,6 +349,14 @@ import:
349 how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 firefox:
353 page_title: 'Import > Firefox'
354 description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 chrome:
357 page_title: 'Import > Chrome'
358 description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 page_title: 'Developer' 362 page_title: 'Developer'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 7b981069..1d6993db 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 page_title: 'Promotor' 362 page_title: 'Promotor'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 99fcc378..68272f99 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 # page_title: 'Developer' 362 # page_title: 'Developer'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index dd82e7f5..b28068b6 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -349,6 +349,14 @@ import:
349 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l'importer." 349 how_to: "Choisissez le fichier de votre export Readability et cliquez sur le bouton ci-dessous pour l'importer."
350 worker: 350 worker:
351 enabled: "Les imports sont asynchrones. Une fois l'import commencé un worker externe traitera les messages un par un. Le service activé est :" 351 enabled: "Les imports sont asynchrones. Une fois l'import commencé un worker externe traitera les messages un par un. Le service activé est :"
352 firefox:
353 page_title: 'Import > Firefox'
354 description: "Cet outil va vous permettre d'importer tous vos marques-pages de Firefox. <p>Pour Firefox, ouvrez le panneau des marques-pages (Ctrl+Maj+O), puis dans « Importation et sauvegarde », choisissez « Sauvegarde... ». Vous allez récupérer un fichier .json. </p>"
355 how_to: "Choisissez le fichier de sauvegarde de vos marques-page et cliquez sur le bouton pour l'importer. Soyez avertis que le processus peut prendre un temps assez long car tous les articles doivent être récupérés en ligne."
356 chrome:
357 page_title: 'Import > Chrome'
358 description: "Cet outil va vous permettre d'importer tous vos marques-pages de Google Chrome/Chromium. Pour Google Chrome, la situation du fichier dépend de votre système d'exploitation : <ul><li>Sur GNU/Linux, allez dans le répertoire <code>~/.config/google-chrome/Default/</code></li><li>Sous Windows, il devrait se trouver à <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>Sur OS X, il devrait se trouver dans le fichier <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Une fois que vous y êtes, copiez le fichier Bookmarks à un endroit où vous le retrouverez.<em><br>Notez que si vous utilisez Chromium à la place de Chrome, vous devez corriger les chemins en conséquence.</em></p>"
359 how_to: "Choisissez le fichier de sauvegarde de vos marques-page et cliquez sur le bouton pour l'importer. Soyez avertis que le processus peut prendre un temps assez long car tous les articles doivent être récupérés en ligne."
352 360
353developer: 361developer:
354 page_title: 'Développeur' 362 page_title: 'Développeur'
@@ -432,7 +440,7 @@ flashes:
432 notice: 440 notice:
433 failed: "L'import a échoué, veuillez ré-essayer" 441 failed: "L'import a échoué, veuillez ré-essayer"
434 failed_on_file: "Erreur lors du traitement de l'import. Vérifier votre fichier." 442 failed_on_file: "Erreur lors du traitement de l'import. Vérifier votre fichier."
435 summary: "Rapport d'import: %imported% importés, %skipped% déjà présent." 443 summary: "Rapport d'import: %imported% importés, %skipped% déjà présents."
436 summary_with_queue: "Rapport d'import: %queued% en cours de traitement." 444 summary_with_queue: "Rapport d'import: %queued% en cours de traitement."
437 error: 445 error:
438 redis_enabled_not_installed: Redis est activé pour les imports asynchrones mais <u>impossible de s'y connecter</u>. Vérifier la configuration de Redis. 446 redis_enabled_not_installed: Redis est activé pour les imports asynchrones mais <u>impossible de s'y connecter</u>. Vérifier la configuration de Redis.
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index d3ce30c9..bd98c8c0 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -348,6 +348,14 @@ import:
348 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 348 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
349 worker: 349 worker:
350 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 350 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
351 # firefox:
352 # page_title: 'Import > Firefox'
353 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
354 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
355 # chrome:
356 # page_title: 'Import > Chrome'
357 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
358 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
351 359
352developer: 360developer:
353 page_title: 'Sviluppatori' 361 page_title: 'Sviluppatori'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index d040daea..6da9ff18 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -349,6 +349,14 @@ import:
349 how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar." 349 how_to: "Mercés de seleccionar vòstre Readability fichièr e de clicar sul boton dejós per lo telecargar e l'importar."
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 page_title: 'Desvolopador' 362 page_title: 'Desvolopador'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index a51ed1f2..daa34bc0 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -349,6 +349,14 @@ import:
349 how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.' 349 how_to: 'Wybierz swój plik eksportu z Readability i kliknij poniższy przycisk, aby go załadować.'
350 worker: 350 worker:
351 enabled: "Import jest wykonywany asynchronicznie. Od momentu rozpoczęcia importu, zewnętrzna usługa może zajmować się na raz tylko jednym zadaniem. Bieżącą usługą jest:" 351 enabled: "Import jest wykonywany asynchronicznie. Od momentu rozpoczęcia importu, zewnętrzna usługa może zajmować się na raz tylko jednym zadaniem. Bieżącą usługą jest:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 page_title: 'Deweloper' 362 page_title: 'Deweloper'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index de21f0b3..067f7878 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 # page_title: 'Developer' 362 # page_title: 'Developer'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index d4b7a7a2..62c69510 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -349,6 +349,14 @@ import:
349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.' 349 # how_to: 'Please select your Readability export and click on the below button to upload and import it.'
350 worker: 350 worker:
351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:" 351 # enabled: "Import is made asynchronously. Once the import task is started, an external worker will handle jobs one at a time. The current service is:"
352 # firefox:
353 # page_title: 'Import > Firefox'
354 # description: "This importer will import all your Firefox bookmarks. <p>For Firefox, just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
355 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
356 # chrome:
357 # page_title: 'Import > Chrome'
358 # description: "This importer will import all your Chrome bookmarks. The location of the file depends on your operating system : <ul><li>On Linux, go into the <code>~/.config/chromium/Default/</code> directory</li><li>On Windows, it should be at <code>%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default</code></li><li>On OS X, it should be at <code>~/Library/Application Support/Google/Chrome/Default/Bookmarks</code></li></ul>Once you got there, copy the Bookmarks file someplace you'll find.<em><br>Note that if you have Chromium instead of Chrome, you'll have to correct paths accordingly.</em></p>"
359 # how_to: "Please choose the bookmark backup file and click on the button below to import it. Note that the process may take a long time since all articles have to be fetched."
352 360
353developer: 361developer:
354 # page_title: 'Developer' 362 # page_title: 'Developer'
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php
index 20ecc6e1..1df38295 100644
--- a/src/Wallabag/ImportBundle/Command/ImportCommand.php
+++ b/src/Wallabag/ImportBundle/Command/ImportCommand.php
@@ -17,7 +17,7 @@ class ImportCommand extends ContainerAwareCommand
17 ->setDescription('Import entries from a JSON export from a wallabag v1 instance') 17 ->setDescription('Import entries from a JSON export from a wallabag v1 instance')
18 ->addArgument('userId', InputArgument::REQUIRED, 'User ID to populate') 18 ->addArgument('userId', InputArgument::REQUIRED, 'User ID to populate')
19 ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file') 19 ->addArgument('filepath', InputArgument::REQUIRED, 'Path to the JSON file')
20 ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: v1 or v2', 'v1') 20 ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: wallabag v1, v2, firefox or chrome', 'v1')
21 ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false) 21 ->addOption('markAsRead', null, InputArgument::OPTIONAL, 'Mark all entries as read', false)
22 ; 22 ;
23 } 23 }
@@ -40,10 +40,20 @@ class ImportCommand extends ContainerAwareCommand
40 throw new Exception(sprintf('User with id "%s" not found', $input->getArgument('userId'))); 40 throw new Exception(sprintf('User with id "%s" not found', $input->getArgument('userId')));
41 } 41 }
42 42
43 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); 43 switch ($input->getOption('importer')) {
44 44 case 'v2':
45 if ('v2' === $input->getOption('importer')) { 45 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v2.import');
46 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v2.import'); 46 break;
47 case 'firefox':
48 $wallabag = $this->getContainer()->get('wallabag_import.firefox.import');
49 break;
50 case 'chrome':
51 $wallabag = $this->getContainer()->get('wallabag_import.chrome.import');
52 break;
53 case 'v1':
54 default:
55 $wallabag = $this->getContainer()->get('wallabag_import.wallabag_v1.import');
56 break;
47 } 57 }
48 58
49 $wallabag->setMarkAsRead($input->getOption('markAsRead')); 59 $wallabag->setMarkAsRead($input->getOption('markAsRead'));
diff --git a/src/Wallabag/ImportBundle/Controller/BrowserController.php b/src/Wallabag/ImportBundle/Controller/BrowserController.php
new file mode 100644
index 00000000..144a4880
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Controller/BrowserController.php
@@ -0,0 +1,90 @@
1<?php
2
3namespace Wallabag\ImportBundle\Controller;
4
5use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
7use Symfony\Component\HttpFoundation\Request;
8use Symfony\Component\HttpFoundation\Response;
9use Wallabag\ImportBundle\Form\Type\UploadImportType;
10
11abstract class BrowserController extends Controller
12{
13 /**
14 * Return the service to handle the import.
15 *
16 * @return \Wallabag\ImportBundle\Import\ImportInterface
17 */
18 abstract protected function getImportService();
19
20 /**
21 * Return the template used for the form.
22 *
23 * @return string
24 */
25 abstract protected function getImportTemplate();
26
27 /**
28 * @Route("/browser", name="import_browser")
29 *
30 * @param Request $request
31 *
32 * @return Response
33 */
34 public function indexAction(Request $request)
35 {
36 $form = $this->createForm(UploadImportType::class);
37 $form->handleRequest($request);
38
39 $wallabag = $this->getImportService();
40 $wallabag->setUser($this->getUser());
41
42 if ($form->isValid()) {
43 $file = $form->get('file')->getData();
44 $markAsRead = $form->get('mark_as_read')->getData();
45 $name = $this->getUser()->getId().'.json';
46
47 if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) {
48 $res = $wallabag
49 ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name)
50 ->setMarkAsRead($markAsRead)
51 ->import();
52
53 $message = 'flashes.import.notice.failed';
54
55 if (true === $res) {
56 $summary = $wallabag->getSummary();
57 $message = $this->get('translator')->trans('flashes.import.notice.summary', [
58 '%imported%' => $summary['imported'],
59 '%skipped%' => $summary['skipped'],
60 ]);
61
62 if (0 < $summary['queued']) {
63 $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [
64 '%queued%' => $summary['queued'],
65 ]);
66 }
67
68 unlink($this->getParameter('wallabag_import.resource_dir').'/'.$name);
69 }
70
71 $this->get('session')->getFlashBag()->add(
72 'notice',
73 $message
74 );
75
76 return $this->redirect($this->generateUrl('homepage'));
77 } else {
78 $this->get('session')->getFlashBag()->add(
79 'notice',
80 'flashes.import.notice.failed_on_file'
81 );
82 }
83 }
84
85 return $this->render($this->getImportTemplate(), [
86 'form' => $form->createView(),
87 'import' => $wallabag,
88 ]);
89 }
90}
diff --git a/src/Wallabag/ImportBundle/Controller/ChromeController.php b/src/Wallabag/ImportBundle/Controller/ChromeController.php
new file mode 100644
index 00000000..454f3347
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Controller/ChromeController.php
@@ -0,0 +1,41 @@
1<?php
2
3namespace Wallabag\ImportBundle\Controller;
4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Component\HttpFoundation\Request;
7
8class ChromeController extends BrowserController
9{
10 /**
11 * {@inheritdoc}
12 */
13 protected function getImportService()
14 {
15 $service = $this->get('wallabag_import.chrome.import');
16
17 if ($this->get('craue_config')->get('import_with_rabbitmq')) {
18 $service->setProducer($this->get('old_sound_rabbit_mq.import_chrome_producer'));
19 } elseif ($this->get('craue_config')->get('import_with_redis')) {
20 $service->setProducer($this->get('wallabag_import.producer.redis.chrome'));
21 }
22
23 return $service;
24 }
25
26 /**
27 * {@inheritdoc}
28 */
29 protected function getImportTemplate()
30 {
31 return 'WallabagImportBundle:Chrome:index.html.twig';
32 }
33
34 /**
35 * @Route("/chrome", name="import_chrome")
36 */
37 public function indexAction(Request $request)
38 {
39 return parent::indexAction($request);
40 }
41}
diff --git a/src/Wallabag/ImportBundle/Controller/FirefoxController.php b/src/Wallabag/ImportBundle/Controller/FirefoxController.php
new file mode 100644
index 00000000..c329b9c4
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Controller/FirefoxController.php
@@ -0,0 +1,41 @@
1<?php
2
3namespace Wallabag\ImportBundle\Controller;
4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6use Symfony\Component\HttpFoundation\Request;
7
8class FirefoxController extends BrowserController
9{
10 /**
11 * {@inheritdoc}
12 */
13 protected function getImportService()
14 {
15 $service = $this->get('wallabag_import.firefox.import');
16
17 if ($this->get('craue_config')->get('import_with_rabbitmq')) {
18 $service->setProducer($this->get('old_sound_rabbit_mq.import_firefox_producer'));
19 } elseif ($this->get('craue_config')->get('import_with_redis')) {
20 $service->setProducer($this->get('wallabag_import.producer.redis.firefox'));
21 }
22
23 return $service;
24 }
25
26 /**
27 * {@inheritdoc}
28 */
29 protected function getImportTemplate()
30 {
31 return 'WallabagImportBundle:Firefox:index.html.twig';
32 }
33
34 /**
35 * @Route("/firefox", name="import_firefox")
36 */
37 public function indexAction(Request $request)
38 {
39 return parent::indexAction($request);
40 }
41}
diff --git a/src/Wallabag/ImportBundle/Import/BrowserImport.php b/src/Wallabag/ImportBundle/Import/BrowserImport.php
new file mode 100644
index 00000000..e15443c4
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Import/BrowserImport.php
@@ -0,0 +1,205 @@
1<?php
2
3namespace Wallabag\ImportBundle\Import;
4
5use Wallabag\CoreBundle\Entity\Entry;
6use Wallabag\UserBundle\Entity\User;
7use Wallabag\CoreBundle\Helper\ContentProxy;
8
9abstract class BrowserImport extends AbstractImport
10{
11 protected $filepath;
12
13 /**
14 * {@inheritdoc}
15 */
16 abstract public function getName();
17
18 /**
19 * {@inheritdoc}
20 */
21 abstract public function getUrl();
22
23 /**
24 * {@inheritdoc}
25 */
26 abstract public function getDescription();
27
28 /**
29 * {@inheritdoc}
30 */
31 public function import()
32 {
33 if (!$this->user) {
34 $this->logger->error('Wallabag Browser Import: user is not defined');
35
36 return false;
37 }
38
39 if (!file_exists($this->filepath) || !is_readable($this->filepath)) {
40 $this->logger->error('Wallabag Browser Import: unable to read file', ['filepath' => $this->filepath]);
41
42 return false;
43 }
44
45 $data = json_decode(file_get_contents($this->filepath), true);
46
47 if (empty($data)) {
48 return false;
49 }
50
51 if ($this->producer) {
52 $this->parseEntriesForProducer($data);
53
54 return true;
55 }
56
57 $this->parseEntries($data);
58
59 return true;
60 }
61
62 /**
63 * Set file path to the json file.
64 *
65 * @param string $filepath
66 */
67 public function setFilepath($filepath)
68 {
69 $this->filepath = $filepath;
70
71 return $this;
72 }
73
74 /**
75 * Parse and insert all given entries.
76 *
77 * @param $entries
78 */
79 protected function parseEntries($entries)
80 {
81 $i = 1;
82
83 foreach ($entries as $importedEntry) {
84 if ((array) $importedEntry !== $importedEntry) {
85 continue;
86 }
87
88 $entry = $this->parseEntry($importedEntry);
89
90 if (null === $entry) {
91 continue;
92 }
93
94 // flush every 20 entries
95 if (($i % 20) === 0) {
96 $this->em->flush();
97 }
98 ++$i;
99 }
100
101 $this->em->flush();
102 }
103
104 /**
105 * Parse entries and send them to the queue.
106 * It should just be a simple loop on all item, no call to the database should be done
107 * to speedup queuing.
108 *
109 * Faster parse entries for Producer.
110 * We don't care to make check at this time. They'll be done by the consumer.
111 *
112 * @param array $entries
113 */
114 protected function parseEntriesForProducer(array $entries)
115 {
116 foreach ($entries as $importedEntry) {
117 if ((array) $importedEntry !== $importedEntry) {
118 continue;
119 }
120
121 // set userId for the producer (it won't know which user is connected)
122 $importedEntry['userId'] = $this->user->getId();
123
124 if ($this->markAsRead) {
125 $importedEntry = $this->setEntryAsRead($importedEntry);
126 }
127
128 ++$this->queuedEntries;
129
130 $this->producer->publish(json_encode($importedEntry));
131 }
132 }
133
134 /**
135 * {@inheritdoc}
136 */
137 public function parseEntry(array $importedEntry)
138 {
139 if ((!array_key_exists('guid', $importedEntry) || (!array_key_exists('id', $importedEntry))) && is_array(reset($importedEntry))) {
140 $this->parseEntries($importedEntry);
141
142 return;
143 }
144
145 if (array_key_exists('children', $importedEntry)) {
146 $this->parseEntries($importedEntry['children']);
147
148 return;
149 }
150
151 if (!array_key_exists('uri', $importedEntry) && !array_key_exists('url', $importedEntry)) {
152 return;
153 }
154
155 $url = array_key_exists('uri', $importedEntry) ? $importedEntry['uri'] : $importedEntry['url'];
156
157 $existingEntry = $this->em
158 ->getRepository('WallabagCoreBundle:Entry')
159 ->findByUrlAndUserId($url, $this->user->getId());
160
161 if (false !== $existingEntry) {
162 ++$this->skippedEntries;
163
164 return;
165 }
166
167 $data = $this->prepareEntry($importedEntry);
168
169 $entry = new Entry($this->user);
170 $entry->setUrl($data['url']);
171 $entry->setTitle($data['title']);
172
173 // update entry with content (in case fetching failed, the given entry will be return)
174 $entry = $this->fetchContent($entry, $data['url'], $data);
175
176 if (array_key_exists('tags', $data)) {
177 $this->contentProxy->assignTagsToEntry(
178 $entry,
179 $data['tags']
180 );
181 }
182
183 $entry->setArchived($data['is_archived']);
184
185 if (!empty($data['created_at'])) {
186 $dt = new \DateTime();
187 $entry->setCreatedAt($dt->setTimestamp($data['created_at']));
188 }
189
190 $this->em->persist($entry);
191 ++$this->importedEntries;
192
193 return $entry;
194 }
195
196 /**
197 * {@inheritdoc}
198 */
199 protected function setEntryAsRead(array $importedEntry)
200 {
201 $importedEntry['is_archived'] = 1;
202
203 return $importedEntry;
204 }
205}
diff --git a/src/Wallabag/ImportBundle/Import/ChromeImport.php b/src/Wallabag/ImportBundle/Import/ChromeImport.php
new file mode 100644
index 00000000..d7620bcb
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Import/ChromeImport.php
@@ -0,0 +1,53 @@
1<?php
2
3namespace Wallabag\ImportBundle\Import;
4
5class ChromeImport extends BrowserImport
6{
7 protected $filepath;
8
9 /**
10 * {@inheritdoc}
11 */
12 public function getName()
13 {
14 return 'Chrome';
15 }
16
17 /**
18 * {@inheritdoc}
19 */
20 public function getUrl()
21 {
22 return 'import_chrome';
23 }
24
25 /**
26 * {@inheritdoc}
27 */
28 public function getDescription()
29 {
30 return 'import.chrome.description';
31 }
32
33 /**
34 * {@inheritdoc}
35 */
36 protected function prepareEntry(array $entry = [])
37 {
38 $data = [
39 'title' => $entry['name'],
40 'html' => '',
41 'url' => $entry['url'],
42 'is_archived' => $this->markAsRead,
43 'tags' => '',
44 'created_at' => substr($entry['date_added'], 0, 10),
45 ];
46
47 if (array_key_exists('tags', $entry) && $entry['tags'] != '') {
48 $data['tags'] = $entry['tags'];
49 }
50
51 return $data;
52 }
53}
diff --git a/src/Wallabag/ImportBundle/Import/FirefoxImport.php b/src/Wallabag/ImportBundle/Import/FirefoxImport.php
new file mode 100644
index 00000000..e010f5a4
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Import/FirefoxImport.php
@@ -0,0 +1,53 @@
1<?php
2
3namespace Wallabag\ImportBundle\Import;
4
5class FirefoxImport extends BrowserImport
6{
7 protected $filepath;
8
9 /**
10 * {@inheritdoc}
11 */
12 public function getName()
13 {
14 return 'Firefox';
15 }
16
17 /**
18 * {@inheritdoc}
19 */
20 public function getUrl()
21 {
22 return 'import_firefox';
23 }
24
25 /**
26 * {@inheritdoc}
27 */
28 public function getDescription()
29 {
30 return 'import.firefox.description';
31 }
32
33 /**
34 * {@inheritdoc}
35 */
36 protected function prepareEntry(array $entry = [])
37 {
38 $data = [
39 'title' => $entry['title'],
40 'html' => '',
41 'url' => $entry['uri'],
42 'is_archived' => $this->markAsRead,
43 'tags' => '',
44 'created_at' => substr($entry['dateAdded'], 0, 10),
45 ];
46
47 if (array_key_exists('tags', $entry) && $entry['tags'] != '') {
48 $data['tags'] = $entry['tags'];
49 }
50
51 return $data;
52 }
53}
diff --git a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml
index aa049749..6ada6302 100644
--- a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml
+++ b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml
@@ -28,3 +28,17 @@ services:
28 - "@wallabag_user.user_repository" 28 - "@wallabag_user.user_repository"
29 - "@wallabag_import.wallabag_v2.import" 29 - "@wallabag_import.wallabag_v2.import"
30 - "@logger" 30 - "@logger"
31 wallabag_import.consumer.amqp.firefox:
32 class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
33 arguments:
34 - "@doctrine.orm.entity_manager"
35 - "@wallabag_user.user_repository"
36 - "@wallabag_import.firefox.import"
37 - "@logger"
38 wallabag_import.consumer.amqp.chrome:
39 class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
40 arguments:
41 - "@doctrine.orm.entity_manager"
42 - "@wallabag_user.user_repository"
43 - "@wallabag_import.chrome.import"
44 - "@logger"
diff --git a/src/Wallabag/ImportBundle/Resources/config/redis.yml b/src/Wallabag/ImportBundle/Resources/config/redis.yml
index 7d3248e5..c9c2cf26 100644
--- a/src/Wallabag/ImportBundle/Resources/config/redis.yml
+++ b/src/Wallabag/ImportBundle/Resources/config/redis.yml
@@ -79,3 +79,43 @@ services:
79 - "@wallabag_user.user_repository" 79 - "@wallabag_user.user_repository"
80 - "@wallabag_import.wallabag_v2.import" 80 - "@wallabag_import.wallabag_v2.import"
81 - "@logger" 81 - "@logger"
82
83 # firefox
84 wallabag_import.queue.redis.firefox:
85 class: Simpleue\Queue\RedisQueue
86 arguments:
87 - "@wallabag_core.redis.client"
88 - "wallabag.import.firefox"
89
90 wallabag_import.producer.redis.firefox:
91 class: Wallabag\ImportBundle\Redis\Producer
92 arguments:
93 - "@wallabag_import.queue.redis.firefox"
94
95 wallabag_import.consumer.redis.firefox:
96 class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer
97 arguments:
98 - "@doctrine.orm.entity_manager"
99 - "@wallabag_user.user_repository"
100 - "@wallabag_import.firefox.import"
101 - "@logger"
102
103 # chrome
104 wallabag_import.queue.redis.chrome:
105 class: Simpleue\Queue\RedisQueue
106 arguments:
107 - "@wallabag_core.redis.client"
108 - "wallabag.import.chrome"
109
110 wallabag_import.producer.redis.chrome:
111 class: Wallabag\ImportBundle\Redis\Producer
112 arguments:
113 - "@wallabag_import.queue.redis.chrome"
114
115 wallabag_import.consumer.redis.chrome:
116 class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer
117 arguments:
118 - "@doctrine.orm.entity_manager"
119 - "@wallabag_user.user_repository"
120 - "@wallabag_import.chrome.import"
121 - "@logger"
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml
index f03404ae..990f336d 100644
--- a/src/Wallabag/ImportBundle/Resources/config/services.yml
+++ b/src/Wallabag/ImportBundle/Resources/config/services.yml
@@ -56,3 +56,22 @@ services:
56 - [ setLogger, [ "@logger" ]] 56 - [ setLogger, [ "@logger" ]]
57 tags: 57 tags:
58 - { name: wallabag_import.import, alias: readability } 58 - { name: wallabag_import.import, alias: readability }
59
60 wallabag_import.firefox.import:
61 class: Wallabag\ImportBundle\Import\FirefoxImport
62 arguments:
63 - "@doctrine.orm.entity_manager"
64 - "@wallabag_core.content_proxy"
65 calls:
66 - [ setLogger, [ "@logger" ]]
67 tags:
68 - { name: wallabag_import.import, alias: firefox }
69 wallabag_import.chrome.import:
70 class: Wallabag\ImportBundle\Import\ChromeImport
71 arguments:
72 - "@doctrine.orm.entity_manager"
73 - "@wallabag_core.content_proxy"
74 calls:
75 - [ setLogger, [ "@logger" ]]
76 tags:
77 - { name: wallabag_import.import, alias: chrome }
diff --git a/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig
new file mode 100644
index 00000000..ead828c6
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Resources/views/Chrome/index.html.twig
@@ -0,0 +1,43 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %}
2
3{% block title %}{{ 'import.chrome.page_title'|trans }}{% endblock %}
4
5{% block content %}
6<div class="row">
7 <div class="col s12">
8 <div class="card-panel settings">
9 <div class="row">
10 <blockquote>{{ import.description|trans|raw }}</blockquote>
11 <p>{{ 'import.chrome.how_to'|trans }}</p>
12
13 <div class="col s12">
14 {{ form_start(form, {'method': 'POST'}) }}
15 {{ form_errors(form) }}
16 <div class="row">
17 <div class="file-field input-field col s12">
18 {{ form_errors(form.file) }}
19 <div class="btn">
20 <span>{{ form.file.vars.label|trans }}</span>
21 {{ form_widget(form.file) }}
22 </div>
23 <div class="file-path-wrapper">
24 <input class="file-path validate" type="text">
25 </div>
26 </div>
27 <div class="input-field col s6 with-checkbox">
28 <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6>
29 {{ form_widget(form.mark_as_read) }}
30 {{ form_label(form.mark_as_read) }}
31 </div>
32 </div>
33
34 {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }}
35
36 {{ form_rest(form) }}
37 </form>
38 </div>
39 </div>
40 </div>
41 </div>
42</div>
43{% endblock %}
diff --git a/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig
new file mode 100644
index 00000000..f975da3f
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Resources/views/Firefox/index.html.twig
@@ -0,0 +1,43 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %}
2
3{% block title %}{{ 'import.firefox.page_title'|trans }}{% endblock %}
4
5{% block content %}
6<div class="row">
7 <div class="col s12">
8 <div class="card-panel settings">
9 <div class="row">
10 <blockquote>{{ import.description|trans|raw }}</blockquote>
11 <p>{{ 'import.firefox.how_to'|trans }}</p>
12
13 <div class="col s12">
14 {{ form_start(form, {'method': 'POST'}) }}
15 {{ form_errors(form) }}
16 <div class="row">
17 <div class="file-field input-field col s12">
18 {{ form_errors(form.file) }}
19 <div class="btn">
20 <span>{{ form.file.vars.label|trans }}</span>
21 {{ form_widget(form.file) }}
22 </div>
23 <div class="file-path-wrapper">
24 <input class="file-path validate" type="text">
25 </div>
26 </div>
27 <div class="input-field col s6 with-checkbox">
28 <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6>
29 {{ form_widget(form.mark_as_read) }}
30 {{ form_label(form.mark_as_read) }}
31 </div>
32 </div>
33
34 {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }}
35
36 {{ form_rest(form) }}
37 </form>
38 </div>
39 </div>
40 </div>
41 </div>
42</div>
43{% endblock %}
diff --git a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
index aebbfa20..6ea5e0f4 100644
--- a/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
+++ b/src/Wallabag/ImportBundle/Resources/views/Import/index.html.twig
@@ -11,7 +11,7 @@
11 {% for import in imports %} 11 {% for import in imports %}
12 <li> 12 <li>
13 <h5>{{ import.name }}</h5> 13 <h5>{{ import.name }}</h5>
14 <blockquote>{{ import.description|trans }}</blockquote> 14 <blockquote>{{ import.description|trans|raw }}</blockquote>
15 <p><a class="waves-effect waves-light btn" href="{{ path(import.url) }}">{{ 'import.action.import_contents'|trans }}</a></p> 15 <p><a class="waves-effect waves-light btn" href="{{ path(import.url) }}">{{ 'import.action.import_contents'|trans }}</a></p>
16 </li> 16 </li>
17 {% endfor %} 17 {% endfor %}
diff --git a/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php
index ee5b2ab7..101c20eb 100644
--- a/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php
+++ b/tests/Wallabag/ApiBundle/Controller/WallabagRestControllerTest.php
@@ -80,7 +80,7 @@ class WallabagRestControllerTest extends WallabagApiTestCase
80 80
81 public function testGetStarredEntries() 81 public function testGetStarredEntries()
82 { 82 {
83 $this->client->request('GET', '/api/entries', ['star' => 1, 'sort' => 'updated']); 83 $this->client->request('GET', '/api/entries', ['starred' => 1, 'sort' => 'updated']);
84 84
85 $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); 85 $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
86 86
diff --git a/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php b/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php
index eb7fce79..7be1eb18 100644
--- a/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php
+++ b/tests/Wallabag/ImportBundle/Command/ImportCommandTest.php
@@ -6,7 +6,6 @@ use Symfony\Bundle\FrameworkBundle\Console\Application;
6use Symfony\Component\Console\Tester\CommandTester; 6use Symfony\Component\Console\Tester\CommandTester;
7use Wallabag\ImportBundle\Command\ImportCommand; 7use Wallabag\ImportBundle\Command\ImportCommand;
8use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; 8use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
9use M6Web\Component\RedisMock\RedisMockFactory;
10 9
11class ImportCommandTest extends WallabagCoreTestCase 10class ImportCommandTest extends WallabagCoreTestCase
12{ 11{
diff --git a/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php
new file mode 100644
index 00000000..23c80bec
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/Controller/ChromeControllerTest.php
@@ -0,0 +1,152 @@
1<?php
2
3namespace Tests\Wallabag\ImportBundle\Controller;
4
5use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
6use Symfony\Component\HttpFoundation\File\UploadedFile;
7
8class ChromeControllerTest extends WallabagCoreTestCase
9{
10 public function testImportChrome()
11 {
12 $this->logInAs('admin');
13 $client = $this->getClient();
14
15 $crawler = $client->request('GET', '/import/chrome');
16
17 $this->assertEquals(200, $client->getResponse()->getStatusCode());
18 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
19 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
20 }
21
22 public function testImportChromeWithRabbitEnabled()
23 {
24 $this->logInAs('admin');
25 $client = $this->getClient();
26
27 $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1);
28
29 $crawler = $client->request('GET', '/import/chrome');
30
31 $this->assertEquals(200, $client->getResponse()->getStatusCode());
32 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
33 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
34
35 $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0);
36 }
37
38 public function testImportChromeBadFile()
39 {
40 $this->logInAs('admin');
41 $client = $this->getClient();
42
43 $crawler = $client->request('GET', '/import/chrome');
44 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
45
46 $data = [
47 'upload_import_file[file]' => '',
48 ];
49
50 $client->submit($form, $data);
51
52 $this->assertEquals(200, $client->getResponse()->getStatusCode());
53 }
54
55 public function testImportChromeWithRedisEnabled()
56 {
57 $this->logInAs('admin');
58 $client = $this->getClient();
59 $client->getContainer()->get('craue_config')->set('import_with_redis', 1);
60
61 $crawler = $client->request('GET', '/import/chrome');
62
63 $this->assertEquals(200, $client->getResponse()->getStatusCode());
64 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
65 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
66
67 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
68
69 $file = new UploadedFile(__DIR__.'/../fixtures/chrome-bookmarks', 'Bookmarks');
70
71 $data = [
72 'upload_import_file[file]' => $file,
73 ];
74
75 $client->submit($form, $data);
76
77 $this->assertEquals(302, $client->getResponse()->getStatusCode());
78
79 $crawler = $client->followRedirect();
80
81 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
82 $this->assertContains('flashes.import.notice.summary', $body[0]);
83
84 $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.chrome'));
85
86 $client->getContainer()->get('craue_config')->set('import_with_redis', 0);
87 }
88
89 public function testImportWallabagWithChromeFile()
90 {
91 $this->logInAs('admin');
92 $client = $this->getClient();
93
94 $crawler = $client->request('GET', '/import/chrome');
95 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
96
97 $file = new UploadedFile(__DIR__.'/../fixtures/chrome-bookmarks', 'Bookmarks');
98
99 $data = [
100 'upload_import_file[file]' => $file,
101 ];
102
103 $client->submit($form, $data);
104
105 $this->assertEquals(302, $client->getResponse()->getStatusCode());
106
107 $crawler = $client->followRedirect();
108
109 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
110 $this->assertContains('flashes.import.notice.summary', $body[0]);
111
112 $content = $client->getContainer()
113 ->get('doctrine.orm.entity_manager')
114 ->getRepository('WallabagCoreBundle:Entry')
115 ->findByUrlAndUserId(
116 'http://www.usinenouvelle.com/article/la-multiplication-des-chefs-de-projet-est-une-catastrophe-manageriale-majeure-affirme-le-sociologue-francois-dupuy.N307730',
117 $this->getLoggedInUserId()
118 );
119
120 $this->assertNotEmpty($content->getPreviewPicture());
121 $this->assertNotEmpty($content->getLanguage());
122 $this->assertEquals(0, count($content->getTags()));
123
124 $createdAt = $content->getCreatedAt();
125 $this->assertEquals('2011', $createdAt->format('Y'));
126 $this->assertEquals('07', $createdAt->format('m'));
127 }
128
129 public function testImportWallabagWithEmptyFile()
130 {
131 $this->logInAs('admin');
132 $client = $this->getClient();
133
134 $crawler = $client->request('GET', '/import/chrome');
135 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
136
137 $file = new UploadedFile(__DIR__.'/../fixtures/test.txt', 'test.txt');
138
139 $data = [
140 'upload_import_file[file]' => $file,
141 ];
142
143 $client->submit($form, $data);
144
145 $this->assertEquals(302, $client->getResponse()->getStatusCode());
146
147 $crawler = $client->followRedirect();
148
149 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
150 $this->assertContains('flashes.import.notice.failed', $body[0]);
151 }
152}
diff --git a/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php b/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php
new file mode 100644
index 00000000..98f13d72
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/Controller/FirefoxControllerTest.php
@@ -0,0 +1,165 @@
1<?php
2
3namespace Tests\Wallabag\ImportBundle\Controller;
4
5use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
6use Symfony\Component\HttpFoundation\File\UploadedFile;
7
8class FirefoxControllerTest extends WallabagCoreTestCase
9{
10 public function testImportFirefox()
11 {
12 $this->logInAs('admin');
13 $client = $this->getClient();
14
15 $crawler = $client->request('GET', '/import/firefox');
16
17 $this->assertEquals(200, $client->getResponse()->getStatusCode());
18 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
19 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
20 }
21
22 public function testImportFirefoxWithRabbitEnabled()
23 {
24 $this->logInAs('admin');
25 $client = $this->getClient();
26
27 $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 1);
28
29 $crawler = $client->request('GET', '/import/firefox');
30
31 $this->assertEquals(200, $client->getResponse()->getStatusCode());
32 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
33 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
34
35 $client->getContainer()->get('craue_config')->set('import_with_rabbitmq', 0);
36 }
37
38 public function testImportFirefoxBadFile()
39 {
40 $this->logInAs('admin');
41 $client = $this->getClient();
42
43 $crawler = $client->request('GET', '/import/firefox');
44 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
45
46 $data = [
47 'upload_import_file[file]' => '',
48 ];
49
50 $client->submit($form, $data);
51
52 $this->assertEquals(200, $client->getResponse()->getStatusCode());
53 }
54
55 public function testImportFirefoxWithRedisEnabled()
56 {
57 $this->logInAs('admin');
58 $client = $this->getClient();
59 $client->getContainer()->get('craue_config')->set('import_with_redis', 1);
60
61 $crawler = $client->request('GET', '/import/firefox');
62
63 $this->assertEquals(200, $client->getResponse()->getStatusCode());
64 $this->assertEquals(1, $crawler->filter('form[name=upload_import_file] > button[type=submit]')->count());
65 $this->assertEquals(1, $crawler->filter('input[type=file]')->count());
66
67 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
68
69 $file = new UploadedFile(__DIR__.'/../fixtures/firefox-bookmarks.json', 'Bookmarks');
70
71 $data = [
72 'upload_import_file[file]' => $file,
73 ];
74
75 $client->submit($form, $data);
76
77 $this->assertEquals(302, $client->getResponse()->getStatusCode());
78
79 $crawler = $client->followRedirect();
80
81 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
82 $this->assertContains('flashes.import.notice.summary', $body[0]);
83
84 $this->assertNotEmpty($client->getContainer()->get('wallabag_core.redis.client')->lpop('wallabag.import.firefox'));
85
86 $client->getContainer()->get('craue_config')->set('import_with_redis', 0);
87 }
88
89 public function testImportWallabagWithFirefoxFile()
90 {
91 $this->logInAs('admin');
92 $client = $this->getClient();
93
94 $crawler = $client->request('GET', '/import/firefox');
95 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
96
97 $file = new UploadedFile(__DIR__.'/../fixtures/firefox-bookmarks.json', 'Bookmarks');
98
99 $data = [
100 'upload_import_file[file]' => $file,
101 ];
102
103 $client->submit($form, $data);
104
105 $this->assertEquals(302, $client->getResponse()->getStatusCode());
106
107 $crawler = $client->followRedirect();
108
109 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
110 $this->assertContains('flashes.import.notice.summary', $body[0]);
111
112 $content = $client->getContainer()
113 ->get('doctrine.orm.entity_manager')
114 ->getRepository('WallabagCoreBundle:Entry')
115 ->findByUrlAndUserId(
116 'http://lexpansion.lexpress.fr/high-tech/orange-offre-un-meilleur-reseau-mobile-que-bouygues-et-sfr-free-derriere_1811554.html',
117 $this->getLoggedInUserId()
118 );
119
120 $this->assertNotEmpty($content->getMimetype());
121 $this->assertNotEmpty($content->getPreviewPicture());
122 $this->assertNotEmpty($content->getLanguage());
123 $this->assertEquals(2, count($content->getTags()));
124
125 $content = $client->getContainer()
126 ->get('doctrine.orm.entity_manager')
127 ->getRepository('WallabagCoreBundle:Entry')
128 ->findByUrlAndUserId(
129 'http://stackoverflow.com/questions/15017163/parser-for-exported-bookmarks-html-file-of-google-chrome-and-mozilla-in-java',
130 $this->getLoggedInUserId()
131 );
132
133 $this->assertNotEmpty($content->getMimetype());
134 $this->assertNotEmpty($content->getPreviewPicture());
135 $this->assertEmpty($content->getLanguage());
136
137 $createdAt = $content->getCreatedAt();
138 $this->assertEquals('2013', $createdAt->format('Y'));
139 $this->assertEquals('12', $createdAt->format('m'));
140 }
141
142 public function testImportWallabagWithEmptyFile()
143 {
144 $this->logInAs('admin');
145 $client = $this->getClient();
146
147 $crawler = $client->request('GET', '/import/firefox');
148 $form = $crawler->filter('form[name=upload_import_file] > button[type=submit]')->form();
149
150 $file = new UploadedFile(__DIR__.'/../fixtures/test.txt', 'test.txt');
151
152 $data = [
153 'upload_import_file[file]' => $file,
154 ];
155
156 $client->submit($form, $data);
157
158 $this->assertEquals(302, $client->getResponse()->getStatusCode());
159
160 $crawler = $client->followRedirect();
161
162 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
163 $this->assertContains('flashes.import.notice.failed', $body[0]);
164 }
165}
diff --git a/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php
index d869cdf9..b6783a56 100644
--- a/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php
+++ b/tests/Wallabag/ImportBundle/Controller/ImportControllerTest.php
@@ -24,6 +24,6 @@ class ImportControllerTest extends WallabagCoreTestCase
24 $crawler = $client->request('GET', '/import/'); 24 $crawler = $client->request('GET', '/import/');
25 25
26 $this->assertEquals(200, $client->getResponse()->getStatusCode()); 26 $this->assertEquals(200, $client->getResponse()->getStatusCode());
27 $this->assertEquals(4, $crawler->filter('blockquote')->count()); 27 $this->assertEquals(6, $crawler->filter('blockquote')->count());
28 } 28 }
29} 29}
diff --git a/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php b/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php
index 87ecb9d3..916dd297 100644
--- a/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php
+++ b/tests/Wallabag/ImportBundle/Controller/ReadabilityControllerTest.php
@@ -57,7 +57,6 @@ class ReadabilityControllerTest extends WallabagCoreTestCase
57 $this->checkRedis(); 57 $this->checkRedis();
58 $this->logInAs('admin'); 58 $this->logInAs('admin');
59 $client = $this->getClient(); 59 $client = $this->getClient();
60
61 $client->getContainer()->get('craue_config')->set('import_with_redis', 1); 60 $client->getContainer()->get('craue_config')->set('import_with_redis', 1);
62 61
63 $crawler = $client->request('GET', '/import/readability'); 62 $crawler = $client->request('GET', '/import/readability');
diff --git a/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php b/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php
new file mode 100644
index 00000000..1e52615c
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/Import/ChromeImportTest.php
@@ -0,0 +1,233 @@
1<?php
2
3namespace Tests\Wallabag\ImportBundle\Import;
4
5use Wallabag\ImportBundle\Import\ChromeImport;
6use Wallabag\UserBundle\Entity\User;
7use Wallabag\CoreBundle\Entity\Entry;
8use Wallabag\ImportBundle\Redis\Producer;
9use Monolog\Logger;
10use Monolog\Handler\TestHandler;
11use Simpleue\Queue\RedisQueue;
12use M6Web\Component\RedisMock\RedisMockFactory;
13
14class ChromeImportTest extends \PHPUnit_Framework_TestCase
15{
16 protected $user;
17 protected $em;
18 protected $logHandler;
19 protected $contentProxy;
20
21 private function getChromeImport($unsetUser = false)
22 {
23 $this->user = new User();
24
25 $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
26 ->disableOriginalConstructor()
27 ->getMock();
28
29 $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
30 ->disableOriginalConstructor()
31 ->getMock();
32
33 $wallabag = new ChromeImport($this->em, $this->contentProxy);
34
35 $this->logHandler = new TestHandler();
36 $logger = new Logger('test', [$this->logHandler]);
37 $wallabag->setLogger($logger);
38
39 if (false === $unsetUser) {
40 $wallabag->setUser($this->user);
41 }
42
43 return $wallabag;
44 }
45
46 public function testInit()
47 {
48 $chromeImport = $this->getChromeImport();
49
50 $this->assertEquals('Chrome', $chromeImport->getName());
51 $this->assertNotEmpty($chromeImport->getUrl());
52 $this->assertEquals('import.chrome.description', $chromeImport->getDescription());
53 }
54
55 public function testImport()
56 {
57 $chromeImport = $this->getChromeImport();
58 $chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
59
60 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
61 ->disableOriginalConstructor()
62 ->getMock();
63
64 $entryRepo->expects($this->exactly(1))
65 ->method('findByUrlAndUserId')
66 ->willReturn(false);
67
68 $this->em
69 ->expects($this->any())
70 ->method('getRepository')
71 ->willReturn($entryRepo);
72
73 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
74 ->disableOriginalConstructor()
75 ->getMock();
76
77 $this->contentProxy
78 ->expects($this->exactly(1))
79 ->method('updateEntry')
80 ->willReturn($entry);
81
82 $res = $chromeImport->import();
83
84 $this->assertTrue($res);
85 $this->assertEquals(['skipped' => 0, 'imported' => 1, 'queued' => 0], $chromeImport->getSummary());
86 }
87
88 public function testImportAndMarkAllAsRead()
89 {
90 $chromeImport = $this->getChromeImport();
91 $chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
92
93 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
94 ->disableOriginalConstructor()
95 ->getMock();
96
97 $entryRepo->expects($this->exactly(1))
98 ->method('findByUrlAndUserId')
99 ->will($this->onConsecutiveCalls(false, true));
100
101 $this->em
102 ->expects($this->any())
103 ->method('getRepository')
104 ->willReturn($entryRepo);
105
106 $this->contentProxy
107 ->expects($this->exactly(1))
108 ->method('updateEntry')
109 ->willReturn(new Entry($this->user));
110
111 // check that every entry persisted are archived
112 $this->em
113 ->expects($this->any())
114 ->method('persist')
115 ->with($this->callback(function ($persistedEntry) {
116 return $persistedEntry->isArchived();
117 }));
118
119 $res = $chromeImport->setMarkAsRead(true)->import();
120
121 $this->assertTrue($res);
122
123 $this->assertEquals(['skipped' => 0, 'imported' => 1, 'queued' => 0], $chromeImport->getSummary());
124 }
125
126 public function testImportWithRabbit()
127 {
128 $chromeImport = $this->getChromeImport();
129 $chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
130
131 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
132 ->disableOriginalConstructor()
133 ->getMock();
134
135 $entryRepo->expects($this->never())
136 ->method('findByUrlAndUserId');
137
138 $this->em
139 ->expects($this->never())
140 ->method('getRepository');
141
142 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
143 ->disableOriginalConstructor()
144 ->getMock();
145
146 $this->contentProxy
147 ->expects($this->never())
148 ->method('updateEntry');
149
150 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
151 ->disableOriginalConstructor()
152 ->getMock();
153
154 $producer
155 ->expects($this->exactly(1))
156 ->method('publish');
157
158 $chromeImport->setProducer($producer);
159
160 $res = $chromeImport->setMarkAsRead(true)->import();
161
162 $this->assertTrue($res);
163 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $chromeImport->getSummary());
164 }
165
166 public function testImportWithRedis()
167 {
168 $chromeImport = $this->getChromeImport();
169 $chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
170
171 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
172 ->disableOriginalConstructor()
173 ->getMock();
174
175 $entryRepo->expects($this->never())
176 ->method('findByUrlAndUserId');
177
178 $this->em
179 ->expects($this->never())
180 ->method('getRepository');
181
182 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
183 ->disableOriginalConstructor()
184 ->getMock();
185
186 $this->contentProxy
187 ->expects($this->never())
188 ->method('updateEntry');
189
190 $factory = new RedisMockFactory();
191 $redisMock = $factory->getAdapter('Predis\Client', true);
192
193 $queue = new RedisQueue($redisMock, 'chrome');
194 $producer = new Producer($queue);
195
196 $chromeImport->setProducer($producer);
197
198 $res = $chromeImport->setMarkAsRead(true)->import();
199
200 $this->assertTrue($res);
201 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $chromeImport->getSummary());
202
203 $this->assertNotEmpty($redisMock->lpop('chrome'));
204 }
205
206 public function testImportBadFile()
207 {
208 $chromeImport = $this->getChromeImport();
209 $chromeImport->setFilepath(__DIR__.'/../fixtures/wallabag-v1.jsonx');
210
211 $res = $chromeImport->import();
212
213 $this->assertFalse($res);
214
215 $records = $this->logHandler->getRecords();
216 $this->assertContains('Wallabag Browser Import: unable to read file', $records[0]['message']);
217 $this->assertEquals('ERROR', $records[0]['level_name']);
218 }
219
220 public function testImportUserNotDefined()
221 {
222 $chromeImport = $this->getChromeImport(true);
223 $chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
224
225 $res = $chromeImport->import();
226
227 $this->assertFalse($res);
228
229 $records = $this->logHandler->getRecords();
230 $this->assertContains('Wallabag Browser Import: user is not defined', $records[0]['message']);
231 $this->assertEquals('ERROR', $records[0]['level_name']);
232 }
233}
diff --git a/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php b/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php
new file mode 100644
index 00000000..007dda6a
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/Import/FirefoxImportTest.php
@@ -0,0 +1,233 @@
1<?php
2
3namespace Tests\Wallabag\ImportBundle\Import;
4
5use Wallabag\ImportBundle\Import\FirefoxImport;
6use Wallabag\UserBundle\Entity\User;
7use Wallabag\CoreBundle\Entity\Entry;
8use Wallabag\ImportBundle\Redis\Producer;
9use Monolog\Logger;
10use Monolog\Handler\TestHandler;
11use Simpleue\Queue\RedisQueue;
12use M6Web\Component\RedisMock\RedisMockFactory;
13
14class FirefoxImportTest extends \PHPUnit_Framework_TestCase
15{
16 protected $user;
17 protected $em;
18 protected $logHandler;
19 protected $contentProxy;
20
21 private function getFirefoxImport($unsetUser = false)
22 {
23 $this->user = new User();
24
25 $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
26 ->disableOriginalConstructor()
27 ->getMock();
28
29 $this->contentProxy = $this->getMockBuilder('Wallabag\CoreBundle\Helper\ContentProxy')
30 ->disableOriginalConstructor()
31 ->getMock();
32
33 $wallabag = new FirefoxImport($this->em, $this->contentProxy);
34
35 $this->logHandler = new TestHandler();
36 $logger = new Logger('test', [$this->logHandler]);
37 $wallabag->setLogger($logger);
38
39 if (false === $unsetUser) {
40 $wallabag->setUser($this->user);
41 }
42
43 return $wallabag;
44 }
45
46 public function testInit()
47 {
48 $firefoxImport = $this->getFirefoxImport();
49
50 $this->assertEquals('Firefox', $firefoxImport->getName());
51 $this->assertNotEmpty($firefoxImport->getUrl());
52 $this->assertEquals('import.firefox.description', $firefoxImport->getDescription());
53 }
54
55 public function testImport()
56 {
57 $firefoxImport = $this->getFirefoxImport();
58 $firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
59
60 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
61 ->disableOriginalConstructor()
62 ->getMock();
63
64 $entryRepo->expects($this->exactly(2))
65 ->method('findByUrlAndUserId')
66 ->willReturn(false);
67
68 $this->em
69 ->expects($this->any())
70 ->method('getRepository')
71 ->willReturn($entryRepo);
72
73 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
74 ->disableOriginalConstructor()
75 ->getMock();
76
77 $this->contentProxy
78 ->expects($this->exactly(2))
79 ->method('updateEntry')
80 ->willReturn($entry);
81
82 $res = $firefoxImport->import();
83
84 $this->assertTrue($res);
85 $this->assertEquals(['skipped' => 0, 'imported' => 2, 'queued' => 0], $firefoxImport->getSummary());
86 }
87
88 public function testImportAndMarkAllAsRead()
89 {
90 $firefoxImport = $this->getFirefoxImport();
91 $firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
92
93 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
94 ->disableOriginalConstructor()
95 ->getMock();
96
97 $entryRepo->expects($this->exactly(2))
98 ->method('findByUrlAndUserId')
99 ->will($this->onConsecutiveCalls(false, true));
100
101 $this->em
102 ->expects($this->any())
103 ->method('getRepository')
104 ->willReturn($entryRepo);
105
106 $this->contentProxy
107 ->expects($this->exactly(1))
108 ->method('updateEntry')
109 ->willReturn(new Entry($this->user));
110
111 // check that every entry persisted are archived
112 $this->em
113 ->expects($this->any())
114 ->method('persist')
115 ->with($this->callback(function ($persistedEntry) {
116 return $persistedEntry->isArchived();
117 }));
118
119 $res = $firefoxImport->setMarkAsRead(true)->import();
120
121 $this->assertTrue($res);
122
123 $this->assertEquals(['skipped' => 1, 'imported' => 1, 'queued' => 0], $firefoxImport->getSummary());
124 }
125
126 public function testImportWithRabbit()
127 {
128 $firefoxImport = $this->getFirefoxImport();
129 $firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
130
131 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
132 ->disableOriginalConstructor()
133 ->getMock();
134
135 $entryRepo->expects($this->never())
136 ->method('findByUrlAndUserId');
137
138 $this->em
139 ->expects($this->never())
140 ->method('getRepository');
141
142 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
143 ->disableOriginalConstructor()
144 ->getMock();
145
146 $this->contentProxy
147 ->expects($this->never())
148 ->method('updateEntry');
149
150 $producer = $this->getMockBuilder('OldSound\RabbitMqBundle\RabbitMq\Producer')
151 ->disableOriginalConstructor()
152 ->getMock();
153
154 $producer
155 ->expects($this->exactly(1))
156 ->method('publish');
157
158 $firefoxImport->setProducer($producer);
159
160 $res = $firefoxImport->setMarkAsRead(true)->import();
161
162 $this->assertTrue($res);
163 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $firefoxImport->getSummary());
164 }
165
166 public function testImportWithRedis()
167 {
168 $firefoxImport = $this->getFirefoxImport();
169 $firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
170
171 $entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
172 ->disableOriginalConstructor()
173 ->getMock();
174
175 $entryRepo->expects($this->never())
176 ->method('findByUrlAndUserId');
177
178 $this->em
179 ->expects($this->never())
180 ->method('getRepository');
181
182 $entry = $this->getMockBuilder('Wallabag\CoreBundle\Entity\Entry')
183 ->disableOriginalConstructor()
184 ->getMock();
185
186 $this->contentProxy
187 ->expects($this->never())
188 ->method('updateEntry');
189
190 $factory = new RedisMockFactory();
191 $redisMock = $factory->getAdapter('Predis\Client', true);
192
193 $queue = new RedisQueue($redisMock, 'firefox');
194 $producer = new Producer($queue);
195
196 $firefoxImport->setProducer($producer);
197
198 $res = $firefoxImport->setMarkAsRead(true)->import();
199
200 $this->assertTrue($res);
201 $this->assertEquals(['skipped' => 0, 'imported' => 0, 'queued' => 1], $firefoxImport->getSummary());
202
203 $this->assertNotEmpty($redisMock->lpop('firefox'));
204 }
205
206 public function testImportBadFile()
207 {
208 $firefoxImport = $this->getFirefoxImport();
209 $firefoxImport->setFilepath(__DIR__.'/../fixtures/wallabag-v1.jsonx');
210
211 $res = $firefoxImport->import();
212
213 $this->assertFalse($res);
214
215 $records = $this->logHandler->getRecords();
216 $this->assertContains('Wallabag Browser Import: unable to read file', $records[0]['message']);
217 $this->assertEquals('ERROR', $records[0]['level_name']);
218 }
219
220 public function testImportUserNotDefined()
221 {
222 $firefoxImport = $this->getFirefoxImport(true);
223 $firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
224
225 $res = $firefoxImport->import();
226
227 $this->assertFalse($res);
228
229 $records = $this->logHandler->getRecords();
230 $this->assertContains('Wallabag Browser Import: user is not defined', $records[0]['message']);
231 $this->assertEquals('ERROR', $records[0]['level_name']);
232 }
233}
diff --git a/tests/Wallabag/ImportBundle/fixtures/chrome-bookmarks b/tests/Wallabag/ImportBundle/fixtures/chrome-bookmarks
new file mode 100644
index 00000000..0478eb41
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/fixtures/chrome-bookmarks
@@ -0,0 +1,36 @@
1{
2 "checksum": "f3aa0e9c0edad632a246f7e98ec64918",
3 "roots": {
4 "bookmark_bar": {
5 "children": [ {
6 "date_added": "13118850929335823",
7 "id": "6",
8 "name": "\"La multiplication des chefs de projet est une catastrophe managériale majeure\", affirme le sociologue François Dupuy - Ressources humaines",
9 "type": "url",
10 "url": "http://www.usinenouvelle.com/article/la-multiplication-des-chefs-de-projet-est-une-catastrophe-manageriale-majeure-affirme-le-sociologue-francois-dupuy.N307730"
11 } ],
12 "date_added": "13118829474385693",
13 "date_modified": "13118850929335823",
14 "id": "1",
15 "name": "Barre de favoris",
16 "type": "folder"
17 },
18 "other": {
19 "children": [ ],
20 "date_added": "13118829474385701",
21 "date_modified": "0",
22 "id": "2",
23 "name": "Autres favoris",
24 "type": "folder"
25 },
26 "synced": {
27 "children": [ ],
28 "date_added": "13118829474385702",
29 "date_modified": "0",
30 "id": "3",
31 "name": "Favoris sur mobile",
32 "type": "folder"
33 }
34 },
35 "version": 1
36}
diff --git a/tests/Wallabag/ImportBundle/fixtures/firefox-bookmarks.json b/tests/Wallabag/ImportBundle/fixtures/firefox-bookmarks.json
new file mode 100644
index 00000000..406b5697
--- /dev/null
+++ b/tests/Wallabag/ImportBundle/fixtures/firefox-bookmarks.json
@@ -0,0 +1,63 @@
1{
2 "guid": "root________",
3 "title": "",
4 "index": 0,
5 "dateAdded": 1388166091504000,
6 "lastModified": 1472897622350000,
7 "id": 1,
8 "type": "text/x-moz-place-container",
9 "root": "placesRoot",
10 "children": [
11 {
12 "guid": "toolbar_____",
13 "title": "Barre personnelle",
14 "index": 1,
15 "dateAdded": 1388166091504000,
16 "lastModified": 1472897622263000,
17 "id": 3,
18 "annos": [
19 {
20 "name": "bookmarkProperties/description",
21 "flags": 0,
22 "expires": 4,
23 "value": "Ajoutez des marque-pages dans ce dossier pour les voir apparaître sur votre barre personnelle"
24 }
25 ],
26 "type": "text/x-moz-place-container",
27 "root": "toolbarFolder",
28 "children": [
29 {
30 "guid": "tard77lzbC5H",
31 "title": "Orange offre un meilleur réseau mobile que Bouygues et SFR, Free derrière - L'Express L'Expansion",
32 "index": 1,
33 "dateAdded": 1388166091644000,
34 "lastModified": 1388166091644000,
35 "tags":"test,tag",
36 "id": 4,
37 "type": "text/x-moz-place",
38 "uri": "http://lexpansion.lexpress.fr/high-tech/orange-offre-un-meilleur-reseau-mobile-que-bouygues-et-sfr-free-derriere_1811554.html"
39 },
40 {
41 "guid": "E385l9vZ_LVn",
42 "title": "Parser for Exported Bookmarks HTML file of Google Chrome and Mozilla in Java",
43 "index": 1,
44 "dateAdded": 1388166091544000,
45 "lastModified": 1388166091545000,
46 "id": 5,
47 "type": "text/x-moz-place",
48 "uri": "http://stackoverflow.com/questions/15017163/parser-for-exported-bookmarks-html-file-of-google-chrome-and-mozilla-in-java"
49 }
50 ]
51 },
52 {
53 "guid": "unfiled_____",
54 "title": "Autres marque-pages",
55 "index": 3,
56 "dateAdded": 1388166091504000,
57 "lastModified": 1388166091542000,
58 "id": 6,
59 "type": "text/x-moz-place-container",
60 "root": "unfiledBookmarksFolder"
61 }
62 ]
63}