diff options
author | Jeremy Benoist <jeremy.benoist@gmail.com> | 2016-11-04 22:44:31 +0100 |
---|---|---|
committer | Jeremy Benoist <jeremy.benoist@gmail.com> | 2016-11-04 22:44:31 +0100 |
commit | 9ab024b4f5388e2a41c50a8a2b79e4033788782a (patch) | |
tree | ae01ddb121b5037aae89e892d1b971208b5108dd /src/Wallabag/ImportBundle | |
parent | b5571b52ccbc11d71637e1ccb07421cf606ac846 (diff) | |
download | wallabag-9ab024b4f5388e2a41c50a8a2b79e4033788782a.tar.gz wallabag-9ab024b4f5388e2a41c50a8a2b79e4033788782a.tar.zst wallabag-9ab024b4f5388e2a41c50a8a2b79e4033788782a.zip |
Add Pinboard import
Diffstat (limited to 'src/Wallabag/ImportBundle')
9 files changed, 312 insertions, 2 deletions
diff --git a/src/Wallabag/ImportBundle/Command/ImportCommand.php b/src/Wallabag/ImportBundle/Command/ImportCommand.php index e423ffae..28d01715 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') | 17 | ->setDescription('Import entries from a JSON export') |
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, v2, instapaper, readability, firefox or chrome', 'v1') | 20 | ->addOption('importer', null, InputArgument::OPTIONAL, 'The importer to use: v1, v2, instapaper, pinboard, readability, 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 | } |
@@ -56,6 +56,9 @@ class ImportCommand extends ContainerAwareCommand | |||
56 | case 'instapaper': | 56 | case 'instapaper': |
57 | $import = $this->getContainer()->get('wallabag_import.instapaper.import'); | 57 | $import = $this->getContainer()->get('wallabag_import.instapaper.import'); |
58 | break; | 58 | break; |
59 | case 'pinboard': | ||
60 | $import = $this->getContainer()->get('wallabag_import.pinboard.import'); | ||
61 | break; | ||
59 | default: | 62 | default: |
60 | $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); | 63 | $import = $this->getContainer()->get('wallabag_import.wallabag_v1.import'); |
61 | } | 64 | } |
diff --git a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php index c2c11f11..f793a314 100644 --- a/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php +++ b/src/Wallabag/ImportBundle/Command/RedisWorkerCommand.php | |||
@@ -17,7 +17,7 @@ class RedisWorkerCommand extends ContainerAwareCommand | |||
17 | $this | 17 | $this |
18 | ->setName('wallabag:import:redis-worker') | 18 | ->setName('wallabag:import:redis-worker') |
19 | ->setDescription('Launch Redis worker') | 19 | ->setDescription('Launch Redis worker') |
20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket, readability, firefox, chrome or instapaper') | 20 | ->addArgument('serviceName', InputArgument::REQUIRED, 'Service to use: wallabag_v1, wallabag_v2, pocket, readability, pinboard, firefox, chrome or instapaper') |
21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) | 21 | ->addOption('maxIterations', '', InputOption::VALUE_OPTIONAL, 'Number of iterations before stoping', false) |
22 | ; | 22 | ; |
23 | } | 23 | } |
diff --git a/src/Wallabag/ImportBundle/Controller/ImportController.php b/src/Wallabag/ImportBundle/Controller/ImportController.php index 15de75ff..237c748e 100644 --- a/src/Wallabag/ImportBundle/Controller/ImportController.php +++ b/src/Wallabag/ImportBundle/Controller/ImportController.php | |||
@@ -42,6 +42,7 @@ class ImportController extends Controller | |||
42 | + $this->getTotalMessageInRabbitQueue('firefox') | 42 | + $this->getTotalMessageInRabbitQueue('firefox') |
43 | + $this->getTotalMessageInRabbitQueue('chrome') | 43 | + $this->getTotalMessageInRabbitQueue('chrome') |
44 | + $this->getTotalMessageInRabbitQueue('instapaper') | 44 | + $this->getTotalMessageInRabbitQueue('instapaper') |
45 | + $this->getTotalMessageInRabbitQueue('pinboard') | ||
45 | ; | 46 | ; |
46 | } catch (\Exception $e) { | 47 | } catch (\Exception $e) { |
47 | $rabbitNotInstalled = true; | 48 | $rabbitNotInstalled = true; |
@@ -57,6 +58,7 @@ class ImportController extends Controller | |||
57 | + $redis->llen('wallabag.import.firefox') | 58 | + $redis->llen('wallabag.import.firefox') |
58 | + $redis->llen('wallabag.import.chrome') | 59 | + $redis->llen('wallabag.import.chrome') |
59 | + $redis->llen('wallabag.import.instapaper') | 60 | + $redis->llen('wallabag.import.instapaper') |
61 | + $redis->llen('wallabag.import.pinboard') | ||
60 | ; | 62 | ; |
61 | } catch (\Exception $e) { | 63 | } catch (\Exception $e) { |
62 | $redisNotInstalled = true; | 64 | $redisNotInstalled = true; |
diff --git a/src/Wallabag/ImportBundle/Controller/PinboardController.php b/src/Wallabag/ImportBundle/Controller/PinboardController.php new file mode 100644 index 00000000..9c3f98d6 --- /dev/null +++ b/src/Wallabag/ImportBundle/Controller/PinboardController.php | |||
@@ -0,0 +1,77 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Controller; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
6 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Wallabag\ImportBundle\Form\Type\UploadImportType; | ||
9 | |||
10 | class PinboardController extends Controller | ||
11 | { | ||
12 | /** | ||
13 | * @Route("/pinboard", name="import_pinboard") | ||
14 | */ | ||
15 | public function indexAction(Request $request) | ||
16 | { | ||
17 | $form = $this->createForm(UploadImportType::class); | ||
18 | $form->handleRequest($request); | ||
19 | |||
20 | $pinboard = $this->get('wallabag_import.pinboard.import'); | ||
21 | $pinboard->setUser($this->getUser()); | ||
22 | |||
23 | if ($this->get('craue_config')->get('import_with_rabbitmq')) { | ||
24 | $pinboard->setProducer($this->get('old_sound_rabbit_mq.import_pinboard_producer')); | ||
25 | } elseif ($this->get('craue_config')->get('import_with_redis')) { | ||
26 | $pinboard->setProducer($this->get('wallabag_import.producer.redis.pinboard')); | ||
27 | } | ||
28 | |||
29 | if ($form->isValid()) { | ||
30 | $file = $form->get('file')->getData(); | ||
31 | $markAsRead = $form->get('mark_as_read')->getData(); | ||
32 | $name = 'pinboard_'.$this->getUser()->getId().'.json'; | ||
33 | |||
34 | if (null !== $file && in_array($file->getClientMimeType(), $this->getParameter('wallabag_import.allow_mimetypes')) && $file->move($this->getParameter('wallabag_import.resource_dir'), $name)) { | ||
35 | $res = $pinboard | ||
36 | ->setFilepath($this->getParameter('wallabag_import.resource_dir').'/'.$name) | ||
37 | ->setMarkAsRead($markAsRead) | ||
38 | ->import(); | ||
39 | |||
40 | $message = 'flashes.import.notice.failed'; | ||
41 | |||
42 | if (true === $res) { | ||
43 | $summary = $pinboard->getSummary(); | ||
44 | $message = $this->get('translator')->trans('flashes.import.notice.summary', [ | ||
45 | '%imported%' => $summary['imported'], | ||
46 | '%skipped%' => $summary['skipped'], | ||
47 | ]); | ||
48 | |||
49 | if (0 < $summary['queued']) { | ||
50 | $message = $this->get('translator')->trans('flashes.import.notice.summary_with_queue', [ | ||
51 | '%queued%' => $summary['queued'], | ||
52 | ]); | ||
53 | } | ||
54 | |||
55 | unlink($this->getParameter('wallabag_import.resource_dir').'/'.$name); | ||
56 | } | ||
57 | |||
58 | $this->get('session')->getFlashBag()->add( | ||
59 | 'notice', | ||
60 | $message | ||
61 | ); | ||
62 | |||
63 | return $this->redirect($this->generateUrl('homepage')); | ||
64 | } else { | ||
65 | $this->get('session')->getFlashBag()->add( | ||
66 | 'notice', | ||
67 | 'flashes.import.notice.failed_on_file' | ||
68 | ); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | return $this->render('WallabagImportBundle:Pinboard:index.html.twig', [ | ||
73 | 'form' => $form->createView(), | ||
74 | 'import' => $pinboard, | ||
75 | ]); | ||
76 | } | ||
77 | } | ||
diff --git a/src/Wallabag/ImportBundle/Import/PinboardImport.php b/src/Wallabag/ImportBundle/Import/PinboardImport.php new file mode 100644 index 00000000..9bcfbc36 --- /dev/null +++ b/src/Wallabag/ImportBundle/Import/PinboardImport.php | |||
@@ -0,0 +1,143 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ImportBundle\Import; | ||
4 | |||
5 | use Wallabag\CoreBundle\Entity\Entry; | ||
6 | |||
7 | class PinboardImport extends AbstractImport | ||
8 | { | ||
9 | private $filepath; | ||
10 | |||
11 | /** | ||
12 | * {@inheritdoc} | ||
13 | */ | ||
14 | public function getName() | ||
15 | { | ||
16 | return 'Pinboard'; | ||
17 | } | ||
18 | |||
19 | /** | ||
20 | * {@inheritdoc} | ||
21 | */ | ||
22 | public function getUrl() | ||
23 | { | ||
24 | return 'import_pinboard'; | ||
25 | } | ||
26 | |||
27 | /** | ||
28 | * {@inheritdoc} | ||
29 | */ | ||
30 | public function getDescription() | ||
31 | { | ||
32 | return 'import.pinboard.description'; | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * Set file path to the json file. | ||
37 | * | ||
38 | * @param string $filepath | ||
39 | */ | ||
40 | public function setFilepath($filepath) | ||
41 | { | ||
42 | $this->filepath = $filepath; | ||
43 | |||
44 | return $this; | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * {@inheritdoc} | ||
49 | */ | ||
50 | public function import() | ||
51 | { | ||
52 | if (!$this->user) { | ||
53 | $this->logger->error('PinboardImport: user is not defined'); | ||
54 | |||
55 | return false; | ||
56 | } | ||
57 | |||
58 | if (!file_exists($this->filepath) || !is_readable($this->filepath)) { | ||
59 | $this->logger->error('PinboardImport: unable to read file', ['filepath' => $this->filepath]); | ||
60 | |||
61 | return false; | ||
62 | } | ||
63 | |||
64 | $data = json_decode(file_get_contents($this->filepath), true); | ||
65 | |||
66 | if (empty($data)) { | ||
67 | $this->logger->error('PinboardImport: no entries in imported file'); | ||
68 | |||
69 | return false; | ||
70 | } | ||
71 | |||
72 | if ($this->producer) { | ||
73 | $this->parseEntriesForProducer($data); | ||
74 | |||
75 | return true; | ||
76 | } | ||
77 | |||
78 | $this->parseEntries($data); | ||
79 | |||
80 | return true; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * {@inheritdoc} | ||
85 | */ | ||
86 | public function parseEntry(array $importedEntry) | ||
87 | { | ||
88 | $existingEntry = $this->em | ||
89 | ->getRepository('WallabagCoreBundle:Entry') | ||
90 | ->findByUrlAndUserId($importedEntry['href'], $this->user->getId()); | ||
91 | |||
92 | if (false !== $existingEntry) { | ||
93 | ++$this->skippedEntries; | ||
94 | |||
95 | return; | ||
96 | } | ||
97 | |||
98 | $data = [ | ||
99 | 'title' => $importedEntry['description'], | ||
100 | 'url' => $importedEntry['href'], | ||
101 | 'content_type' => '', | ||
102 | 'language' => '', | ||
103 | 'is_archived' => ('no' === $importedEntry['toread']) || $this->markAsRead, | ||
104 | 'is_starred' => false, | ||
105 | 'created_at' => $importedEntry['time'], | ||
106 | 'tags' => explode(' ', $importedEntry['tags']), | ||
107 | ]; | ||
108 | |||
109 | $entry = new Entry($this->user); | ||
110 | $entry->setUrl($data['url']); | ||
111 | $entry->setTitle($data['title']); | ||
112 | |||
113 | // update entry with content (in case fetching failed, the given entry will be return) | ||
114 | $entry = $this->fetchContent($entry, $data['url'], $data); | ||
115 | |||
116 | if (!empty($data['tags'])) { | ||
117 | $this->contentProxy->assignTagsToEntry( | ||
118 | $entry, | ||
119 | $data['tags'], | ||
120 | $this->em->getUnitOfWork()->getScheduledEntityInsertions() | ||
121 | ); | ||
122 | } | ||
123 | |||
124 | $entry->setArchived($data['is_archived']); | ||
125 | $entry->setStarred($data['is_starred']); | ||
126 | $entry->setCreatedAt(new \DateTime($data['created_at'])); | ||
127 | |||
128 | $this->em->persist($entry); | ||
129 | ++$this->importedEntries; | ||
130 | |||
131 | return $entry; | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * {@inheritdoc} | ||
136 | */ | ||
137 | protected function setEntryAsRead(array $importedEntry) | ||
138 | { | ||
139 | $importedEntry['toread'] = 'no'; | ||
140 | |||
141 | return $importedEntry; | ||
142 | } | ||
143 | } | ||
diff --git a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml index a5af5282..e9ecb846 100644 --- a/src/Wallabag/ImportBundle/Resources/config/rabbit.yml +++ b/src/Wallabag/ImportBundle/Resources/config/rabbit.yml | |||
@@ -24,6 +24,14 @@ services: | |||
24 | - "@wallabag_import.instapaper.import" | 24 | - "@wallabag_import.instapaper.import" |
25 | - "@event_dispatcher" | 25 | - "@event_dispatcher" |
26 | - "@logger" | 26 | - "@logger" |
27 | wallabag_import.consumer.amqp.pinboard: | ||
28 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | ||
29 | arguments: | ||
30 | - "@doctrine.orm.entity_manager" | ||
31 | - "@wallabag_user.user_repository" | ||
32 | - "@wallabag_import.pinboard.import" | ||
33 | - "@event_dispatcher" | ||
34 | - "@logger" | ||
27 | wallabag_import.consumer.amqp.wallabag_v1: | 35 | wallabag_import.consumer.amqp.wallabag_v1: |
28 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer | 36 | class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer |
29 | arguments: | 37 | arguments: |
diff --git a/src/Wallabag/ImportBundle/Resources/config/redis.yml b/src/Wallabag/ImportBundle/Resources/config/redis.yml index 5ced4c83..091cdba0 100644 --- a/src/Wallabag/ImportBundle/Resources/config/redis.yml +++ b/src/Wallabag/ImportBundle/Resources/config/redis.yml | |||
@@ -42,6 +42,27 @@ services: | |||
42 | - "@event_dispatcher" | 42 | - "@event_dispatcher" |
43 | - "@logger" | 43 | - "@logger" |
44 | 44 | ||
45 | # pinboard | ||
46 | wallabag_import.queue.redis.pinboard: | ||
47 | class: Simpleue\Queue\RedisQueue | ||
48 | arguments: | ||
49 | - "@wallabag_core.redis.client" | ||
50 | - "wallabag.import.pinboard" | ||
51 | |||
52 | wallabag_import.producer.redis.pinboard: | ||
53 | class: Wallabag\ImportBundle\Redis\Producer | ||
54 | arguments: | ||
55 | - "@wallabag_import.queue.redis.pinboard" | ||
56 | |||
57 | wallabag_import.consumer.redis.pinboard: | ||
58 | class: Wallabag\ImportBundle\Consumer\RedisEntryConsumer | ||
59 | arguments: | ||
60 | - "@doctrine.orm.entity_manager" | ||
61 | - "@wallabag_user.user_repository" | ||
62 | - "@wallabag_import.pinboard.import" | ||
63 | - "@event_dispatcher" | ||
64 | - "@logger" | ||
65 | |||
45 | 66 | ||
46 | wallabag_import.queue.redis.pocket: | 67 | wallabag_import.queue.redis.pocket: |
47 | class: Simpleue\Queue\RedisQueue | 68 | class: Simpleue\Queue\RedisQueue |
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml index 64822963..c4fe3f92 100644 --- a/src/Wallabag/ImportBundle/Resources/config/services.yml +++ b/src/Wallabag/ImportBundle/Resources/config/services.yml | |||
@@ -71,6 +71,17 @@ services: | |||
71 | tags: | 71 | tags: |
72 | - { name: wallabag_import.import, alias: instapaper } | 72 | - { name: wallabag_import.import, alias: instapaper } |
73 | 73 | ||
74 | wallabag_import.pinboard.import: | ||
75 | class: Wallabag\ImportBundle\Import\PinboardImport | ||
76 | arguments: | ||
77 | - "@doctrine.orm.entity_manager" | ||
78 | - "@wallabag_core.content_proxy" | ||
79 | - "@event_dispatcher" | ||
80 | calls: | ||
81 | - [ setLogger, [ "@logger" ]] | ||
82 | tags: | ||
83 | - { name: wallabag_import.import, alias: pinboard } | ||
84 | |||
74 | wallabag_import.firefox.import: | 85 | wallabag_import.firefox.import: |
75 | class: Wallabag\ImportBundle\Import\FirefoxImport | 86 | class: Wallabag\ImportBundle\Import\FirefoxImport |
76 | arguments: | 87 | arguments: |
diff --git a/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig new file mode 100644 index 00000000..43f196ad --- /dev/null +++ b/src/Wallabag/ImportBundle/Resources/views/Pinboard/index.html.twig | |||
@@ -0,0 +1,45 @@ | |||
1 | {% extends "WallabagCoreBundle::layout.html.twig" %} | ||
2 | |||
3 | {% block title %}{{ 'import.pinboard.page_title'|trans }}{% endblock %} | ||
4 | |||
5 | {% block content %} | ||
6 | <div class="row"> | ||
7 | <div class="col s12"> | ||
8 | <div class="card-panel settings"> | ||
9 | {% include 'WallabagImportBundle:Import:_information.html.twig' %} | ||
10 | |||
11 | <div class="row"> | ||
12 | <blockquote>{{ import.description|trans }}</blockquote> | ||
13 | <p>{{ 'import.pinboard.how_to'|trans }}</p> | ||
14 | |||
15 | <div class="col s12"> | ||
16 | {{ form_start(form, {'method': 'POST'}) }} | ||
17 | {{ form_errors(form) }} | ||
18 | <div class="row"> | ||
19 | <div class="file-field input-field col s12"> | ||
20 | {{ form_errors(form.file) }} | ||
21 | <div class="btn"> | ||
22 | <span>{{ form.file.vars.label|trans }}</span> | ||
23 | {{ form_widget(form.file) }} | ||
24 | </div> | ||
25 | <div class="file-path-wrapper"> | ||
26 | <input class="file-path validate" type="text"> | ||
27 | </div> | ||
28 | </div> | ||
29 | <div class="input-field col s6 with-checkbox"> | ||
30 | <h6>{{ 'import.form.mark_as_read_title'|trans }}</h6> | ||
31 | {{ form_widget(form.mark_as_read) }} | ||
32 | {{ form_label(form.mark_as_read) }} | ||
33 | </div> | ||
34 | </div> | ||
35 | |||
36 | {{ form_widget(form.save, { 'attr': {'class': 'btn waves-effect waves-light'} }) }} | ||
37 | |||
38 | {{ form_rest(form) }} | ||
39 | </form> | ||
40 | </div> | ||
41 | </div> | ||
42 | </div> | ||
43 | </div> | ||
44 | </div> | ||
45 | {% endblock %} | ||