aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas LÅ“uillet <nicolas.loeuillet@smile.fr>2015-10-20 13:58:13 +0200
committerJeremy Benoist <jeremy.benoist@gmail.com>2016-01-02 23:24:17 +0100
commit1f4408de9ed08f3b0fda45a93f1585c80feeb21d (patch)
treec8e7e05e9db85b331dde2ba5fef35796d8f3439f
parent10b40f85d664da2b3ebcfd24d6e7145c9cd90d64 (diff)
downloadwallabag-1f4408de9ed08f3b0fda45a93f1585c80feeb21d.tar.gz
wallabag-1f4408de9ed08f3b0fda45a93f1585c80feeb21d.tar.zst
wallabag-1f4408de9ed08f3b0fda45a93f1585c80feeb21d.zip
1st draft for Pocket import via API
-rw-r--r--app/AppKernel.php1
-rw-r--r--app/config/parameters.yml.dist3
-rw-r--r--app/config/routing.yml5
-rw-r--r--composer.json3
-rw-r--r--composer.lock66
-rw-r--r--src/Wallabag/CoreBundle/Tools/Utils.php11
-rw-r--r--src/Wallabag/ImportBundle/Controller/PocketController.php139
-rw-r--r--src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig16
-rw-r--r--src/Wallabag/ImportBundle/WallabagImportBundle.php9
9 files changed, 219 insertions, 34 deletions
diff --git a/app/AppKernel.php b/app/AppKernel.php
index 85edc14a..93b0201a 100644
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -31,6 +31,7 @@ class AppKernel extends Kernel
31 new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(), 31 new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
32 new Scheb\TwoFactorBundle\SchebTwoFactorBundle(), 32 new Scheb\TwoFactorBundle\SchebTwoFactorBundle(),
33 new KPhoen\RulerZBundle\KPhoenRulerZBundle(), 33 new KPhoen\RulerZBundle\KPhoenRulerZBundle(),
34 new Wallabag\ImportBundle\WallabagImportBundle(),
34 ); 35 );
35 36
36 if (in_array($this->getEnvironment(), array('dev', 'test'))) { 37 if (in_array($this->getEnvironment(), array('dev', 'test'))) {
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
index 149179c2..c0d57aa1 100644
--- a/app/config/parameters.yml.dist
+++ b/app/config/parameters.yml.dist
@@ -60,3 +60,6 @@ parameters:
60 language: en 60 language: en
61 from_email: no-reply@wallabag.org 61 from_email: no-reply@wallabag.org
62 rss_limit: 50 62 rss_limit: 50
63
64 # pocket import
65 pocket_consumer_key: 47025-85ed5e6cfd72abbb49d12db1
diff --git a/app/config/routing.yml b/app/config/routing.yml
index 0f7b61fb..91a5705f 100644
--- a/app/config/routing.yml
+++ b/app/config/routing.yml
@@ -1,3 +1,8 @@
1wallabag_import:
2 resource: "@WallabagImportBundle/Controller/"
3 type: annotation
4 prefix: /
5
1wallabag_api: 6wallabag_api:
2 resource: "@WallabagApiBundle/Resources/config/routing.yml" 7 resource: "@WallabagApiBundle/Resources/config/routing.yml"
3 prefix: / 8 prefix: /
diff --git a/composer.json b/composer.json
index bf519faf..0ba42a3e 100644
--- a/composer.json
+++ b/composer.json
@@ -59,7 +59,8 @@
59 "scheb/two-factor-bundle": "~1.4.0", 59 "scheb/two-factor-bundle": "~1.4.0",
60 "grandt/phpepub": "~4.0", 60 "grandt/phpepub": "~4.0",
61 "wallabag/php-mobi": "~1.0.0", 61 "wallabag/php-mobi": "~1.0.0",
62 "kphoen/rulerz-bundle": "~0.10" 62 "kphoen/rulerz-bundle": "~0.10",
63 "guzzlehttp/guzzle": "^5.2.0"
63 }, 64 },
64 "require-dev": { 65 "require-dev": {
65 "doctrine/doctrine-fixtures-bundle": "~2.2.0", 66 "doctrine/doctrine-fixtures-bundle": "~2.2.0",
diff --git a/composer.lock b/composer.lock
index aee96198..076dfcac 100644
--- a/composer.lock
+++ b/composer.lock
@@ -117,16 +117,16 @@
117 }, 117 },
118 { 118 {
119 "name": "doctrine/cache", 119 "name": "doctrine/cache",
120 "version": "v1.5.4", 120 "version": "v1.5.2",
121 "source": { 121 "source": {
122 "type": "git", 122 "type": "git",
123 "url": "https://github.com/doctrine/cache.git", 123 "url": "https://github.com/doctrine/cache.git",
124 "reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136" 124 "reference": "47c7128262da274f590ae6f86eb137a7a64e82af"
125 }, 125 },
126 "dist": { 126 "dist": {
127 "type": "zip", 127 "type": "zip",
128 "url": "https://api.github.com/repos/doctrine/cache/zipball/47cdc76ceb95cc591d9c79a36dc3794975b5d136", 128 "url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af",
129 "reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136", 129 "reference": "47c7128262da274f590ae6f86eb137a7a64e82af",
130 "shasum": "" 130 "shasum": ""
131 }, 131 },
132 "require": { 132 "require": {
@@ -183,7 +183,7 @@
183 "cache", 183 "cache",
184 "caching" 184 "caching"
185 ], 185 ],
186 "time": "2015-12-19 05:03:47" 186 "time": "2015-12-03 10:50:37"
187 }, 187 },
188 { 188 {
189 "name": "doctrine/collections", 189 "name": "doctrine/collections",
@@ -981,17 +981,17 @@
981 }, 981 },
982 { 982 {
983 "name": "friendsofsymfony/rest-bundle", 983 "name": "friendsofsymfony/rest-bundle",
984 "version": "1.7.6", 984 "version": "1.7.4",
985 "target-dir": "FOS/RestBundle", 985 "target-dir": "FOS/RestBundle",
986 "source": { 986 "source": {
987 "type": "git", 987 "type": "git",
988 "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git", 988 "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git",
989 "reference": "f95b2f141748e9a5e2ddae833f60c38417aee8c3" 989 "reference": "64ba918b1eb47acb5aa7fef1ce95623235b53775"
990 }, 990 },
991 "dist": { 991 "dist": {
992 "type": "zip", 992 "type": "zip",
993 "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/f95b2f141748e9a5e2ddae833f60c38417aee8c3", 993 "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/64ba918b1eb47acb5aa7fef1ce95623235b53775",
994 "reference": "f95b2f141748e9a5e2ddae833f60c38417aee8c3", 994 "reference": "64ba918b1eb47acb5aa7fef1ce95623235b53775",
995 "shasum": "" 995 "shasum": ""
996 }, 996 },
997 "require": { 997 "require": {
@@ -1063,7 +1063,7 @@
1063 "keywords": [ 1063 "keywords": [
1064 "rest" 1064 "rest"
1065 ], 1065 ],
1066 "time": "2015-12-20 13:45:30" 1066 "time": "2015-12-05 14:55:07"
1067 }, 1067 },
1068 { 1068 {
1069 "name": "friendsofsymfony/user-bundle", 1069 "name": "friendsofsymfony/user-bundle",
@@ -2313,16 +2313,16 @@
2313 }, 2313 },
2314 { 2314 {
2315 "name": "j0k3r/graby", 2315 "name": "j0k3r/graby",
2316 "version": "1.0.8", 2316 "version": "1.0.6",
2317 "source": { 2317 "source": {
2318 "type": "git", 2318 "type": "git",
2319 "url": "https://github.com/j0k3r/graby.git", 2319 "url": "https://github.com/j0k3r/graby.git",
2320 "reference": "bf152ccc6629bdd63b1e5e8b297c2912516b5f1e" 2320 "reference": "c9f5543fad60dc4efd12195733f96bb4fdb0e6e0"
2321 }, 2321 },
2322 "dist": { 2322 "dist": {
2323 "type": "zip", 2323 "type": "zip",
2324 "url": "https://api.github.com/repos/j0k3r/graby/zipball/bf152ccc6629bdd63b1e5e8b297c2912516b5f1e", 2324 "url": "https://api.github.com/repos/j0k3r/graby/zipball/c9f5543fad60dc4efd12195733f96bb4fdb0e6e0",
2325 "reference": "bf152ccc6629bdd63b1e5e8b297c2912516b5f1e", 2325 "reference": "c9f5543fad60dc4efd12195733f96bb4fdb0e6e0",
2326 "shasum": "" 2326 "shasum": ""
2327 }, 2327 },
2328 "require": { 2328 "require": {
@@ -2365,20 +2365,20 @@
2365 } 2365 }
2366 ], 2366 ],
2367 "description": "Graby helps you extract article content from web pages", 2367 "description": "Graby helps you extract article content from web pages",
2368 "time": "2015-12-24 08:28:38" 2368 "time": "2015-12-02 13:22:19"
2369 }, 2369 },
2370 { 2370 {
2371 "name": "j0k3r/graby-site-config", 2371 "name": "j0k3r/graby-site-config",
2372 "version": "1.0.11", 2372 "version": "1.0.9",
2373 "source": { 2373 "source": {
2374 "type": "git", 2374 "type": "git",
2375 "url": "https://github.com/j0k3r/graby-site-config.git", 2375 "url": "https://github.com/j0k3r/graby-site-config.git",
2376 "reference": "ac198f308beabccc97bbd35ed0daeaac63fbf1e3" 2376 "reference": "7666fed2a2cd211ef366f6fed9ccddd8e0b9e623"
2377 }, 2377 },
2378 "dist": { 2378 "dist": {
2379 "type": "zip", 2379 "type": "zip",
2380 "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/ac198f308beabccc97bbd35ed0daeaac63fbf1e3", 2380 "url": "https://api.github.com/repos/j0k3r/graby-site-config/zipball/7666fed2a2cd211ef366f6fed9ccddd8e0b9e623",
2381 "reference": "ac198f308beabccc97bbd35ed0daeaac63fbf1e3", 2381 "reference": "7666fed2a2cd211ef366f6fed9ccddd8e0b9e623",
2382 "shasum": "" 2382 "shasum": ""
2383 }, 2383 },
2384 "require": { 2384 "require": {
@@ -2401,7 +2401,7 @@
2401 } 2401 }
2402 ], 2402 ],
2403 "description": "Graby site config files", 2403 "description": "Graby site config files",
2404 "time": "2015-12-23 22:52:15" 2404 "time": "2015-12-03 19:49:20"
2405 }, 2405 },
2406 { 2406 {
2407 "name": "j0k3r/php-readability", 2407 "name": "j0k3r/php-readability",
@@ -3138,7 +3138,9 @@
3138 "authors": [ 3138 "authors": [
3139 { 3139 {
3140 "name": "S.C. Chen", 3140 "name": "S.C. Chen",
3141 "email": "me578022@gmail.com" 3141 "email": "me578022@gmail.com",
3142 "homepage": "http://simplehtmldom.sourceforge.net/",
3143 "role": "Lead Developer"
3142 } 3144 }
3143 ], 3145 ],
3144 "description": "Composer package that gives you access to and (unlike all the others at this time) autoloads S.C. Chen's PHP Simple HTML DOM Parser Library", 3146 "description": "Composer package that gives you access to and (unlike all the others at this time) autoloads S.C. Chen's PHP Simple HTML DOM Parser Library",
@@ -3765,16 +3767,16 @@
3765 }, 3767 },
3766 { 3768 {
3767 "name": "scheb/two-factor-bundle", 3769 "name": "scheb/two-factor-bundle",
3768 "version": "v1.4.7", 3770 "version": "v1.5.0",
3769 "source": { 3771 "source": {
3770 "type": "git", 3772 "type": "git",
3771 "url": "https://github.com/scheb/two-factor-bundle.git", 3773 "url": "https://github.com/scheb/two-factor-bundle.git",
3772 "reference": "ef6830dbbf62b22efd335db8f64bf0f51d4284a2" 3774 "reference": "b0da3a85b181237c3bebde88c99b18745313360b"
3773 }, 3775 },
3774 "dist": { 3776 "dist": {
3775 "type": "zip", 3777 "type": "zip",
3776 "url": "https://api.github.com/repos/scheb/two-factor-bundle/zipball/ef6830dbbf62b22efd335db8f64bf0f51d4284a2", 3778 "url": "https://api.github.com/repos/scheb/two-factor-bundle/zipball/b0da3a85b181237c3bebde88c99b18745313360b",
3777 "reference": "ef6830dbbf62b22efd335db8f64bf0f51d4284a2", 3779 "reference": "b0da3a85b181237c3bebde88c99b18745313360b",
3778 "shasum": "" 3780 "shasum": ""
3779 }, 3781 },
3780 "require": { 3782 "require": {
@@ -3810,7 +3812,7 @@
3810 "two-factor", 3812 "two-factor",
3811 "two-step" 3813 "two-step"
3812 ], 3814 ],
3813 "time": "2015-08-25 19:58:00" 3815 "time": "2015-11-15 13:31:23"
3814 }, 3816 },
3815 { 3817 {
3816 "name": "sensio/distribution-bundle", 3818 "name": "sensio/distribution-bundle",
@@ -5437,16 +5439,16 @@
5437 }, 5439 },
5438 { 5440 {
5439 "name": "phpunit/phpunit", 5441 "name": "phpunit/phpunit",
5440 "version": "4.8.21", 5442 "version": "4.8.20",
5441 "source": { 5443 "source": {
5442 "type": "git", 5444 "type": "git",
5443 "url": "https://github.com/sebastianbergmann/phpunit.git", 5445 "url": "https://github.com/sebastianbergmann/phpunit.git",
5444 "reference": "ea76b17bced0500a28098626b84eda12dbcf119c" 5446 "reference": "7438c43bc2bbb2febe1723eb595b1c49283a26ad"
5445 }, 5447 },
5446 "dist": { 5448 "dist": {
5447 "type": "zip", 5449 "type": "zip",
5448 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea76b17bced0500a28098626b84eda12dbcf119c", 5450 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7438c43bc2bbb2febe1723eb595b1c49283a26ad",
5449 "reference": "ea76b17bced0500a28098626b84eda12dbcf119c", 5451 "reference": "7438c43bc2bbb2febe1723eb595b1c49283a26ad",
5450 "shasum": "" 5452 "shasum": ""
5451 }, 5453 },
5452 "require": { 5454 "require": {
@@ -5455,7 +5457,7 @@
5455 "ext-pcre": "*", 5457 "ext-pcre": "*",
5456 "ext-reflection": "*", 5458 "ext-reflection": "*",
5457 "ext-spl": "*", 5459 "ext-spl": "*",
5458 "php": ">=5.3.3", 5460 "php": "~5.3.3|~5.4|~5.5|~5.6",
5459 "phpspec/prophecy": "^1.3.1", 5461 "phpspec/prophecy": "^1.3.1",
5460 "phpunit/php-code-coverage": "~2.1", 5462 "phpunit/php-code-coverage": "~2.1",
5461 "phpunit/php-file-iterator": "~1.4", 5463 "phpunit/php-file-iterator": "~1.4",
@@ -5505,7 +5507,7 @@
5505 "testing", 5507 "testing",
5506 "xunit" 5508 "xunit"
5507 ], 5509 ],
5508 "time": "2015-12-12 07:45:58" 5510 "time": "2015-12-10 07:48:52"
5509 }, 5511 },
5510 { 5512 {
5511 "name": "phpunit/phpunit-mock-objects", 5513 "name": "phpunit/phpunit-mock-objects",
diff --git a/src/Wallabag/CoreBundle/Tools/Utils.php b/src/Wallabag/CoreBundle/Tools/Utils.php
index a16baca9..b146d98b 100644
--- a/src/Wallabag/CoreBundle/Tools/Utils.php
+++ b/src/Wallabag/CoreBundle/Tools/Utils.php
@@ -27,6 +27,15 @@ class Utils
27 } 27 }
28 28
29 /** 29 /**
30 * @param $words
31 * @return float
32 */
33 public static function convertWordsToMinutes($words)
34 {
35 return floor($words / 200);
36 }
37
38 /**
30 * For a given text, we calculate reading time for an article 39 * For a given text, we calculate reading time for an article
31 * based on 200 words per minute. 40 * based on 200 words per minute.
32 * 41 *
@@ -36,6 +45,6 @@ class Utils
36 */ 45 */
37 public static function getReadingTime($text) 46 public static function getReadingTime($text)
38 { 47 {
39 return floor(str_word_count(strip_tags($text)) / 200); 48 return self::convertWordsToMinutes(str_word_count(strip_tags($text)));
40 } 49 }
41} 50}
diff --git a/src/Wallabag/ImportBundle/Controller/PocketController.php b/src/Wallabag/ImportBundle/Controller/PocketController.php
new file mode 100644
index 00000000..ffd0c9ab
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Controller/PocketController.php
@@ -0,0 +1,139 @@
1<?php
2
3namespace Wallabag\ImportBundle\Controller;
4
5use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
7use Symfony\Component\HttpFoundation\Request;
8use GuzzleHttp\Client;
9use Wallabag\CoreBundle\Entity\Entry;
10use Wallabag\CoreBundle\Tools\Utils;
11
12class PocketController extends Controller
13{
14 /**
15 * @Route("/import", name="import")
16 */
17 public function importAction()
18 {
19 return $this->render('WallabagImportBundle:Pocket:index.html.twig', array());
20 }
21
22 /**
23 * Create a new Client.
24 *
25 * @return Client
26 */
27 private function createClient()
28 {
29 return new Client([
30 'defaults' => [
31 'headers' => [
32 'content-type' => 'application/json',
33 'X-Accept' => 'application/json',
34 ],
35 ],
36 ]);
37 }
38
39 /**
40 * @Route("/auth-pocket", name="authpocket")
41 */
42 public function authAction()
43 {
44 $client = $this->createClient();
45 $request = $client->createRequest('POST', 'https://getpocket.com/v3/oauth/request',
46 [
47 'body' => json_encode([
48 'consumer_key' => $this->container->getParameter('pocket_consumer_key'),
49 'redirect_uri' => $this->generateUrl('import', array(), true),
50 ]),
51 ]
52 );
53
54 $response = $client->send($request);
55 $values = $response->json();
56 $code = $values['code'];
57
58 // store code in session for callback method
59 $session = $this->get('session');
60 $session->set('pocketCode', $code);
61
62 $url = 'https://getpocket.com/auth/authorize?request_token='.$code.'&redirect_uri='.$this->generateUrl('callbackpocket', array(), true);
63
64 return $this->redirect($url, 301);
65 }
66
67 /**
68 * @Route("/callback-pocket", name="callbackpocket")
69 */
70 public function callbackAction()
71 {
72 $client = $this->createClient();
73
74 $request = $client->createRequest('POST', 'https://getpocket.com/v3/oauth/authorize',
75 [
76 'body' => json_encode([
77 'consumer_key' => $this->container->getParameter('pocket_consumer_key'),
78 'code' => $this->get('session')->get('pocketCode'),
79 ]),
80 ]
81 );
82
83 $response = $client->send($request);
84 $values = $response->json();
85 $accessToken = $values['access_token'];
86
87 $request = $client->createRequest('POST', 'https://getpocket.com/v3/get',
88 [
89 'body' => json_encode([
90 'consumer_key' => $this->container->getParameter('pocket_consumer_key'),
91 'access_token' => $accessToken,
92 'detailType' => 'complete',
93 ]),
94 ]
95 );
96
97 $response = $client->send($request);
98 $entries = $response->json();
99
100 $this->parsePocketEntries($entries['list']);
101
102 $this->get('session')->getFlashBag()->add(
103 'notice',
104 count($entries['list']).' entries imported'
105 );
106
107 return $this->redirect($this->generateUrl('homepage'));
108 }
109
110 /**
111 * @param $entries
112 */
113 private function parsePocketEntries($entries)
114 {
115 $em = $this->getDoctrine()->getManager();
116
117 foreach ($entries as $entry) {
118 $newEntry = new Entry($this->getUser());
119 $newEntry->setUrl($entry['given_url']);
120 $newEntry->setTitle(isset($entry['resolved_title']) ? $entry['resolved_title'] : (isset($entry['given_title']) ? $entry['given_title'] : 'Untitled'));
121
122 if (isset($entry['excerpt'])) {
123 $newEntry->setContent($entry['excerpt']);
124 }
125
126 if (isset($entry['has_image']) && $entry['has_image'] > 0) {
127 $newEntry->setPreviewPicture($entry['image']['src']);
128 }
129
130 if (isset($entry['word_count'])) {
131 $newEntry->setReadingTime(Utils::convertWordsToMinutes($entry['word_count']));
132 }
133
134 $em->persist($newEntry);
135 }
136
137 $em->flush();
138 }
139}
diff --git a/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig
new file mode 100644
index 00000000..d47dd8d5
--- /dev/null
+++ b/src/Wallabag/ImportBundle/Resources/views/Pocket/index.html.twig
@@ -0,0 +1,16 @@
1{% extends "WallabagCoreBundle::layout.html.twig" %}
2{% block title %}{% trans %}import{% endtrans %}{% endblock %}
3
4{% block content %}
5
6<div class="row">
7 <div class="col s12">
8 <div class="card-panel settings">
9 {% trans %}You can import your data from your Pocket account. You just have to click on the below button and authorize the application to connect to getpocket.com.{% endtrans %}
10 <form method="post" action="{{ path('authpocket') }}">
11 <input type="submit" value="Connect to Pocket" />
12 </form>
13 </div>
14 </div>
15</div>
16{% endblock %}
diff --git a/src/Wallabag/ImportBundle/WallabagImportBundle.php b/src/Wallabag/ImportBundle/WallabagImportBundle.php
new file mode 100644
index 00000000..d00f2fe9
--- /dev/null
+++ b/src/Wallabag/ImportBundle/WallabagImportBundle.php
@@ -0,0 +1,9 @@
1<?php
2
3namespace Wallabag\ImportBundle;
4
5use Symfony\Component\HttpKernel\Bundle\Bundle;
6
7class WallabagImportBundle extends Bundle
8{
9}