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