3 namespace Wallabag\ImportBundle\Import
;
5 use Psr\Log\NullLogger
;
6 use Doctrine\ORM\EntityManager
;
8 use GuzzleHttp\Exception\RequestException
;
9 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface
;
10 use Wallabag\CoreBundle\Entity\Entry
;
11 use Wallabag\CoreBundle\Helper\ContentProxy
;
12 use Craue\ConfigBundle\Util\Config
;
14 class PocketImport
extends AbstractImport
19 private $skippedEntries = 0;
20 private $importedEntries = 0;
22 protected $accessToken;
24 public function __construct(TokenStorageInterface
$tokenStorage, EntityManager
$em, ContentProxy
$contentProxy, Config
$craueConfig)
26 $this->user
= $tokenStorage->getToken()->getUser();
28 $this->contentProxy
= $contentProxy;
29 $this->consumerKey
= $craueConfig->get('pocket_consumer_key');
30 $this->logger
= new NullLogger();
36 public function getName()
44 public function getUrl()
46 return 'import_pocket';
52 public function getDescription()
54 return 'import.pocket.description';
58 * Return the oauth url to authenticate the client.
60 * @param string $redirectUri Redirect url in case of error
62 * @return string|false request_token for callback method
64 public function getRequestToken($redirectUri)
66 $request = $this->client
->createRequest('POST', 'https://getpocket.com/v3/oauth/request',
68 'body' => json_encode([
69 'consumer_key' => $this->consumerKey
,
70 'redirect_uri' => $redirectUri,
76 $response = $this->client
->send($request);
77 } catch (RequestException
$e) {
78 $this->logger
->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]);
83 return $response->json()['code'];
87 * Usually called by the previous callback to authorize the client.
88 * Then it return a token that can be used for next requests.
90 * @param string $code request_token from getRequestToken
94 public function authorize($code)
96 $request = $this->client
->createRequest('POST', 'https://getpocket.com/v3/oauth/authorize',
98 'body' => json_encode([
99 'consumer_key' => $this->consumerKey
,
106 $response = $this->client
->send($request);
107 } catch (RequestException
$e) {
108 $this->logger
->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]);
113 $this->accessToken
= $response->json()['access_token'];
119 * Set whether articles must be all marked as read.
121 * @param bool $markAsRead
123 public function setMarkAsRead($markAsRead)
125 $this->markAsRead
= $markAsRead;
131 * Get whether articles must be all marked as read.
133 public function getMarkAsRead()
135 return $this->markAsRead
;
141 public function import()
143 $request = $this->client
->createRequest('POST', 'https://getpocket.com/v3/get',
145 'body' => json_encode([
146 'consumer_key' => $this->consumerKey
,
147 'access_token' => $this->accessToken
,
148 'detailType' => 'complete',
156 $response = $this->client
->send($request);
157 } catch (RequestException
$e) {
158 $this->logger
->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]);
163 $entries = $response->json();
165 $this->parseEntries($entries['list']);
173 public function getSummary()
176 'skipped' => $this->skippedEntries
,
177 'imported' => $this->importedEntries
,
182 * Set the Guzzle client.
184 * @param Client $client
186 public function setClient(Client
$client)
188 $this->client
= $client;
192 * @see https://getpocket.com/developer/docs/v3/retrieve
196 private function parseEntries($entries)
200 foreach ($entries as $pocketEntry) {
201 $url = isset($pocketEntry['resolved_url']) && $pocketEntry['resolved_url'] != '' ? $pocketEntry['resolved_url'] : $pocketEntry['given_url'];
203 $existingEntry = $this->em
204 ->getRepository('WallabagCoreBundle:Entry')
205 ->findByUrlAndUserId($url, $this->user
->getId());
207 if (false !== $existingEntry) {
208 ++
$this->skippedEntries
;
212 $entry = new Entry($this->user
);
213 $entry = $this->fetchContent($entry, $url);
215 // jump to next entry in case of problem while getting content
216 if (false === $entry) {
217 ++
$this->skippedEntries
;
221 // 0, 1, 2 - 1 if the item is archived - 2 if the item should be deleted
222 if ($pocketEntry['status'] == 1 || $this->markAsRead
) {
223 $entry->setArchived(true);
226 // 0 or 1 - 1 If the item is starred
227 if ($pocketEntry['favorite'] == 1) {
228 $entry->setStarred(true);
232 if (isset($pocketEntry['resolved_title']) && $pocketEntry['resolved_title'] != '') {
233 $title = $pocketEntry['resolved_title'];
234 } elseif (isset($pocketEntry['given_title']) && $pocketEntry['given_title'] != '') {
235 $title = $pocketEntry['given_title'];
238 $entry->setTitle($title);
240 // 0, 1, or 2 - 1 if the item has images in it - 2 if the item is an image
241 if (isset($pocketEntry['has_image']) && $pocketEntry['has_image'] > 0 && isset($pocketEntry['images'][1])) {
242 $entry->setPreviewPicture($pocketEntry['images'][1]['src']);
245 if (isset($pocketEntry['tags']) && !empty($pocketEntry['tags'])) {
246 $this->contentProxy
->assignTagsToEntry(
248 array_keys($pocketEntry['tags'])
252 $this->em
->persist($entry);
253 ++
$this->importedEntries
;
255 // flush every 20 entries
256 if (($i %
20) === 0) {
258 $this->em
->clear($entry);