]> git.immae.eu Git - github/wallabag/wallabag.git/blame - src/Wallabag/ImportBundle/Import/PocketImport.php
french translation & pocket
[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 /**
129 * Set whether articles must be all marked as read.
130 *
131 * @param bool $markAsRead
132 */
133 public function setMarkAsRead($markAsRead)
134 {
135 $this->markAsRead = $markAsRead;
136
137 return $this;
138 }
139
140 /**
141 * Get whether articles must be all marked as read.
142 */
143 public function getRead()
144 {
145 return $this->markAsRead;
146 }
147
7ec2897e
JB
148 /**
149 * {@inheritdoc}
150 */
252ebd60 151 public function import()
7ec2897e
JB
152 {
153 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/get',
154 [
155 'body' => json_encode([
156 'consumer_key' => $this->consumerKey,
252ebd60 157 'access_token' => $this->accessToken,
7ec2897e
JB
158 'detailType' => 'complete',
159 'state' => 'all',
160 'sort' => 'oldest',
161 ]),
162 ]
163 );
164
252ebd60
JB
165 try {
166 $response = $this->client->send($request);
167 } catch (RequestException $e) {
168 $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]);
169
170 return false;
171 }
172
7ec2897e
JB
173 $entries = $response->json();
174
b1d05721 175 $this->parseEntries($entries['list']);
7ec2897e 176
252ebd60 177 return true;
7ec2897e
JB
178 }
179
180 /**
252ebd60 181 * {@inheritdoc}
ff7b031d 182 */
252ebd60 183 public function getSummary()
ff7b031d 184 {
252ebd60
JB
185 return [
186 'skipped' => $this->skippedEntries,
187 'imported' => $this->importedEntries,
188 ];
ff7b031d
NL
189 }
190
87f23b00 191 /**
252ebd60 192 * Set the Guzzle client.
87f23b00 193 *
252ebd60 194 * @param Client $client
87f23b00 195 */
252ebd60 196 public function setClient(Client $client)
87f23b00 197 {
252ebd60 198 $this->client = $client;
dda57bb9
NL
199 }
200
ff7b031d 201 /**
252ebd60
JB
202 * @see https://getpocket.com/developer/docs/v3/retrieve
203 *
ff7b031d
NL
204 * @param $entries
205 */
b1d05721 206 private function parseEntries($entries)
ff7b031d 207 {
7019c7cf
JB
208 $i = 1;
209
87f23b00 210 foreach ($entries as $pocketEntry) {
252ebd60 211 $url = isset($pocketEntry['resolved_url']) && $pocketEntry['resolved_url'] != '' ? $pocketEntry['resolved_url'] : $pocketEntry['given_url'];
dda57bb9
NL
212
213 $existingEntry = $this->em
214 ->getRepository('WallabagCoreBundle:Entry')
78833672 215 ->findByUrlAndUserId($url, $this->user->getId());
dda57bb9 216
5a4bbcc9 217 if (false !== $existingEntry) {
dda57bb9
NL
218 ++$this->skippedEntries;
219 continue;
220 }
221
b1d05721 222 $entry = new Entry($this->user);
252ebd60 223 $entry = $this->contentProxy->updateEntry($entry, $url);
dda57bb9 224
252ebd60 225 // 0, 1, 2 - 1 if the item is archived - 2 if the item should be deleted
c10fcb3b 226 if ($pocketEntry['status'] == 1 | $this->markAsRead) {
87f23b00
NL
227 $entry->setArchived(true);
228 }
252ebd60
JB
229
230 // 0 or 1 - 1 If the item is favorited
87f23b00
NL
231 if ($pocketEntry['favorite'] == 1) {
232 $entry->setStarred(true);
233 }
234
252ebd60
JB
235 $title = 'Untitled';
236 if (isset($pocketEntry['resolved_title']) && $pocketEntry['resolved_title'] != '') {
237 $title = $pocketEntry['resolved_title'];
238 } elseif (isset($pocketEntry['given_title']) && $pocketEntry['given_title'] != '') {
239 $title = $pocketEntry['given_title'];
87f23b00 240 }
ff7b031d 241
252ebd60 242 $entry->setTitle($title);
ff7b031d 243
252ebd60
JB
244 // 0, 1, or 2 - 1 if the item has images in it - 2 if the item is an image
245 if (isset($pocketEntry['has_image']) && $pocketEntry['has_image'] > 0 && isset($pocketEntry['images'][1])) {
246 $entry->setPreviewPicture($pocketEntry['images'][1]['src']);
ff7b031d
NL
247 }
248
252ebd60 249 if (isset($pocketEntry['tags']) && !empty($pocketEntry['tags'])) {
c2656f96
JB
250 $this->contentProxy->assignTagsToEntry(
251 $entry,
252 array_keys($pocketEntry['tags'])
253 );
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}