]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/ImportBundle/Import/PocketImport.php
fix #1502 avoid duplicate entry and store pocket url in config
[github/wallabag/wallabag.git] / src / Wallabag / ImportBundle / Import / PocketImport.php
1 <?php
2
3 namespace Wallabag\ImportBundle\Import;
4
5 use Doctrine\ORM\EntityManager;
6 use GuzzleHttp\Client;
7 use Symfony\Component\HttpFoundation\Session\Session;
8 use Wallabag\CoreBundle\Entity\Entry;
9 use Wallabag\CoreBundle\Entity\Tag;
10 use Wallabag\CoreBundle\Tools\Utils;
11
12 class PocketImport implements ImportInterface
13 {
14 private $user;
15 private $session;
16 private $em;
17 private $consumerKey;
18 private $skippedEntries;
19 private $importedEntries;
20 private $pocketURL;
21
22 public function __construct($tokenStorage, Session $session, EntityManager $em, $consumerKey, $pocketURL)
23 {
24 $this->user = $tokenStorage->getToken()->getUser();
25 $this->session = $session;
26 $this->em = $em;
27 $this->consumerKey = $consumerKey;
28 $this->skippedEntries = 0;
29 $this->importedEntries = 0;
30 $this->pocketURL = $pocketURL;
31 }
32
33 public function getName()
34 {
35 return 'Pocket';
36 }
37
38 public function getDescription()
39 {
40 return 'This importer will import all your <a href="https://getpocket.com">Pocket</a> data.';
41 }
42
43 /**
44 * Create a new Client.
45 *
46 * @return Client
47 */
48 private function createClient()
49 {
50 return new Client([
51 'defaults' => [
52 'headers' => [
53 'content-type' => 'application/json',
54 'X-Accept' => 'application/json',
55 ],
56 ],
57 ]);
58 }
59
60 /**
61 * Returns the good title for current entry.
62 *
63 * @param $pocketEntry
64 *
65 * @return string
66 */
67 private function guessTitle($pocketEntry)
68 {
69 if (isset($pocketEntry['resolved_title']) && $pocketEntry['resolved_title'] != '') {
70 return $pocketEntry['resolved_title'];
71 } elseif (isset($pocketEntry['given_title']) && $pocketEntry['given_title'] != '') {
72 return $pocketEntry['given_title'];
73 }
74
75 return 'Untitled';
76 }
77
78 /**
79 * Returns the good URL for current entry.
80 *
81 * @param $pocketEntry
82 *
83 * @return string
84 */
85 private function guessURL($pocketEntry)
86 {
87 if (isset($pocketEntry['resolved_url']) && $pocketEntry['resolved_url'] != '') {
88 return $pocketEntry['resolved_url'];
89 }
90
91 return $pocketEntry['given_url'];
92 }
93
94 private function assignTagsToEntry(Entry $entry, $tags)
95 {
96 foreach ($tags as $tag) {
97 $label = trim($tag['tag']);
98 $tagEntity = $this->em
99 ->getRepository('WallabagCoreBundle:Tag')
100 ->findOneByLabelAndUserId($label, $this->user->getId());
101
102 if (is_object($tagEntity)) {
103 $entry->addTag($tagEntity);
104 } else {
105 $newTag = new Tag($this->user);
106 $newTag->setLabel($label);
107 $entry->addTag($newTag);
108 }
109 $this->em->flush();
110 }
111 }
112
113 /**
114 * @param $entries
115 */
116 private function parsePocketEntries($entries)
117 {
118 foreach ($entries as $pocketEntry) {
119 $entry = new Entry($this->user);
120 $url = $this->guessURL($pocketEntry);
121
122 $existingEntry = $this->em
123 ->getRepository('WallabagCoreBundle:Entry')
124 ->findOneByUrl($url);
125
126 if (!is_null($existingEntry)) {
127 ++$this->skippedEntries;
128 continue;
129 }
130
131 $entry->setUrl($url);
132 $entry->setDomainName(parse_url($url, PHP_URL_HOST));
133
134 if ($pocketEntry['status'] == 1) {
135 $entry->setArchived(true);
136 }
137 if ($pocketEntry['favorite'] == 1) {
138 $entry->setStarred(true);
139 }
140
141 $entry->setTitle($this->guessTitle($pocketEntry));
142
143 if (isset($pocketEntry['excerpt'])) {
144 $entry->setContent($pocketEntry['excerpt']);
145 }
146
147 if (isset($pocketEntry['has_image']) && $pocketEntry['has_image'] > 0) {
148 $entry->setPreviewPicture($pocketEntry['image']['src']);
149 }
150
151 if (isset($pocketEntry['word_count'])) {
152 $entry->setReadingTime(Utils::convertWordsToMinutes($pocketEntry['word_count']));
153 }
154
155 if (!empty($pocketEntry['tags'])) {
156 // $this->assignTagsToEntry($entry, $pocketEntry['tags']);
157 }
158
159 $this->em->persist($entry);
160 ++$this->importedEntries;
161 }
162
163 $this->em->flush();
164 }
165
166 public function oAuthRequest($redirectUri, $callbackUri)
167 {
168 $client = $this->createClient();
169 $request = $client->createRequest('POST', $this->pocketURL['oauth_request'],
170 [
171 'body' => json_encode([
172 'consumer_key' => $this->consumerKey,
173 'redirect_uri' => $redirectUri,
174 ]),
175 ]
176 );
177
178 $response = $client->send($request);
179 $values = $response->json();
180
181 // store code in session for callback method
182 $this->session->set('pocketCode', $values['code']);
183
184 return $this->pocketURL['auth_authorize'].'?request_token='.$values['code'].'&redirect_uri='.$callbackUri;
185 }
186
187 public function oAuthAuthorize()
188 {
189 $client = $this->createClient();
190
191 $request = $client->createRequest('POST', $this->pocketURL['oauth_authorize'],
192 [
193 'body' => json_encode([
194 'consumer_key' => $this->consumerKey,
195 'code' => $this->session->get('pocketCode'),
196 ]),
197 ]
198 );
199
200 $response = $client->send($request);
201
202 return $response->json()['access_token'];
203 }
204
205 public function import($accessToken)
206 {
207 $client = $this->createClient();
208
209 $request = $client->createRequest('POST', $this->pocketURL['get'],
210 [
211 'body' => json_encode([
212 'consumer_key' => $this->consumerKey,
213 'access_token' => $accessToken,
214 'detailType' => 'complete',
215 'state' => 'all',
216 'sort' => 'oldest',
217 ]),
218 ]
219 );
220
221 $response = $client->send($request);
222 $entries = $response->json();
223
224 $this->parsePocketEntries($entries['list']);
225
226 $this->session->getFlashBag()->add(
227 'notice',
228 $this->importedEntries.' entries imported, '.$this->skippedEntries.' already saved.'
229 );
230 }
231 }