]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/ImportBundle/Import/PocketImport.php
Move assignTagsToEntry in ContentProxy helper
[github/wallabag/wallabag.git] / src / Wallabag / ImportBundle / Import / PocketImport.php
CommitLineData
ff7b031d
NL
1<?php
2
3namespace Wallabag\ImportBundle\Import;
4
252ebd60
JB
5use Psr\Log\LoggerInterface;
6use Psr\Log\NullLogger;
ff7b031d
NL
7use Doctrine\ORM\EntityManager;
8use GuzzleHttp\Client;
252ebd60 9use GuzzleHttp\Exception\RequestException;
0aa344dc 10use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
ff7b031d 11use Wallabag\CoreBundle\Entity\Entry;
252ebd60 12use Wallabag\CoreBundle\Helper\ContentProxy;
63e40f2d 13use Craue\ConfigBundle\Util\Config;
ff7b031d
NL
14
15class PocketImport implements ImportInterface
16{
17 private $user;
ff7b031d 18 private $em;
252ebd60
JB
19 private $contentProxy;
20 private $logger;
8eedc8cf 21 private $client;
ff7b031d 22 private $consumerKey;
303768df
NL
23 private $skippedEntries = 0;
24 private $importedEntries = 0;
252ebd60 25 protected $accessToken;
ff7b031d 26
63e40f2d 27 public function __construct(TokenStorageInterface $tokenStorage, EntityManager $em, ContentProxy $contentProxy, Config $craueConfig)
ff7b031d
NL
28 {
29 $this->user = $tokenStorage->getToken()->getUser();
ff7b031d 30 $this->em = $em;
252ebd60 31 $this->contentProxy = $contentProxy;
63e40f2d 32 $this->consumerKey = $craueConfig->get('pocket_consumer_key');
252ebd60
JB
33 $this->logger = new NullLogger();
34 }
35
36 public function setLogger(LoggerInterface $logger)
37 {
38 $this->logger = $logger;
ff7b031d
NL
39 }
40
0aa344dc
JB
41 /**
42 * {@inheritdoc}
43 */
d51b38ed
NL
44 public function getName()
45 {
46 return 'Pocket';
47 }
48
7019c7cf
JB
49 /**
50 * {@inheritdoc}
51 */
52 public function getUrl()
53 {
54 return 'import_pocket';
55 }
56
0aa344dc
JB
57 /**
58 * {@inheritdoc}
59 */
d51b38ed
NL
60 public function getDescription()
61 {
b88cf91f 62 return 'This importer will import all your Pocket data. Pocket doesn\'t allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag.';
d51b38ed
NL
63 }
64
ff7b031d 65 /**
252ebd60
JB
66 * Return the oauth url to authenticate the client.
67 *
68 * @param string $redirectUri Redirect url in case of error
69 *
70 * @return string request_token for callback method
7ec2897e 71 */
252ebd60 72 public function getRequestToken($redirectUri)
7ec2897e
JB
73 {
74 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/request',
75 [
76 'body' => json_encode([
77 'consumer_key' => $this->consumerKey,
78 'redirect_uri' => $redirectUri,
79 ]),
80 ]
81 );
82
252ebd60
JB
83 try {
84 $response = $this->client->send($request);
85 } catch (RequestException $e) {
86 $this->logger->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]);
7ec2897e 87
252ebd60
JB
88 return false;
89 }
7ec2897e 90
252ebd60 91 return $response->json()['code'];
7ec2897e
JB
92 }
93
94 /**
252ebd60
JB
95 * Usually called by the previous callback to authorize the client.
96 * Then it return a token that can be used for next requests.
97 *
98 * @param string $code request_token from getRequestToken
99 *
100 * @return bool
7ec2897e 101 */
252ebd60 102 public function authorize($code)
7ec2897e
JB
103 {
104 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/authorize',
105 [
106 'body' => json_encode([
107 'consumer_key' => $this->consumerKey,
252ebd60 108 'code' => $code,
7ec2897e
JB
109 ]),
110 ]
111 );
112
252ebd60
JB
113 try {
114 $response = $this->client->send($request);
115 } catch (RequestException $e) {
116 $this->logger->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]);
7ec2897e 117
252ebd60
JB
118 return false;
119 }
120
121 $this->accessToken = $response->json()['access_token'];
122
123 return true;
7ec2897e
JB
124 }
125
126 /**
127 * {@inheritdoc}
128 */
252ebd60 129 public function import()
7ec2897e
JB
130 {
131 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/get',
132 [
133 'body' => json_encode([
134 'consumer_key' => $this->consumerKey,
252ebd60 135 'access_token' => $this->accessToken,
7ec2897e
JB
136 'detailType' => 'complete',
137 'state' => 'all',
138 'sort' => 'oldest',
139 ]),
140 ]
141 );
142
252ebd60
JB
143 try {
144 $response = $this->client->send($request);
145 } catch (RequestException $e) {
146 $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]);
147
148 return false;
149 }
150
7ec2897e
JB
151 $entries = $response->json();
152
b1d05721 153 $this->parseEntries($entries['list']);
7ec2897e 154
252ebd60 155 return true;
7ec2897e
JB
156 }
157
158 /**
252ebd60 159 * {@inheritdoc}
ff7b031d 160 */
252ebd60 161 public function getSummary()
ff7b031d 162 {
252ebd60
JB
163 return [
164 'skipped' => $this->skippedEntries,
165 'imported' => $this->importedEntries,
166 ];
ff7b031d
NL
167 }
168
87f23b00 169 /**
252ebd60 170 * Set the Guzzle client.
87f23b00 171 *
252ebd60 172 * @param Client $client
87f23b00 173 */
252ebd60 174 public function setClient(Client $client)
87f23b00 175 {
252ebd60 176 $this->client = $client;
dda57bb9
NL
177 }
178
ff7b031d 179 /**
252ebd60
JB
180 * @see https://getpocket.com/developer/docs/v3/retrieve
181 *
ff7b031d
NL
182 * @param $entries
183 */
b1d05721 184 private function parseEntries($entries)
ff7b031d 185 {
7019c7cf
JB
186 $i = 1;
187
87f23b00 188 foreach ($entries as $pocketEntry) {
252ebd60 189 $url = isset($pocketEntry['resolved_url']) && $pocketEntry['resolved_url'] != '' ? $pocketEntry['resolved_url'] : $pocketEntry['given_url'];
dda57bb9
NL
190
191 $existingEntry = $this->em
192 ->getRepository('WallabagCoreBundle:Entry')
78833672 193 ->findByUrlAndUserId($url, $this->user->getId());
dda57bb9 194
5a4bbcc9 195 if (false !== $existingEntry) {
dda57bb9
NL
196 ++$this->skippedEntries;
197 continue;
198 }
199
b1d05721 200 $entry = new Entry($this->user);
252ebd60 201 $entry = $this->contentProxy->updateEntry($entry, $url);
dda57bb9 202
252ebd60 203 // 0, 1, 2 - 1 if the item is archived - 2 if the item should be deleted
87f23b00
NL
204 if ($pocketEntry['status'] == 1) {
205 $entry->setArchived(true);
206 }
252ebd60
JB
207
208 // 0 or 1 - 1 If the item is favorited
87f23b00
NL
209 if ($pocketEntry['favorite'] == 1) {
210 $entry->setStarred(true);
211 }
212
252ebd60
JB
213 $title = 'Untitled';
214 if (isset($pocketEntry['resolved_title']) && $pocketEntry['resolved_title'] != '') {
215 $title = $pocketEntry['resolved_title'];
216 } elseif (isset($pocketEntry['given_title']) && $pocketEntry['given_title'] != '') {
217 $title = $pocketEntry['given_title'];
87f23b00 218 }
ff7b031d 219
252ebd60 220 $entry->setTitle($title);
ff7b031d 221
252ebd60
JB
222 // 0, 1, or 2 - 1 if the item has images in it - 2 if the item is an image
223 if (isset($pocketEntry['has_image']) && $pocketEntry['has_image'] > 0 && isset($pocketEntry['images'][1])) {
224 $entry->setPreviewPicture($pocketEntry['images'][1]['src']);
ff7b031d
NL
225 }
226
252ebd60 227 if (isset($pocketEntry['tags']) && !empty($pocketEntry['tags'])) {
c2656f96
JB
228 $this->contentProxy->assignTagsToEntry(
229 $entry,
230 array_keys($pocketEntry['tags'])
231 );
ff7b031d
NL
232 }
233
87f23b00 234 $this->em->persist($entry);
dda57bb9 235 ++$this->importedEntries;
7019c7cf
JB
236
237 // flush every 20 entries
238 if (($i % 20) === 0) {
8eedc8cf 239 $this->em->flush();
7019c7cf
JB
240 }
241 ++$i;
ff7b031d
NL
242 }
243
244 $this->em->flush();
245 }
ff7b031d 246}