Merge lp:~marcustomlinson/unity-scope-vimeo/request_token_from_run into lp:unity-scope-vimeo

Proposed by Marcus Tomlinson
Status: Merged
Merged at revision: 83
Proposed branch: lp:~marcustomlinson/unity-scope-vimeo/request_token_from_run
Merge into: lp:unity-scope-vimeo
Diff against target: 475 lines (+126/-146)
7 files modified
CMakeLists.txt (+1/-1)
include/vimeo/api/client.h (+4/-2)
include/vimeo/scope/query.h (+2/-1)
include/vimeo/scope/scope.h (+0/-18)
src/vimeo/api/client.cpp (+112/-15)
src/vimeo/scope/query.cpp (+5/-4)
src/vimeo/scope/scope.cpp (+2/-105)
To merge this branch: bzr merge lp:~marcustomlinson/unity-scope-vimeo/request_token_from_run
Reviewer Review Type Date Requested Status
Unity API Team Pending
Review via email: mp+243650@code.launchpad.net

Commit message

Create one OnlineAccountClient instance and pass it into Query and Preview objects. This instance is then used by an internal Client object to keep its config up to date (by refreshing the service statuses each time the token is needed).

This way the config can be completely encapsulated within Client, and Client can be encapsulated within Query and Preview.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-11-18 17:34:05 +0000
+++ CMakeLists.txt 2014-12-04 12:41:10 +0000
@@ -49,7 +49,7 @@
49 ${SCOPE_INCLUDE_DIRS}49 ${SCOPE_INCLUDE_DIRS}
50)50)
5151
52set(SCOPE_VERSION "1.0.1-${BZR_REVNO}")52set(SCOPE_VERSION "1.0.2-${BZR_REVNO}")
53set(CMAKE_INSTALL_PREFIX /)53set(CMAKE_INSTALL_PREFIX /)
54set(SCOPE_NAME "com.ubuntu.scopes.vimeo")54set(SCOPE_NAME "com.ubuntu.scopes.vimeo")
55set(SCOPE_INSTALL_NAME "${SCOPE_NAME}_vimeo")55set(SCOPE_INSTALL_NAME "${SCOPE_NAME}_vimeo")
5656
=== modified file 'include/vimeo/api/client.h'
--- include/vimeo/api/client.h 2014-11-17 12:44:51 +0000
+++ include/vimeo/api/client.h 2014-12-04 12:41:10 +0000
@@ -23,6 +23,8 @@
23#include <vimeo/api/config.h>23#include <vimeo/api/config.h>
24#include <vimeo/api/video.h>24#include <vimeo/api/video.h>
2525
26#include <unity/scopes/OnlineAccountClient.h>
27
26#include <atomic>28#include <atomic>
27#include <deque>29#include <deque>
28#include <future>30#include <future>
@@ -44,7 +46,7 @@
4446
45 typedef std::deque<Video::Ptr> VideoList;47 typedef std::deque<Video::Ptr> VideoList;
4648
47 Client(Config::Ptr config);49 Client(std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client);
4850
49 virtual ~Client() = default;51 virtual ~Client() = default;
5052
@@ -58,7 +60,7 @@
5860
59 virtual void cancel();61 virtual void cancel();
6062
61 virtual Config::Ptr config();63 virtual bool authenticated();
6264
63protected:65protected:
64 class Priv;66 class Priv;
6567
=== modified file 'include/vimeo/scope/query.h'
--- include/vimeo/scope/query.h 2014-06-25 14:41:07 +0000
+++ include/vimeo/scope/query.h 2014-12-04 12:41:10 +0000
@@ -30,7 +30,8 @@
30class Query: public unity::scopes::SearchQueryBase {30class Query: public unity::scopes::SearchQueryBase {
31public:31public:
32 Query(const unity::scopes::CannedQuery &query,32 Query(const unity::scopes::CannedQuery &query,
33 const unity::scopes::SearchMetadata &metadata, vimeo::api::Config::Ptr config);33 const unity::scopes::SearchMetadata &metadata,
34 std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client);
3435
35 ~Query() = default;36 ~Query() = default;
3637
3738
=== modified file 'include/vimeo/scope/scope.h'
--- include/vimeo/scope/scope.h 2014-11-03 10:04:16 +0000
+++ include/vimeo/scope/scope.h 2014-12-04 12:41:10 +0000
@@ -19,8 +19,6 @@
19#ifndef VIMEO_SCOPE_SCOPE_H_19#ifndef VIMEO_SCOPE_SCOPE_H_
20#define VIMEO_SCOPE_SCOPE_H_20#define VIMEO_SCOPE_SCOPE_H_
2121
22#include <vimeo/api/config.h>
23
24#include <unity/scopes/ScopeBase.h>22#include <unity/scopes/ScopeBase.h>
25#include <unity/scopes/OnlineAccountClient.h>23#include <unity/scopes/OnlineAccountClient.h>
26#include <unity/scopes/QueryBase.h>24#include <unity/scopes/QueryBase.h>
@@ -28,8 +26,6 @@
28#include <unity/scopes/QueryBase.h>26#include <unity/scopes/QueryBase.h>
29#include <unity/scopes/PreviewQueryBase.h>27#include <unity/scopes/PreviewQueryBase.h>
3028
31#include <condition_variable>
32
33namespace vimeo {29namespace vimeo {
3430
35namespace scope {31namespace scope {
@@ -48,20 +44,6 @@
48 unity::scopes::SearchMetadata const&) override;44 unity::scopes::SearchMetadata const&) override;
4945
50protected:46protected:
51 void anonymous_login();
52
53 void service_update(unity::scopes::OnlineAccountClient::ServiceStatus const& status);
54
55 void update_config();
56
57 void init_config();
58
59 vimeo::api::Config::Ptr config_;
60
61 std::mutex config_mutex_;
62
63 std::condition_variable config_cond_;
64
65 std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client_;47 std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client_;
66};48};
6749
6850
=== modified file 'src/vimeo/api/client.cpp'
--- src/vimeo/api/client.cpp 2014-11-17 12:54:17 +0000
+++ src/vimeo/api/client.cpp 2014-12-04 12:41:10 +0000
@@ -17,7 +17,10 @@
17 */17 */
1818
19#include <vimeo/api/client.h>19#include <vimeo/api/client.h>
20#include <vimeo/api/login.h>
2021
22#include <boost/filesystem/operations.hpp>
23#include <boost/filesystem/path.hpp>
21#include <boost/iostreams/filtering_stream.hpp>24#include <boost/iostreams/filtering_stream.hpp>
22#include <boost/iostreams/filter/gzip.hpp>25#include <boost/iostreams/filter/gzip.hpp>
23#include <core/net/error.h>26#include <core/net/error.h>
@@ -26,7 +29,10 @@
26#include <core/net/http/response.h>29#include <core/net/http/response.h>
27#include <json/json.h>30#include <json/json.h>
2831
32#include <fstream>
33
29namespace http = core::net::http;34namespace http = core::net::http;
35namespace fs = boost::filesystem;
30namespace io = boost::iostreams;36namespace io = boost::iostreams;
31namespace json = Json;37namespace json = Json;
32namespace net = core::net;38namespace net = core::net;
@@ -34,6 +40,9 @@
34using namespace vimeo::api;40using namespace vimeo::api;
35using namespace std;41using namespace std;
3642
43static const char* CLIENT_ID = "b6758ff9f929cdb9f45a8477732bdbc4c6a89c7e";
44static const char* CLIENT_SECRET = "a3222f38f799b3b528e29418fe062c02c677a249";
45
37namespace {46namespace {
3847
39template<typename T>48template<typename T>
@@ -50,9 +59,9 @@
5059
51class Client::Priv {60class Client::Priv {
52public:61public:
53 Priv(Config::Ptr config) :62 Priv(std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client) :
54 client_(http::make_client()), worker_ { [this]() {client_->run();} }, config_(63 client_(http::make_client()), worker_ { [this]() {client_->run();} },
55 config), cancelled_(false) {64 oa_client_(oa_client), cancelled_(false) {
56 }65 }
5766
58 ~Priv() {67 ~Priv() {
@@ -66,31 +75,36 @@
6675
67 std::thread worker_;76 std::thread worker_;
6877
69 Config::Ptr config_;78 Config config_;
79 std::mutex config_mutex_;
80
81 std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client_;
7082
71 std::atomic<bool> cancelled_;83 std::atomic<bool> cancelled_;
7284
73 void get(const net::Uri::Path &path,85 void get(const net::Uri::Path &path,
74 const net::Uri::QueryParameters &parameters,86 const net::Uri::QueryParameters &parameters,
75 http::Request::Handler &handler) {87 http::Request::Handler &handler) {
88 std::lock_guard<std::mutex> lock(config_mutex_);
89 update_config();
7690
77 http::Request::Configuration configuration;91 http::Request::Configuration configuration;
78 net::Uri::QueryParameters complete_parameters(parameters);92 net::Uri::QueryParameters complete_parameters(parameters);
7993
80 net::Uri uri = net::make_uri(config_->apiroot, path,94 net::Uri uri = net::make_uri(config_.apiroot, path,
81 complete_parameters);95 complete_parameters);
82 configuration.uri = client_->uri_to_string(uri);96 configuration.uri = client_->uri_to_string(uri);
83 if (!config_->access_token.empty()) {97 if (!config_.access_token.empty()) {
84 configuration.header.add("Authorization",98 configuration.header.add("Authorization",
85 "bearer " + config_->access_token);99 "bearer " + config_.access_token);
86 } else if (!config_->client_id.empty() && !config_->client_secret.empty()) {100 } else if (!config_.client_id.empty() && !config_.client_secret.empty()) {
87 string auth = "basic "101 string auth = "basic "
88 + client_->base64_encode(102 + client_->base64_encode(
89 config_->client_id + ":" + config_->client_secret);103 config_.client_id + ":" + config_.client_secret);
90 configuration.header.add("Authorization", auth);104 configuration.header.add("Authorization", auth);
91 }105 }
92 configuration.header.add("Accept", config_->accept);106 configuration.header.add("Accept", config_.accept);
93 configuration.header.add("User-Agent", config_->user_agent + " (gzip)");107 configuration.header.add("User-Agent", config_.user_agent + " (gzip)");
94 configuration.header.add("Accept-Encoding", "gzip");108 configuration.header.add("Accept-Encoding", "gzip");
95109
96 auto request = client_->head(configuration);110 auto request = client_->head(configuration);
@@ -151,10 +165,93 @@
151165
152 return prom->get_future();166 return prom->get_future();
153 }167 }
168
169 bool authenticated() {
170 std::lock_guard<std::mutex> lock(config_mutex_);
171 update_config();
172 return config_.authenticated;
173 }
174
175 void anonymous_login() {
176 fs::path saved_token_dir = fs::path(getenv("HOME"))
177 / ".local" / "share" / "unity-scopes" / "leaf-net" / SCOPE_NAME;
178 fs::path saved_token_path = saved_token_dir
179 / "anonymous_auth_token";
180
181 bool save_auth_token = getenv("VIMEO_SCOPE_IGNORE_ACCOUNTS") == nullptr;
182
183 config_.client_id = CLIENT_ID;
184 config_.client_secret = CLIENT_SECRET;
185
186 if (fs::exists(saved_token_path) && save_auth_token) {
187 ifstream in(saved_token_path.native(), ios::in | ios::binary);
188 if (in) {
189 ostringstream contents;
190 contents << in.rdbuf();
191 in.close();
192 config_.access_token = contents.str();
193 }
194 cerr << " re-using saved auth_token" << endl;
195 } else {
196 config_.access_token = unauthenticated(CLIENT_ID, CLIENT_SECRET,
197 config_.apiroot);
198 if (save_auth_token) {
199 fs::create_directories(saved_token_dir);
200 ofstream out(saved_token_path.native(), ios::out | ios::binary);
201 if (out) {
202 out << config_.access_token;
203 out.close();
204 }
205 }
206 cerr << " new auth_token" << endl;
207 }
208 }
209
210 void update_config() {
211 if (getenv("VIMEO_SCOPE_APIROOT")) {
212 config_.apiroot = getenv("VIMEO_SCOPE_APIROOT");
213 }
214
215 if (getenv("VIMEO_SCOPE_IGNORE_ACCOUNTS") != nullptr) {
216 return;
217 }
218
219 /// TODO: The code commented out below should be uncommented as soon as
220 /// OnlineAccountClient::refresh_service_statuses() is fixed (Bug #1398813).
221 /// For now we have to re-instantiate a new OnlineAccountClient each time.
222
223 ///if (oa_client_ == nullptr) {
224 oa_client_.reset(
225 new unity::scopes::OnlineAccountClient(SCOPE_INSTALL_NAME,
226 "sharing", SCOPE_ACCOUNTS_NAME));
227 ///} else {
228 /// oa_client_->refresh_service_statuses();
229 ///}
230
231 for (auto const& status : oa_client_->get_service_statuses()) {
232 if (status.service_authenticated) {
233 config_.authenticated = true;
234 config_.access_token = status.access_token;
235 config_.client_id = status.client_id;
236 config_.client_secret = status.client_secret;
237 break;
238 }
239 }
240
241 if (!config_.authenticated) {
242 config_.access_token = "";
243 config_.client_id = "";
244 config_.client_secret = "";
245 std::cerr << "Vimeo scope is unauthenticated" << std::endl;
246 anonymous_login();
247 } else {
248 std::cerr << "Vimeo scope is authenticated" << std::endl;
249 }
250 }
154};251};
155252
156Client::Client(Config::Ptr config) :253Client::Client(std::shared_ptr<unity::scopes::OnlineAccountClient> oa_client) :
157 p(new Priv(config)) {254 p(new Priv(oa_client)) {
158}255}
159256
160future<Client::VideoList> Client::videos(const string &query) {257future<Client::VideoList> Client::videos(const string &query) {
@@ -190,7 +287,7 @@
190 p->cancelled_ = true;287 p->cancelled_ = true;
191}288}
192289
193Config::Ptr Client::config() {290bool Client::authenticated() {
194 return p->config_;291 return p->authenticated();
195}292}
196293
197294
=== modified file 'src/vimeo/scope/query.cpp'
--- src/vimeo/scope/query.cpp 2014-11-17 12:44:51 +0000
+++ src/vimeo/scope/query.cpp 2014-12-04 12:41:10 +0000
@@ -88,8 +88,9 @@
88}88}
8989
90Query::Query(const sc::CannedQuery &query, const sc::SearchMetadata &metadata,90Query::Query(const sc::CannedQuery &query, const sc::SearchMetadata &metadata,
91 Config::Ptr config) :91 std::shared_ptr<sc::OnlineAccountClient> oa_client) :
92 sc::SearchQueryBase(query, metadata), client_(config) {92 sc::SearchQueryBase(query, metadata),
93 client_(oa_client) {
93}94}
9495
95void Query::cancelled() {96void Query::cancelled() {
@@ -132,7 +133,7 @@
132 "My Feed");133 "My Feed");
133 sc::Department::SPtr dummy_dept;134 sc::Department::SPtr dummy_dept;
134135
135 bool include_login_nag = !client_.config()->authenticated;136 bool include_login_nag = !client_.authenticated();
136137
137 if (query_string.empty()) {138 if (query_string.empty()) {
138 channels_future = client_.channels();139 channels_future = client_.channels();
@@ -147,7 +148,7 @@
147 videos_future = client_.channels_videos("staffpicks");148 videos_future = client_.channels_videos("staffpicks");
148 } else if (!query.department_id().empty()) {149 } else if (!query.department_id().empty()) {
149 videos_future = client_.channels_videos(query.department_id());150 videos_future = client_.channels_videos(query.department_id());
150 } else if (client_.config()->authenticated) {151 } else if (client_.authenticated()) {
151 videos_future = client_.feed();152 videos_future = client_.feed();
152 } else {153 } else {
153 videos_future = client_.channels_videos("staffpicks");154 videos_future = client_.channels_videos("staffpicks");
154155
=== modified file 'src/vimeo/scope/scope.cpp'
--- src/vimeo/scope/scope.cpp 2014-11-07 18:54:12 +0000
+++ src/vimeo/scope/scope.cpp 2014-12-04 12:41:10 +0000
@@ -16,102 +16,16 @@
16 * Author: Pete Woods <pete.woods@canonical.com>16 * Author: Pete Woods <pete.woods@canonical.com>
17 */17 */
1818
19#include <vimeo/api/login.h>19#include <vimeo/scope/localisation.h>
20#include <vimeo/scope/scope.h>20#include <vimeo/scope/scope.h>
21#include <vimeo/scope/query.h>21#include <vimeo/scope/query.h>
22#include <vimeo/scope/preview.h>22#include <vimeo/scope/preview.h>
2323
24#include <boost/filesystem/path.hpp>
25#include <boost/filesystem/operations.hpp>
26
27#include <iostream>
28#include <sstream>
29#include <fstream>
30
31namespace sc = unity::scopes;24namespace sc = unity::scopes;
32using namespace std;25using namespace std;
33using namespace boost;
34using namespace vimeo::scope;26using namespace vimeo::scope;
35using namespace vimeo::api;27using namespace vimeo::api;
3628
37static const char* CLIENT_ID = "b6758ff9f929cdb9f45a8477732bdbc4c6a89c7e";
38static const char* CLIENT_SECRET = "a3222f38f799b3b528e29418fe062c02c677a249";
39
40void Scope::anonymous_login() {
41 filesystem::path saved_token_dir = filesystem::path(getenv("HOME"))
42 / ".local" / "share" / "unity-scopes" / "leaf-net" / SCOPE_NAME;
43 filesystem::path saved_token_path = saved_token_dir
44 / "anonymous_auth_token";
45
46 bool save_auth_token = getenv("VIMEO_SCOPE_IGNORE_ACCOUNTS") == nullptr;
47
48 config_->client_id = CLIENT_ID;
49 config_->client_secret = CLIENT_SECRET;
50
51 if (filesystem::exists(saved_token_path) && save_auth_token) {
52 ifstream in(saved_token_path.native(), ios::in | ios::binary);
53 if (in) {
54 ostringstream contents;
55 contents << in.rdbuf();
56 in.close();
57 config_->access_token = contents.str();
58 }
59 cerr << " re-using saved auth_token" << endl;
60 } else {
61 config_->access_token = unauthenticated(CLIENT_ID, CLIENT_SECRET,
62 config_->apiroot);
63 if (save_auth_token) {
64 filesystem::create_directories(saved_token_dir);
65 ofstream out(saved_token_path.native(), ios::out | ios::binary);
66 if (out) {
67 out << config_->access_token;
68 out.close();
69 }
70 }
71 cerr << " new auth_token" << endl;
72 }
73}
74
75void Scope::service_update(sc::OnlineAccountClient::ServiceStatus const&)
76{
77 update_config();
78}
79
80void Scope::update_config()
81{
82 std::lock_guard<std::mutex> lock(config_mutex_);
83 init_config();
84
85 for (auto const& status : oa_client_->get_service_statuses())
86 {
87 if (status.service_authenticated)
88 {
89 config_->authenticated = true;
90 config_->access_token = status.access_token;
91 config_->client_id = status.client_id;
92 config_->client_secret = status.client_secret;
93 break;
94 }
95 }
96
97 if (!config_->authenticated) {
98 cerr << "Vimeo scope is unauthenticated" << endl;
99 anonymous_login();
100 } else {
101 cerr << "Vimeo scope is authenticated" << endl;
102 }
103
104 config_cond_.notify_all();
105}
106
107void Scope::init_config()
108{
109 config_ = make_shared<Config>();
110 if (getenv("VIMEO_SCOPE_APIROOT")) {
111 config_->apiroot = getenv("VIMEO_SCOPE_APIROOT");
112 }
113}
114
115void Scope::start(string const&) {29void Scope::start(string const&) {
116 setlocale(LC_ALL, "");30 setlocale(LC_ALL, "");
117 string translation_directory = ScopeBase::scope_directory()31 string translation_directory = ScopeBase::scope_directory()
@@ -122,23 +36,6 @@
122 oa_client_.reset(36 oa_client_.reset(
123 new sc::OnlineAccountClient(SCOPE_INSTALL_NAME,37 new sc::OnlineAccountClient(SCOPE_INSTALL_NAME,
124 "sharing", SCOPE_ACCOUNTS_NAME));38 "sharing", SCOPE_ACCOUNTS_NAME));
125 oa_client_->set_service_update_callback(
126 std::bind(&Scope::service_update, this, std::placeholders::_1));
127
128 ///! TODO: We should only be waiting here if we know that there is at least one Google account enabled.
129 /// OnlineAccountClient needs to expose some functionality for us to determine that.
130
131 // Allow 1 second for the callback to initialize config_
132 std::unique_lock<std::mutex> lock(config_mutex_);
133 config_cond_.wait_for(lock, std::chrono::seconds(1), [this] { return config_ != nullptr; });
134 }
135
136 if (config_ == nullptr)
137 {
138 // If the callback was not invoked, default initialize config_
139 init_config();
140 cerr << "Vimeo scope is unauthenticated" << endl;
141 anonymous_login();
142 }39 }
143}40}
14441
@@ -147,7 +44,7 @@
14744
148sc::SearchQueryBase::UPtr Scope::search(const sc::CannedQuery &query,45sc::SearchQueryBase::UPtr Scope::search(const sc::CannedQuery &query,
149 const sc::SearchMetadata &metadata) {46 const sc::SearchMetadata &metadata) {
150 return sc::SearchQueryBase::UPtr(new Query(query, metadata, config_));47 return sc::SearchQueryBase::UPtr(new Query(query, metadata, oa_client_));
151}48}
15249
153sc::PreviewQueryBase::UPtr Scope::preview(sc::Result const& result,50sc::PreviewQueryBase::UPtr Scope::preview(sc::Result const& result,

Subscribers

People subscribed via source and target branches