aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/CoreBundle/Helper/DownloadImages.php21
-rw-r--r--src/Wallabag/CoreBundle/Helper/HttpClientFactory.php47
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml11
-rw-r--r--src/Wallabag/ImportBundle/Import/PocketImport.php90
-rw-r--r--src/Wallabag/ImportBundle/Resources/config/services.yml8
5 files changed, 92 insertions, 85 deletions
diff --git a/src/Wallabag/CoreBundle/Helper/DownloadImages.php b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
index c1645e45..e5749060 100644
--- a/src/Wallabag/CoreBundle/Helper/DownloadImages.php
+++ b/src/Wallabag/CoreBundle/Helper/DownloadImages.php
@@ -2,8 +2,13 @@
2 2
3namespace Wallabag\CoreBundle\Helper; 3namespace Wallabag\CoreBundle\Helper;
4 4
5use GuzzleHttp\Client; 5use Http\Client\Common\HttpMethodsClient;
6use GuzzleHttp\Message\Response; 6use Http\Client\Common\Plugin\ErrorPlugin;
7use Http\Client\Common\PluginClient;
8use Http\Client\HttpClient;
9use Http\Discovery\MessageFactoryDiscovery;
10use Http\Message\MessageFactory;
11use Psr\Http\Message\ResponseInterface;
7use Psr\Log\LoggerInterface; 12use Psr\Log\LoggerInterface;
8use Symfony\Component\DomCrawler\Crawler; 13use Symfony\Component\DomCrawler\Crawler;
9use Symfony\Component\Finder\Finder; 14use Symfony\Component\Finder\Finder;
@@ -19,9 +24,9 @@ class DownloadImages
19 private $mimeGuesser; 24 private $mimeGuesser;
20 private $wallabagUrl; 25 private $wallabagUrl;
21 26
22 public function __construct(Client $client, $baseFolder, $wallabagUrl, LoggerInterface $logger) 27 public function __construct(HttpClient $client, $baseFolder, $wallabagUrl, LoggerInterface $logger, MessageFactory $messageFactory = null)
23 { 28 {
24 $this->client = $client; 29 $this->client = new HttpMethodsClient(new PluginClient($client, [new ErrorPlugin()]), $messageFactory ?: MessageFactoryDiscovery::find());
25 $this->baseFolder = $baseFolder; 30 $this->baseFolder = $baseFolder;
26 $this->wallabagUrl = rtrim($wallabagUrl, '/'); 31 $this->wallabagUrl = rtrim($wallabagUrl, '/');
27 $this->logger = $logger; 32 $this->logger = $logger;
@@ -135,7 +140,7 @@ class DownloadImages
135 $localPath = $folderPath . '/' . $hashImage . '.' . $ext; 140 $localPath = $folderPath . '/' . $hashImage . '.' . $ext;
136 141
137 try { 142 try {
138 $im = imagecreatefromstring($res->getBody()); 143 $im = imagecreatefromstring((string) $res->getBody());
139 } catch (\Exception $e) { 144 } catch (\Exception $e) {
140 $im = false; 145 $im = false;
141 } 146 }
@@ -306,14 +311,14 @@ class DownloadImages
306 /** 311 /**
307 * Retrieve and validate the extension from the response of the url of the image. 312 * Retrieve and validate the extension from the response of the url of the image.
308 * 313 *
309 * @param Response $res Guzzle Response 314 * @param ResponseInterface $res Http Response
310 * @param string $imagePath Path from the src image from the content (used for log only) 315 * @param string $imagePath Path from the src image from the content (used for log only)
311 * 316 *
312 * @return string|false Extension name or false if validation failed 317 * @return string|false Extension name or false if validation failed
313 */ 318 */
314 private function getExtensionFromResponse(Response $res, $imagePath) 319 private function getExtensionFromResponse(ResponseInterface $res, $imagePath)
315 { 320 {
316 $ext = $this->mimeGuesser->guess($res->getHeader('content-type')); 321 $ext = $this->mimeGuesser->guess(current($res->getHeader('content-type')));
317 $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]); 322 $this->logger->debug('DownloadImages: Checking extension', ['ext' => $ext, 'header' => $res->getHeader('content-type')]);
318 323
319 // ok header doesn't have the extension, try a different way 324 // ok header doesn't have the extension, try a different way
diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php
index 4602a684..4899d3d4 100644
--- a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php
+++ b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php
@@ -2,16 +2,18 @@
2 2
3namespace Wallabag\CoreBundle\Helper; 3namespace Wallabag\CoreBundle\Helper;
4 4
5use Graby\Ring\Client\SafeCurlHandler; 5use GuzzleHttp\Client as GuzzleClient;
6use GuzzleHttp\Client;
7use GuzzleHttp\Cookie\CookieJar; 6use GuzzleHttp\Cookie\CookieJar;
8use GuzzleHttp\Event\SubscriberInterface; 7use GuzzleHttp\Event\SubscriberInterface;
8use Http\Adapter\Guzzle5\Client as GuzzleAdapter;
9use Psr\Log\LoggerInterface; 9use Psr\Log\LoggerInterface;
10use Http\Client\HttpClient;
11use Http\HttplugBundle\ClientFactory\ClientFactory;
10 12
11/** 13/**
12 * Builds and configures the Guzzle HTTP client. 14 * Builds and configures the HTTP client.
13 */ 15 */
14class HttpClientFactory 16class HttpClientFactory implements ClientFactory
15{ 17{
16 /** @var [\GuzzleHttp\Event\SubscriberInterface] */ 18 /** @var [\GuzzleHttp\Event\SubscriberInterface] */
17 private $subscribers = []; 19 private $subscribers = [];
@@ -37,35 +39,38 @@ class HttpClientFactory
37 } 39 }
38 40
39 /** 41 /**
40 * @return \GuzzleHttp\Client|null 42 * Adds a subscriber to the HTTP client.
43 *
44 * @param SubscriberInterface $subscriber
45 */
46 public function addSubscriber(SubscriberInterface $subscriber)
47 {
48 $this->subscribers[] = $subscriber;
49 }
50
51 /**
52 * Input an array of configuration to be able to create a HttpClient.
53 *
54 * @param array $config
55 *
56 * @return HttpClient
41 */ 57 */
42 public function buildHttpClient() 58 public function createClient(array $config = [])
43 { 59 {
44 $this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]); 60 $this->logger->log('debug', 'Restricted access config enabled?', ['enabled' => (int) $this->restrictedAccess]);
45 61
46 if (0 === (int) $this->restrictedAccess) { 62 if (0 === (int) $this->restrictedAccess) {
47 return; 63 return new GuzzleAdapter(new GuzzleClient());
48 } 64 }
49 65
50 // we clear the cookie to avoid websites who use cookies for analytics 66 // we clear the cookie to avoid websites who use cookies for analytics
51 $this->cookieJar->clear(); 67 $this->cookieJar->clear();
52 // need to set the (shared) cookie jar 68 // need to set the (shared) cookie jar
53 $client = new Client(['handler' => new SafeCurlHandler(), 'defaults' => ['cookies' => $this->cookieJar]]); 69 $guzzle = new GuzzleClient(['defaults' => ['cookies' => $this->cookieJar]]);
54
55 foreach ($this->subscribers as $subscriber) { 70 foreach ($this->subscribers as $subscriber) {
56 $client->getEmitter()->attach($subscriber); 71 $guzzle->getEmitter()->attach($subscriber);
57 } 72 }
58 73
59 return $client; 74 return new GuzzleAdapter($guzzle);
60 }
61
62 /**
63 * Adds a subscriber to the HTTP client.
64 *
65 * @param SubscriberInterface $subscriber
66 */
67 public function addSubscriber(SubscriberInterface $subscriber)
68 {
69 $this->subscribers[] = $subscriber;
70 } 75 }
71} 76}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 280d779d..31986951 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -42,7 +42,7 @@ services:
42 - 42 -
43 error_message: '%wallabag_core.fetching_error_message%' 43 error_message: '%wallabag_core.fetching_error_message%'
44 error_message_title: '%wallabag_core.fetching_error_message_title%' 44 error_message_title: '%wallabag_core.fetching_error_message_title%'
45 - "@wallabag_core.guzzle.http_client" 45 - "@wallabag_core.http_client"
46 - "@wallabag_core.graby.config_builder" 46 - "@wallabag_core.graby.config_builder"
47 calls: 47 calls:
48 - [ setLogger, [ "@logger" ] ] 48 - [ setLogger, [ "@logger" ] ]
@@ -55,9 +55,8 @@ services:
55 - {} 55 - {}
56 - "@logger" 56 - "@logger"
57 57
58 wallabag_core.guzzle.http_client: 58 wallabag_core.http_client:
59 class: GuzzleHttp\ClientInterface 59 alias: 'httplug.client.wallabag_core'
60 factory: ["@wallabag_core.guzzle.http_client_factory", buildHttpClient]
61 60
62 wallabag_core.guzzle_authenticator.config_builder: 61 wallabag_core.guzzle_authenticator.config_builder:
63 class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder 62 class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder
@@ -73,7 +72,7 @@ services:
73 bd_guzzle_site_authenticator.site_config_builder: 72 bd_guzzle_site_authenticator.site_config_builder:
74 alias: wallabag_core.guzzle_authenticator.config_builder 73 alias: wallabag_core.guzzle_authenticator.config_builder
75 74
76 wallabag_core.guzzle.http_client_factory: 75 wallabag_core.http_client_factory:
77 class: Wallabag\CoreBundle\Helper\HttpClientFactory 76 class: Wallabag\CoreBundle\Helper\HttpClientFactory
78 arguments: 77 arguments:
79 - "@wallabag_core.guzzle.cookie_jar" 78 - "@wallabag_core.guzzle.cookie_jar"
@@ -212,7 +211,7 @@ services:
212 - "@logger" 211 - "@logger"
213 212
214 wallabag_core.entry.download_images.client: 213 wallabag_core.entry.download_images.client:
215 class: GuzzleHttp\Client 214 alias: 'httplug.client.wallabag_core.entry.download_images'
216 215
217 wallabag_core.helper.crypto_proxy: 216 wallabag_core.helper.crypto_proxy:
218 class: Wallabag\CoreBundle\Helper\CryptoProxy 217 class: Wallabag\CoreBundle\Helper\CryptoProxy
diff --git a/src/Wallabag/ImportBundle/Import/PocketImport.php b/src/Wallabag/ImportBundle/Import/PocketImport.php
index a39d8156..9467fae2 100644
--- a/src/Wallabag/ImportBundle/Import/PocketImport.php
+++ b/src/Wallabag/ImportBundle/Import/PocketImport.php
@@ -2,13 +2,22 @@
2 2
3namespace Wallabag\ImportBundle\Import; 3namespace Wallabag\ImportBundle\Import;
4 4
5use GuzzleHttp\Client; 5use Http\Client\Common\HttpMethodsClient;
6use GuzzleHttp\Exception\RequestException; 6use Http\Client\Common\Plugin\ErrorPlugin;
7use Http\Client\Common\PluginClient;
8use Http\Client\HttpClient;
9use Http\Discovery\MessageFactoryDiscovery;
10use Http\Message\MessageFactory;
11use Http\Client\Exception\RequestException;
7use Wallabag\CoreBundle\Entity\Entry; 12use Wallabag\CoreBundle\Entity\Entry;
13use Psr\Http\Message\ResponseInterface;
8 14
9class PocketImport extends AbstractImport 15class PocketImport extends AbstractImport
10{ 16{
11 const NB_ELEMENTS = 5000; 17 const NB_ELEMENTS = 5000;
18 /**
19 * @var HttpMethodsClient
20 */
12 private $client; 21 private $client;
13 private $accessToken; 22 private $accessToken;
14 23
@@ -55,24 +64,18 @@ class PocketImport extends AbstractImport
55 */ 64 */
56 public function getRequestToken($redirectUri) 65 public function getRequestToken($redirectUri)
57 { 66 {
58 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/request',
59 [
60 'body' => json_encode([
61 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
62 'redirect_uri' => $redirectUri,
63 ]),
64 ]
65 );
66
67 try { 67 try {
68 $response = $this->client->send($request); 68 $response = $this->client->post('https://getpocket.com/v3/oauth/request', [], json_encode([
69 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
70 'redirect_uri' => $redirectUri,
71 ]));
69 } catch (RequestException $e) { 72 } catch (RequestException $e) {
70 $this->logger->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]); 73 $this->logger->error(sprintf('PocketImport: Failed to request token: %s', $e->getMessage()), ['exception' => $e]);
71 74
72 return false; 75 return false;
73 } 76 }
74 77
75 return $response->json()['code']; 78 return $this->jsonDecode($response)['code'];
76 } 79 }
77 80
78 /** 81 /**
@@ -85,24 +88,19 @@ class PocketImport extends AbstractImport
85 */ 88 */
86 public function authorize($code) 89 public function authorize($code)
87 { 90 {
88 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/oauth/authorize',
89 [
90 'body' => json_encode([
91 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
92 'code' => $code,
93 ]),
94 ]
95 );
96 91
97 try { 92 try {
98 $response = $this->client->send($request); 93 $response = $this->client->post('https://getpocket.com/v3/oauth/authorize', [], json_encode([
94 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
95 'code' => $code,
96 ]));
99 } catch (RequestException $e) { 97 } catch (RequestException $e) {
100 $this->logger->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]); 98 $this->logger->error(sprintf('PocketImport: Failed to authorize client: %s', $e->getMessage()), ['exception' => $e]);
101 99
102 return false; 100 return false;
103 } 101 }
104 102
105 $this->accessToken = $response->json()['access_token']; 103 $this->accessToken = $this->jsonDecode($response)['access_token'];
106 104
107 return true; 105 return true;
108 } 106 }
@@ -114,29 +112,23 @@ class PocketImport extends AbstractImport
114 { 112 {
115 static $run = 0; 113 static $run = 0;
116 114
117 $request = $this->client->createRequest('POST', 'https://getpocket.com/v3/get',
118 [
119 'body' => json_encode([
120 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
121 'access_token' => $this->accessToken,
122 'detailType' => 'complete',
123 'state' => 'all',
124 'sort' => 'newest',
125 'count' => self::NB_ELEMENTS,
126 'offset' => $offset,
127 ]),
128 ]
129 );
130
131 try { 115 try {
132 $response = $this->client->send($request); 116 $response = $this->client->post('https://getpocket.com/v3/get', [], json_encode([
117 'consumer_key' => $this->user->getConfig()->getPocketConsumerKey(),
118 'access_token' => $this->accessToken,
119 'detailType' => 'complete',
120 'state' => 'all',
121 'sort' => 'newest',
122 'count' => self::NB_ELEMENTS,
123 'offset' => $offset,
124 ]));
133 } catch (RequestException $e) { 125 } catch (RequestException $e) {
134 $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]); 126 $this->logger->error(sprintf('PocketImport: Failed to import: %s', $e->getMessage()), ['exception' => $e]);
135 127
136 return false; 128 return false;
137 } 129 }
138 130
139 $entries = $response->json(); 131 $entries = $this->jsonDecode($response);
140 132
141 if ($this->producer) { 133 if ($this->producer) {
142 $this->parseEntriesForProducer($entries['list']); 134 $this->parseEntriesForProducer($entries['list']);
@@ -159,13 +151,14 @@ class PocketImport extends AbstractImport
159 } 151 }
160 152
161 /** 153 /**
162 * Set the Guzzle client. 154 * Set the Http client.
163 * 155 *
164 * @param Client $client 156 * @param HttpClient $client
157 * @param MessageFactory|null $messageFactory
165 */ 158 */
166 public function setClient(Client $client) 159 public function setClient(HttpClient $client, MessageFactory $messageFactory = null)
167 { 160 {
168 $this->client = $client; 161 $this->client = new HttpMethodsClient(new PluginClient($client, [new ErrorPlugin()]), $messageFactory ?: MessageFactoryDiscovery::find());
169 } 162 }
170 163
171 /** 164 /**
@@ -252,4 +245,15 @@ class PocketImport extends AbstractImport
252 245
253 return $importedEntry; 246 return $importedEntry;
254 } 247 }
248
249 protected function jsonDecode(ResponseInterface $response)
250 {
251 $data = \json_decode((string) $response->getBody(), true);
252
253 if (JSON_ERROR_NONE !== json_last_error()) {
254 throw new \InvalidArgumentException('Unable to parse JSON data: ' . json_last_error_msg());
255 }
256
257 return $data;
258 }
255} 259}
diff --git a/src/Wallabag/ImportBundle/Resources/config/services.yml b/src/Wallabag/ImportBundle/Resources/config/services.yml
index 2dd7dff8..973c0d03 100644
--- a/src/Wallabag/ImportBundle/Resources/config/services.yml
+++ b/src/Wallabag/ImportBundle/Resources/config/services.yml
@@ -7,13 +7,7 @@ services:
7 class: Wallabag\ImportBundle\Import\ImportChain 7 class: Wallabag\ImportBundle\Import\ImportChain
8 8
9 wallabag_import.pocket.client: 9 wallabag_import.pocket.client:
10 class: GuzzleHttp\Client 10 alias: 'httplug.client.wallabag_import.pocket.client'
11 arguments:
12 -
13 defaults:
14 headers:
15 content-type: "application/json"
16 X-Accept: "application/json"
17 11
18 wallabag_import.pocket.import: 12 wallabag_import.pocket.import:
19 class: Wallabag\ImportBundle\Import\PocketImport 13 class: Wallabag\ImportBundle\Import\PocketImport