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