Merge lp:~stolowski/unity-scope-click/departments into lp:unity-scope-click/devel
- departments
- Merge into devel
Status: | Superseded |
---|---|
Proposed branch: | lp:~stolowski/unity-scope-click/departments |
Merge into: | lp:unity-scope-click/devel |
Diff against target: |
2394 lines (+1473/-114) (has conflicts) 33 files modified
CMakeLists.txt (+1/-1) debian/control (+1/-1) libclickscope/click/CMakeLists.txt (+3/-0) libclickscope/click/department-lookup.cpp (+84/-0) libclickscope/click/department-lookup.h (+58/-0) libclickscope/click/departments.cpp (+164/-0) libclickscope/click/departments.h (+83/-0) libclickscope/click/highlights.cpp (+95/-0) libclickscope/click/highlights.h (+72/-0) libclickscope/click/index.cpp (+70/-5) libclickscope/click/index.h (+7/-2) libclickscope/click/package.h (+1/-0) libclickscope/click/preview.cpp (+1/-0) libclickscope/click/scope_activation.cpp (+11/-5) libclickscope/click/scope_activation.h (+2/-2) libclickscope/click/webclient.cpp (+2/-1) libclickscope/click/webclient.h (+1/-1) libclickscope/tests/CMakeLists.txt (+2/-0) libclickscope/tests/fake_json.h (+236/-0) libclickscope/tests/mock_network_access_manager.h (+1/-0) libclickscope/tests/mock_webclient.h (+2/-2) libclickscope/tests/test_bootstrap.cpp (+73/-0) libclickscope/tests/test_departments.cpp (+108/-0) libclickscope/tests/test_index.cpp (+10/-10) scope/clickapps/apps-query.cpp (+11/-12) scope/clickapps/apps-scope.cpp (+5/-6) scope/clickapps/apps-scope.h (+3/-3) scope/clickstore/store-query.cpp (+233/-16) scope/clickstore/store-query.h (+16/-3) scope/clickstore/store-scope.cpp (+25/-5) scope/clickstore/store-scope.h (+12/-2) scope/tests/integration/webclient_integration.cpp (+3/-1) scope/tests/test_query.cpp (+77/-36) Text conflict in scope/clickstore/store-scope.cpp |
To merge this branch: | bzr merge lp:~stolowski/unity-scope-click/departments |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
dobey (community) | Needs Fixing | ||
Review via email: mp+219211@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-06-18.
Commit message
Add support for departments and highlights.
Description of the change
Add support for departments and highlights.
dobey (dobey) wrote : | # |
Can you also add a commit with --fixes=lp:1209224 to link that bug?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:254
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
dobey (dobey) wrote : | # |
This conflicts with the changes in https:/
- 255. By Paweł Stołowski
-
Forgot about highlights.
- 256. By Paweł Stołowski
-
Merged 0.5.0 update branch.
- 257. By Paweł Stołowski
-
Merged devel.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:255
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 258. By Paweł Stołowski
-
Reuse code between bootstrap and departments call.
- 259. By Paweł Stołowski
-
Cleanups. Check department href in tests.
- 260. By Paweł Stołowski
-
Test get_department_
info(). - 261. By Paweł Stołowski
-
Added tests for broken departments json.
- 262. By Paweł Stołowski
-
Don't pass departments with search.
- 263. By Paweł Stołowski
-
Test for invalid highlights. Cleanups.
- 264. By Paweł Stołowski
-
Reuse push_package().
- 265. By Paweł Stołowski
-
Fixed comment.
- 266. By Paweł Stołowski
-
Test bootstrap call.
- 267. By Paweł Stołowski
-
Merged devel.
Unmerged revisions
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-05-27 13:15:52 +0000 |
3 | +++ CMakeLists.txt 2014-06-18 18:08:01 +0000 |
4 | @@ -21,7 +21,7 @@ |
5 | |
6 | include(FindPkgConfig) |
7 | |
8 | -pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.4.0 libunity-api>=0.1.3) |
9 | +pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.5.0 libunity-api>=0.1.3) |
10 | add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER}) |
11 | |
12 | find_package (PkgConfig REQUIRED) |
13 | |
14 | === modified file 'debian/control' |
15 | --- debian/control 2014-06-13 15:21:16 +0000 |
16 | +++ debian/control 2014-06-18 18:08:01 +0000 |
17 | @@ -13,7 +13,7 @@ |
18 | libubuntu-download-manager-common-dev (>= 0.3+14.10.20140430-0ubuntu1), |
19 | libubuntuoneauth-2.0-dev, |
20 | libunity-api-dev (>= 7.80.7), |
21 | - libunity-scopes-dev (>= 0.4.0), |
22 | + libunity-scopes-dev (>= 0.5.0), |
23 | pkg-config, |
24 | python3-all, |
25 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
26 | |
27 | === modified file 'libclickscope/click/CMakeLists.txt' |
28 | --- libclickscope/click/CMakeLists.txt 2014-06-13 15:21:16 +0000 |
29 | +++ libclickscope/click/CMakeLists.txt 2014-06-18 18:08:01 +0000 |
30 | @@ -11,6 +11,9 @@ |
31 | add_library(${SCOPE_LIB_NAME} STATIC |
32 | configuration.cpp |
33 | download-manager.cpp |
34 | + department-lookup.cpp |
35 | + departments.cpp |
36 | + highlights.cpp |
37 | index.cpp |
38 | interface.cpp |
39 | key_file_locator.cpp |
40 | |
41 | === added file 'libclickscope/click/department-lookup.cpp' |
42 | --- libclickscope/click/department-lookup.cpp 1970-01-01 00:00:00 +0000 |
43 | +++ libclickscope/click/department-lookup.cpp 2014-06-18 18:08:01 +0000 |
44 | @@ -0,0 +1,84 @@ |
45 | +/* |
46 | + * Copyright (C) 2014 Canonical Ltd. |
47 | + * |
48 | + * This program is free software: you can redistribute it and/or modify it |
49 | + * under the terms of the GNU General Public License version 3, as published |
50 | + * by the Free Software Foundation. |
51 | + * |
52 | + * This program is distributed in the hope that it will be useful, but |
53 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
54 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
55 | + * PURPOSE. See the GNU General Public License for more details. |
56 | + * |
57 | + * You should have received a copy of the GNU General Public License along |
58 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
59 | + * |
60 | + * In addition, as a special exception, the copyright holders give |
61 | + * permission to link the code of portions of this program with the |
62 | + * OpenSSL library under certain conditions as described in each |
63 | + * individual source file, and distribute linked combinations |
64 | + * including the two. |
65 | + * You must obey the GNU General Public License in all respects |
66 | + * for all of the code used other than OpenSSL. If you modify |
67 | + * file(s) with this exception, you may extend this exception to your |
68 | + * version of the file(s), but you are not obligated to do so. If you |
69 | + * do not wish to do so, delete this exception statement from your |
70 | + * version. If you delete this exception statement from all source |
71 | + * files in the program, then also delete it here. |
72 | + */ |
73 | + |
74 | +#include "department-lookup.h" |
75 | + |
76 | +namespace click |
77 | +{ |
78 | + |
79 | +DepartmentLookup::DepartmentLookup() |
80 | +{ |
81 | +} |
82 | + |
83 | +void DepartmentLookup::rebuild(const Department::SPtr& dept) |
84 | +{ |
85 | + departments[dept->id()] = dept; |
86 | + for (auto const& subdep: dept->sub_departments()) |
87 | + { |
88 | + parent_lut[subdep->id()] = dept; |
89 | + rebuild(subdep); |
90 | + } |
91 | +} |
92 | + |
93 | +void DepartmentLookup::rebuild(const std::list<Department::SPtr>& root_departments) |
94 | +{ |
95 | + parent_lut.clear(); |
96 | + departments.clear(); |
97 | + for (auto const& dep: root_departments) |
98 | + { |
99 | + rebuild(dep); |
100 | + } |
101 | +} |
102 | + |
103 | +Department::SPtr DepartmentLookup::get_parent(const std::string& department_id) const |
104 | +{ |
105 | + auto it = parent_lut.find(department_id); |
106 | + if (it != parent_lut.end()) |
107 | + { |
108 | + return it->second; |
109 | + } |
110 | + return Department::SPtr(nullptr); |
111 | +} |
112 | + |
113 | +Department::SPtr DepartmentLookup::get_department_info(const std::string& department_id) const |
114 | +{ |
115 | + auto it = departments.find(department_id); |
116 | + if (it != departments.end()) |
117 | + { |
118 | + return it->second; |
119 | + } |
120 | + return nullptr; |
121 | +} |
122 | + |
123 | +int DepartmentLookup::size() const |
124 | +{ |
125 | + return parent_lut.size(); |
126 | +} |
127 | + |
128 | +} |
129 | |
130 | === added file 'libclickscope/click/department-lookup.h' |
131 | --- libclickscope/click/department-lookup.h 1970-01-01 00:00:00 +0000 |
132 | +++ libclickscope/click/department-lookup.h 2014-06-18 18:08:01 +0000 |
133 | @@ -0,0 +1,58 @@ |
134 | +/* |
135 | + * Copyright (C) 2014 Canonical Ltd. |
136 | + * |
137 | + * This program is free software: you can redistribute it and/or modify it |
138 | + * under the terms of the GNU General Public License version 3, as published |
139 | + * by the Free Software Foundation. |
140 | + * |
141 | + * This program is distributed in the hope that it will be useful, but |
142 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
143 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
144 | + * PURPOSE. See the GNU General Public License for more details. |
145 | + * |
146 | + * You should have received a copy of the GNU General Public License along |
147 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
148 | + * |
149 | + * In addition, as a special exception, the copyright holders give |
150 | + * permission to link the code of portions of this program with the |
151 | + * OpenSSL library under certain conditions as described in each |
152 | + * individual source file, and distribute linked combinations |
153 | + * including the two. |
154 | + * You must obey the GNU General Public License in all respects |
155 | + * for all of the code used other than OpenSSL. If you modify |
156 | + * file(s) with this exception, you may extend this exception to your |
157 | + * version of the file(s), but you are not obligated to do so. If you |
158 | + * do not wish to do so, delete this exception statement from your |
159 | + * version. If you delete this exception statement from all source |
160 | + * files in the program, then also delete it here. |
161 | + */ |
162 | + |
163 | +#ifndef CLICK_DEPARTMENT_LOOKUP_H |
164 | +#define CLICK_DEPARTMENT_LOOKUP_H |
165 | + |
166 | +#include "departments.h" |
167 | +#include <string> |
168 | +#include <memory> |
169 | +#include <map> |
170 | + |
171 | +namespace click |
172 | +{ |
173 | + |
174 | +class DepartmentLookup |
175 | +{ |
176 | + public: |
177 | + DepartmentLookup(); |
178 | + void rebuild(const std::list<Department::SPtr>& root_departments); |
179 | + Department::SPtr get_parent(const std::string& department_id) const; |
180 | + Department::SPtr get_department_info(const std::string& department_id) const; |
181 | + int size() const; |
182 | + |
183 | + private: |
184 | + void rebuild(const Department::SPtr& dept); |
185 | + std::map<std::string, Department::SPtr> parent_lut; |
186 | + std::map<std::string, Department::SPtr> departments; |
187 | +}; |
188 | + |
189 | +} |
190 | + |
191 | +#endif |
192 | |
193 | === added file 'libclickscope/click/departments.cpp' |
194 | --- libclickscope/click/departments.cpp 1970-01-01 00:00:00 +0000 |
195 | +++ libclickscope/click/departments.cpp 2014-06-18 18:08:01 +0000 |
196 | @@ -0,0 +1,164 @@ |
197 | +/* |
198 | + * Copyright (C) 2014 Canonical Ltd. |
199 | + * |
200 | + * This program is free software: you can redistribute it and/or modify it |
201 | + * under the terms of the GNU General Public License version 3, as published |
202 | + * by the Free Software Foundation. |
203 | + * |
204 | + * This program is distributed in the hope that it will be useful, but |
205 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
206 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
207 | + * PURPOSE. See the GNU General Public License for more details. |
208 | + * |
209 | + * You should have received a copy of the GNU General Public License along |
210 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
211 | + * |
212 | + * In addition, as a special exception, the copyright holders give |
213 | + * permission to link the code of portions of this program with the |
214 | + * OpenSSL library under certain conditions as described in each |
215 | + * individual source file, and distribute linked combinations |
216 | + * including the two. |
217 | + * You must obey the GNU General Public License in all respects |
218 | + * for all of the code used other than OpenSSL. If you modify |
219 | + * file(s) with this exception, you may extend this exception to your |
220 | + * version of the file(s), but you are not obligated to do so. If you |
221 | + * do not wish to do so, delete this exception statement from your |
222 | + * version. If you delete this exception statement from all source |
223 | + * files in the program, then also delete it here. |
224 | + */ |
225 | + |
226 | +#include "departments.h" |
227 | +#include <iostream> |
228 | + |
229 | +namespace click |
230 | +{ |
231 | + |
232 | +/*Department::Department(const std::string& id, const std::string& name) |
233 | + : id_(id), |
234 | + name_(name), |
235 | + href_(""), //FIXME |
236 | + has_children_flag_(false) |
237 | +{ |
238 | +}*/ |
239 | + |
240 | +Department::Department(const std::string& id, const std::string &name, const std::string& href, bool has_children) |
241 | + : id_(id), |
242 | + name_(name), |
243 | + href_(href), |
244 | + has_children_flag_(has_children) |
245 | +{ |
246 | +} |
247 | + |
248 | +std::string Department::id() const |
249 | +{ |
250 | + return id_; |
251 | +} |
252 | + |
253 | +std::string Department::name() const |
254 | +{ |
255 | + return name_; |
256 | +} |
257 | + |
258 | +std::string Department::href() const |
259 | +{ |
260 | + return href_; |
261 | +} |
262 | + |
263 | +bool Department::has_children_flag() const |
264 | +{ |
265 | + return has_children_flag_; |
266 | +} |
267 | + |
268 | +void Department::set_subdepartments(const std::list<Department::SPtr>& deps) |
269 | +{ |
270 | + sub_departments_ = deps; |
271 | +} |
272 | + |
273 | +std::list<Department::SPtr> Department::sub_departments() const |
274 | +{ |
275 | + return sub_departments_; |
276 | +} |
277 | + |
278 | +std::list<Department::SPtr> Department::from_json_node(const Json::Value& node) |
279 | +{ |
280 | + std::list<Department::SPtr> deps; |
281 | + |
282 | + for (uint i = 0; i < node.size(); i++) |
283 | + { |
284 | + auto const item = node[i]; |
285 | + if (item.isObject() && item.isMember(Department::JsonKeys::name)) |
286 | + { |
287 | + auto name = item[Department::JsonKeys::name].asString(); |
288 | + const bool has_children = item.isMember(Department::JsonKeys::has_children) ? item[Department::JsonKeys::has_children].asBool() : false; |
289 | + |
290 | + auto const links = item[Department::JsonKeys::links]; |
291 | + auto const self = links[Department::JsonKeys::self]; |
292 | + auto const href = self[Department::JsonKeys::href].asString(); |
293 | + |
294 | + auto dep = std::make_shared<Department>(name, name, href, has_children); //FIXME: id |
295 | + if (item.isObject() && item.isMember(Department::JsonKeys::embedded)) |
296 | + { |
297 | + auto const emb = item[Department::JsonKeys::embedded]; |
298 | + if (emb.isObject() && emb.isMember(Department::JsonKeys::department)) |
299 | + { |
300 | + auto const ditem = emb[Department::JsonKeys::department]; |
301 | + auto const subdeps = from_json_node(ditem); |
302 | + dep->set_subdepartments(subdeps); |
303 | + } |
304 | + } |
305 | + deps.push_back(dep); |
306 | + } |
307 | + } |
308 | + |
309 | + return deps; |
310 | +} |
311 | + |
312 | +std::list<Department::SPtr> Department::from_json_root_node(const Json::Value& root) |
313 | +{ |
314 | + if (root.isObject() && root.isMember(Department::JsonKeys::embedded)) |
315 | + { |
316 | + auto const emb = root[Department::JsonKeys::embedded]; |
317 | + if (emb.isObject() && emb.isMember(Department::JsonKeys::department)) |
318 | + { |
319 | + auto const ditem = emb[Department::JsonKeys::department]; |
320 | + return from_json_node(ditem); |
321 | + } |
322 | + } |
323 | + |
324 | + return std::list<Department::SPtr>(); |
325 | +} |
326 | + |
327 | +std::list<Department::SPtr> Department::from_json(const std::string& json) |
328 | +{ |
329 | + Json::Reader reader; |
330 | + Json::Value root; |
331 | + |
332 | + try |
333 | + { |
334 | + if (!reader.parse(json, root)) { |
335 | + throw std::runtime_error(reader.getFormattedErrorMessages()); |
336 | + } |
337 | + |
338 | + if (root.isObject() && root.isMember(Department::JsonKeys::embedded)) |
339 | + { |
340 | + auto const emb = root[Department::JsonKeys::embedded]; |
341 | + if (emb.isObject() && emb.isMember(Department::JsonKeys::department)) |
342 | + { |
343 | + auto const ditem = emb[Department::JsonKeys::department]; |
344 | + return from_json_node(ditem); |
345 | + } |
346 | + } |
347 | + } |
348 | + catch (const std::exception& e) |
349 | + { |
350 | + std::cerr << "Error parsing departments: " << e.what() << std::endl; |
351 | + } |
352 | + catch (...) |
353 | + { |
354 | + std::cerr << "Unknown error when parsing departments" << std::endl; |
355 | + } |
356 | + |
357 | + return std::list<Department::SPtr>(); |
358 | +} |
359 | + |
360 | +} |
361 | |
362 | === added file 'libclickscope/click/departments.h' |
363 | --- libclickscope/click/departments.h 1970-01-01 00:00:00 +0000 |
364 | +++ libclickscope/click/departments.h 2014-06-18 18:08:01 +0000 |
365 | @@ -0,0 +1,83 @@ |
366 | +/* |
367 | + * Copyright (C) 2014 Canonical Ltd. |
368 | + * |
369 | + * This program is free software: you can redistribute it and/or modify it |
370 | + * under the terms of the GNU General Public License version 3, as published |
371 | + * by the Free Software Foundation. |
372 | + * |
373 | + * This program is distributed in the hope that it will be useful, but |
374 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
375 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
376 | + * PURPOSE. See the GNU General Public License for more details. |
377 | + * |
378 | + * You should have received a copy of the GNU General Public License along |
379 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
380 | + * |
381 | + * In addition, as a special exception, the copyright holders give |
382 | + * permission to link the code of portions of this program with the |
383 | + * OpenSSL library under certain conditions as described in each |
384 | + * individual source file, and distribute linked combinations |
385 | + * including the two. |
386 | + * You must obey the GNU General Public License in all respects |
387 | + * for all of the code used other than OpenSSL. If you modify |
388 | + * file(s) with this exception, you may extend this exception to your |
389 | + * version of the file(s), but you are not obligated to do so. If you |
390 | + * do not wish to do so, delete this exception statement from your |
391 | + * version. If you delete this exception statement from all source |
392 | + * files in the program, then also delete it here. |
393 | + */ |
394 | + |
395 | +#ifndef CLICK_DEPARTMENTS_H |
396 | +#define CLICK_DEPARTMENTS_H |
397 | + |
398 | +#include <string> |
399 | +#include <list> |
400 | +#include <memory> |
401 | +#include <json/json.h> |
402 | + |
403 | +namespace click |
404 | +{ |
405 | + |
406 | +class Department |
407 | +{ |
408 | + public: |
409 | + typedef std::shared_ptr<Department> SPtr; |
410 | + typedef std::shared_ptr<Department const> SCPtr; |
411 | + |
412 | + struct JsonKeys |
413 | + { |
414 | + JsonKeys() = delete; |
415 | + constexpr static const char* name {"name"}; |
416 | + constexpr static const char* embedded {"_embedded"}; |
417 | + constexpr static const char* department {"clickindex:department"}; |
418 | + constexpr static const char* has_children {"has_children"}; |
419 | + constexpr static const char* links {"_links"}; |
420 | + constexpr static const char* self {"self"}; |
421 | + constexpr static const char* href {"href"}; |
422 | + }; |
423 | + |
424 | + //Department(const std::string &id, const std::string &name); |
425 | + Department(const std::string &id, const std::string &name, const std::string& href, bool has_children); |
426 | + std::string id() const; |
427 | + std::string name() const; |
428 | + std::string href() const; |
429 | + bool has_children_flag() const; |
430 | + void set_subdepartments(const std::list<Department::SPtr>& deps); |
431 | + std::list<Department::SPtr> sub_departments() const; |
432 | + static std::list<Department::SPtr> from_json(const std::string& json); |
433 | + static std::list<Department::SPtr> from_json_root_node(const Json::Value& val); |
434 | + |
435 | + private: |
436 | + static std::list<Department::SPtr> from_json_node(const Json::Value& val); |
437 | + std::string id_; |
438 | + std::string name_; |
439 | + std::string href_; |
440 | + bool has_children_flag_; |
441 | + std::list<Department::SPtr> sub_departments_; |
442 | +}; |
443 | + |
444 | +typedef std::list<Department::SPtr> DepartmentList; |
445 | + |
446 | +} |
447 | + |
448 | +#endif |
449 | |
450 | === added file 'libclickscope/click/highlights.cpp' |
451 | --- libclickscope/click/highlights.cpp 1970-01-01 00:00:00 +0000 |
452 | +++ libclickscope/click/highlights.cpp 2014-06-18 18:08:01 +0000 |
453 | @@ -0,0 +1,95 @@ |
454 | +/* |
455 | + * Copyright (C) 2014 Canonical Ltd. |
456 | + * |
457 | + * This program is free software: you can redistribute it and/or modify it |
458 | + * under the terms of the GNU General Public License version 3, as published |
459 | + * by the Free Software Foundation. |
460 | + * |
461 | + * This program is distributed in the hope that it will be useful, but |
462 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
463 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
464 | + * PURPOSE. See the GNU General Public License for more details. |
465 | + * |
466 | + * You should have received a copy of the GNU General Public License along |
467 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
468 | + * |
469 | + * In addition, as a special exception, the copyright holders give |
470 | + * permission to link the code of portions of this program with the |
471 | + * OpenSSL library under certain conditions as described in each |
472 | + * individual source file, and distribute linked combinations |
473 | + * including the two. |
474 | + * You must obey the GNU General Public License in all respects |
475 | + * for all of the code used other than OpenSSL. If you modify |
476 | + * file(s) with this exception, you may extend this exception to your |
477 | + * version of the file(s), but you are not obligated to do so. If you |
478 | + * do not wish to do so, delete this exception statement from your |
479 | + * version. If you delete this exception statement from all source |
480 | + * files in the program, then also delete it here. |
481 | + */ |
482 | + |
483 | +#include "highlights.h" |
484 | +#include <iostream> |
485 | + |
486 | +namespace click |
487 | +{ |
488 | + |
489 | +Highlight::Highlight(const std::string& name) |
490 | + : name_(name) |
491 | +{ |
492 | +} |
493 | + |
494 | +Highlight::Highlight(const std::string& name, const Packages& pkgs) |
495 | + : name_(name), |
496 | + packages_(pkgs) |
497 | +{ |
498 | +} |
499 | + |
500 | +void Highlight::add_package(const Package& pkg) |
501 | +{ |
502 | + packages_.push_back(pkg); |
503 | +} |
504 | + |
505 | +std::string Highlight::name() const |
506 | +{ |
507 | + return name_; |
508 | +} |
509 | + |
510 | +Packages Highlight::packages() const |
511 | +{ |
512 | + return packages_; |
513 | +} |
514 | + |
515 | +std::list<Highlight> Highlight::from_json_node(const Json::Value& node) |
516 | +{ |
517 | + std::list<Highlight> highlights; |
518 | + |
519 | + for (uint i = 0; i < node.size(); i++) |
520 | + { |
521 | + auto const item = node[i]; |
522 | + if (item.isObject() && item.isMember(Highlight::JsonKeys::name)) |
523 | + { |
524 | + auto name = item[Highlight::JsonKeys::name].asString(); |
525 | + auto pkgs = package_list_from_json_node(item); |
526 | + highlights.push_back(Highlight(name, pkgs)); |
527 | + } |
528 | + } |
529 | + |
530 | + return highlights; |
531 | +} |
532 | + |
533 | +std::list<Highlight> Highlight::from_json_root_node(const Json::Value& root) |
534 | +{ |
535 | + if (root.isObject() && root.isMember(Highlight::JsonKeys::embedded)) |
536 | + { |
537 | + auto const emb = root[Highlight::JsonKeys::embedded]; |
538 | + if (emb.isObject() && emb.isMember(Highlight::JsonKeys::highlight)) |
539 | + { |
540 | + auto const hl = emb[Highlight::JsonKeys::highlight]; |
541 | + return from_json_node(hl); |
542 | + } |
543 | + } |
544 | + |
545 | + return std::list<Highlight>(); |
546 | +} |
547 | + |
548 | +} |
549 | |
550 | === added file 'libclickscope/click/highlights.h' |
551 | --- libclickscope/click/highlights.h 1970-01-01 00:00:00 +0000 |
552 | +++ libclickscope/click/highlights.h 2014-06-18 18:08:01 +0000 |
553 | @@ -0,0 +1,72 @@ |
554 | +/* |
555 | + * Copyright (C) 2014 Canonical Ltd. |
556 | + * |
557 | + * This program is free software: you can redistribute it and/or modify it |
558 | + * under the terms of the GNU General Public License version 3, as published |
559 | + * by the Free Software Foundation. |
560 | + * |
561 | + * This program is distributed in the hope that it will be useful, but |
562 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
563 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
564 | + * PURPOSE. See the GNU General Public License for more details. |
565 | + * |
566 | + * You should have received a copy of the GNU General Public License along |
567 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
568 | + * |
569 | + * In addition, as a special exception, the copyright holders give |
570 | + * permission to link the code of portions of this program with the |
571 | + * OpenSSL library under certain conditions as described in each |
572 | + * individual source file, and distribute linked combinations |
573 | + * including the two. |
574 | + * You must obey the GNU General Public License in all respects |
575 | + * for all of the code used other than OpenSSL. If you modify |
576 | + * file(s) with this exception, you may extend this exception to your |
577 | + * version of the file(s), but you are not obligated to do so. If you |
578 | + * do not wish to do so, delete this exception statement from your |
579 | + * version. If you delete this exception statement from all source |
580 | + * files in the program, then also delete it here. |
581 | + */ |
582 | + |
583 | +#ifndef CLICK_HIGHLIGHTS_H |
584 | +#define CLICK_HIGHLIGHTS_H |
585 | + |
586 | +#include <string> |
587 | +#include <list> |
588 | +#include <json/json.h> |
589 | +#include <click/package.h> |
590 | + |
591 | +namespace click |
592 | +{ |
593 | + |
594 | +class Highlight |
595 | +{ |
596 | +public: |
597 | + struct JsonKeys |
598 | + { |
599 | + JsonKeys() = delete; |
600 | + constexpr static const char* name {"name"}; |
601 | + constexpr static const char* embedded {"_embedded"}; |
602 | + constexpr static const char* highlight {"clickindex:highlight"}; |
603 | + }; |
604 | + |
605 | + Highlight(const std::string& name); |
606 | + Highlight(const std::string& name, const Packages& pkgs); |
607 | + void add_package(const Package& pkg); |
608 | + |
609 | + std::string name() const; |
610 | + Packages packages() const; |
611 | + |
612 | + static std::list<Highlight> from_json_root_node(const Json::Value& val); |
613 | + |
614 | +private: |
615 | + static std::list<Highlight> from_json_node(const Json::Value& val); |
616 | + |
617 | + std::string name_; |
618 | + Packages packages_; |
619 | +}; |
620 | + |
621 | +typedef std::list<Highlight> HighlightList; |
622 | + |
623 | +} |
624 | + |
625 | +#endif |
626 | |
627 | === modified file 'libclickscope/click/index.cpp' |
628 | --- libclickscope/click/index.cpp 2014-06-12 21:05:25 +0000 |
629 | +++ libclickscope/click/index.cpp 2014-06-18 18:08:01 +0000 |
630 | @@ -88,11 +88,15 @@ |
631 | |
632 | } |
633 | |
634 | -std::string Index::build_index_query(const std::string& query) |
635 | +std::string Index::build_index_query(const std::string& query, const std::string& department) |
636 | { |
637 | std::stringstream result; |
638 | |
639 | result << query; |
640 | + if (!department.empty()) { |
641 | + result << ",department:" << department; |
642 | + } |
643 | + |
644 | return result.str(); |
645 | } |
646 | |
647 | @@ -110,10 +114,10 @@ |
648 | }; |
649 | } |
650 | |
651 | -click::web::Cancellable Index::search (const std::string& query, std::function<void(click::Packages)> callback) |
652 | +click::web::Cancellable Index::search (const std::string& query, const std::string& department, std::function<void(click::Packages, click::DepartmentList)> callback) |
653 | { |
654 | click::web::CallParams params; |
655 | - const std::string built_query(build_index_query(query)); |
656 | + const std::string built_query(build_index_query(query, department)); |
657 | params.add(click::QUERY_ARGNAME, built_query.c_str()); |
658 | QSharedPointer<click::web::Response> response(client->call( |
659 | get_base_url() + click::SEARCH_PATH, "GET", false, build_headers(), "", params)); |
660 | @@ -123,22 +127,83 @@ |
661 | Json::Value root; |
662 | |
663 | click::Packages pl; |
664 | + click::DepartmentList depts; |
665 | if (reader.parse(reply.toUtf8().constData(), root)) { |
666 | pl = click::package_list_from_json_node(root); |
667 | qDebug() << "found packages:" << pl.size(); |
668 | + depts = click::Department::from_json_root_node(root); |
669 | } |
670 | - callback(pl); |
671 | + callback(pl, depts); |
672 | }); |
673 | QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) { |
674 | qDebug() << "No packages found due to network error"; |
675 | click::Packages pl; |
676 | + click::DepartmentList depts; |
677 | qDebug() << "calling callback"; |
678 | - callback(pl); |
679 | + callback(pl, depts); |
680 | qDebug() << " ...Done!"; |
681 | }); |
682 | return click::web::Cancellable(response); |
683 | } |
684 | |
685 | +click::web::Cancellable Index::bootstrap(std::function<void(const click::DepartmentList&, const click::HighlightList&, Error, int)> callback) |
686 | +{ |
687 | + click::web::CallParams params; |
688 | + QSharedPointer<click::web::Response> response(client->call( |
689 | + get_base_url() + click::BOOTSTRAP_PATH, "GET", false, build_headers(), "", params)); |
690 | + |
691 | + QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) { |
692 | + qDebug() << "bootstrap request finished"; |
693 | + Json::Reader reader; |
694 | + Json::Value root; |
695 | + |
696 | + click::DepartmentList depts; |
697 | + click::HighlightList highlights; |
698 | + if (reader.parse(reply.toUtf8().constData(), root)) { |
699 | + depts = Department::from_json_root_node(root); |
700 | + highlights = Highlight::from_json_root_node(root); |
701 | + } |
702 | + callback(depts, highlights, click::Index::Error::NoError, 0); |
703 | + }); |
704 | + QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/, int error_code) { |
705 | + qWarning() << "bootstrap call failed due to network error, code" << error_code; |
706 | + const click::DepartmentList depts; |
707 | + const click::HighlightList highlights; |
708 | + qDebug() << "bootstrap: calling callback"; |
709 | + callback(depts, highlights, click::Index::Error::NetworkError, error_code); |
710 | + }); |
711 | + return click::web::Cancellable(response); |
712 | +} |
713 | + |
714 | +click::web::Cancellable Index::departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error)> callback) |
715 | +{ |
716 | + click::web::CallParams params; |
717 | + QSharedPointer<click::web::Response> response(client->call( |
718 | + department_href, "GET", false, build_headers(), "", params)); |
719 | + |
720 | + QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) { |
721 | + qDebug() << "departments request finished"; |
722 | + Json::Reader reader; |
723 | + Json::Value root; |
724 | + |
725 | + click::DepartmentList depts; |
726 | + click::HighlightList highlights; |
727 | + if (reader.parse(reply.toUtf8().constData(), root)) { |
728 | + depts = Department::from_json_root_node(root); |
729 | + highlights = Highlight::from_json_root_node(root); |
730 | + } |
731 | + callback(depts, highlights, click::Index::Error::NoError); |
732 | + }); |
733 | + QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) { |
734 | + qWarning() << "departments call failed due to network error"; |
735 | + const click::DepartmentList depts; |
736 | + const click::HighlightList highlights; |
737 | + qDebug() << "departments: calling callback"; |
738 | + callback(depts, highlights, click::Index::Error::NetworkError); |
739 | + }); |
740 | + return click::web::Cancellable(response); |
741 | +} |
742 | + |
743 | click::web::Cancellable Index::get_details (const std::string& package_name, std::function<void(PackageDetails, click::Index::Error)> callback) |
744 | { |
745 | QSharedPointer<click::web::Response> response = client->call |
746 | |
747 | === modified file 'libclickscope/click/index.h' |
748 | --- libclickscope/click/index.h 2014-06-12 21:05:25 +0000 |
749 | +++ libclickscope/click/index.h 2014-06-18 18:08:01 +0000 |
750 | @@ -38,6 +38,8 @@ |
751 | #include <click/webclient.h> |
752 | |
753 | #include "package.h" |
754 | +#include <click/departments.h> |
755 | +#include <click/highlights.h> |
756 | |
757 | |
758 | namespace click { |
759 | @@ -47,6 +49,7 @@ |
760 | const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL"; |
761 | const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/"; |
762 | const std::string SEARCH_PATH = "api/v1/search"; |
763 | +const std::string BOOTSTRAP_PATH = "api/v1"; |
764 | const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10"; |
765 | const std::string QUERY_ARGNAME = "q"; |
766 | const std::string ARCHITECTURE = "architecture:"; |
767 | @@ -64,15 +67,17 @@ |
768 | protected: |
769 | QSharedPointer<web::Client> client; |
770 | QSharedPointer<Configuration> configuration; |
771 | - virtual std::string build_index_query(const std::string& query); |
772 | + virtual std::string build_index_query(const std::string& query, const std::string& department); |
773 | virtual std::map<std::string, std::string> build_headers(); |
774 | |
775 | public: |
776 | enum class Error {NoError, CredentialsError, NetworkError}; |
777 | Index(const QSharedPointer<click::web::Client>& client, |
778 | const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration())); |
779 | - virtual click::web::Cancellable search (const std::string& query, std::function<void(Packages)> callback); |
780 | + virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, DepartmentList)> callback); |
781 | virtual click::web::Cancellable get_details(const std::string& package_name, std::function<void(PackageDetails, Error)> callback); |
782 | + virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback); |
783 | + virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error)> callback); |
784 | virtual ~Index(); |
785 | |
786 | static std::string get_base_url (); |
787 | |
788 | === modified file 'libclickscope/click/package.h' |
789 | --- libclickscope/click/package.h 2014-06-13 22:42:02 +0000 |
790 | +++ libclickscope/click/package.h 2014-06-18 18:08:01 +0000 |
791 | @@ -34,6 +34,7 @@ |
792 | #include <string> |
793 | #include <unordered_set> |
794 | #include <vector> |
795 | +#include <functional> |
796 | |
797 | #include <json/json.h> |
798 | |
799 | |
800 | === modified file 'libclickscope/click/preview.cpp' |
801 | --- libclickscope/click/preview.cpp 2014-06-17 21:05:05 +0000 |
802 | +++ libclickscope/click/preview.cpp 2014-06-18 18:08:01 +0000 |
803 | @@ -57,6 +57,7 @@ |
804 | const unity::scopes::ActionMetadata& metadata, |
805 | const QSharedPointer<click::web::Client>& client, |
806 | const QSharedPointer<click::network::AccessManager>& nam) |
807 | + : PreviewQueryBase(result, metadata) |
808 | { |
809 | strategy.reset(choose_strategy(result, metadata, client, nam)); |
810 | } |
811 | |
812 | === modified file 'libclickscope/click/scope_activation.cpp' |
813 | --- libclickscope/click/scope_activation.cpp 2014-05-28 07:42:24 +0000 |
814 | +++ libclickscope/click/scope_activation.cpp 2014-06-18 18:08:01 +0000 |
815 | @@ -33,6 +33,11 @@ |
816 | #include <click/qtbridge.h> |
817 | #include <unity/scopes/ActivationResponse.h> |
818 | |
819 | +click::ScopeActivation::ScopeActivation(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata) |
820 | + : unity::scopes::ActivationQueryBase(result, metadata) |
821 | +{ |
822 | +} |
823 | + |
824 | unity::scopes::ActivationResponse click::ScopeActivation::activate() |
825 | { |
826 | auto response = unity::scopes::ActivationResponse(status_); |
827 | @@ -50,18 +55,19 @@ |
828 | hints_[key] = value; |
829 | } |
830 | |
831 | -click::PerformUninstallAction::PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActivationResponse& response) |
832 | - : result(result), |
833 | +click::PerformUninstallAction::PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata, const unity::scopes::ActivationResponse& response) |
834 | + : unity::scopes::ActivationQueryBase(result, metadata), |
835 | response(response) |
836 | { |
837 | } |
838 | |
839 | unity::scopes::ActivationResponse click::PerformUninstallAction::activate() |
840 | { |
841 | + auto const res = result(); |
842 | click::Package package; |
843 | - package.title = result.title(); |
844 | - package.name = result["name"].get_string(); |
845 | - package.version = result["version"].get_string(); |
846 | + package.title = res.title(); |
847 | + package.name = res["name"].get_string(); |
848 | + package.version = res["version"].get_string(); |
849 | qt::core::world::enter_with_task([this, package] () |
850 | { |
851 | click::PackageManager manager; |
852 | |
853 | === modified file 'libclickscope/click/scope_activation.h' |
854 | --- libclickscope/click/scope_activation.h 2014-05-28 07:42:24 +0000 |
855 | +++ libclickscope/click/scope_activation.h 2014-06-18 18:08:01 +0000 |
856 | @@ -40,11 +40,10 @@ |
857 | class PerformUninstallAction: public unity::scopes::ActivationQueryBase |
858 | { |
859 | public: |
860 | - PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActivationResponse& response); |
861 | + PerformUninstallAction(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata, const unity::scopes::ActivationResponse& response); |
862 | unity::scopes::ActivationResponse activate() override; |
863 | |
864 | private: |
865 | - unity::scopes::Result result; |
866 | unity::scopes::ActivationResponse response; |
867 | }; |
868 | |
869 | @@ -53,6 +52,7 @@ |
870 | unity::scopes::ActivationResponse activate() override; |
871 | |
872 | public: |
873 | + ScopeActivation(const unity::scopes::Result& result, const unity::scopes::ActionMetadata& metadata); |
874 | void setStatus(unity::scopes::ActivationResponse::Status status); |
875 | void setHint(std::string key, unity::scopes::Variant value); |
876 | |
877 | |
878 | === modified file 'libclickscope/click/webclient.cpp' |
879 | --- libclickscope/click/webclient.cpp 2014-05-23 18:45:01 +0000 |
880 | +++ libclickscope/click/webclient.cpp 2014-06-18 18:08:01 +0000 |
881 | @@ -176,7 +176,8 @@ |
882 | { |
883 | auto message = reply->errorString() + QString(" (%1)").arg(network_error); |
884 | qWarning() << "Network error:" << message << "\n" << reply->readAll(); |
885 | - emit error(message); |
886 | + int error_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); |
887 | + emit error(message, error_code); |
888 | } |
889 | |
890 | void click::web::Response::abort() |
891 | |
892 | === modified file 'libclickscope/click/webclient.h' |
893 | --- libclickscope/click/webclient.h 2014-05-23 18:45:01 +0000 |
894 | +++ libclickscope/click/webclient.h 2014-06-18 18:08:01 +0000 |
895 | @@ -84,7 +84,7 @@ |
896 | |
897 | signals: |
898 | void finished(QByteArray result); |
899 | - void error(QString description); |
900 | + void error(QString description, int error_code); |
901 | |
902 | private: |
903 | QSharedPointer<click::network::Reply> reply; |
904 | |
905 | === modified file 'libclickscope/tests/CMakeLists.txt' |
906 | --- libclickscope/tests/CMakeLists.txt 2014-05-26 14:27:31 +0000 |
907 | +++ libclickscope/tests/CMakeLists.txt 2014-06-18 18:08:01 +0000 |
908 | @@ -28,6 +28,8 @@ |
909 | test_reviews.cpp |
910 | test_smartconnect.cpp |
911 | test_webclient.cpp |
912 | + test_bootstrap.cpp |
913 | + test_departments.cpp |
914 | |
915 | ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp |
916 | ) |
917 | |
918 | === modified file 'libclickscope/tests/fake_json.h' |
919 | --- libclickscope/tests/fake_json.h 2014-06-13 23:18:41 +0000 |
920 | +++ libclickscope/tests/fake_json.h 2014-06-18 18:08:01 +0000 |
921 | @@ -150,6 +150,242 @@ |
922 | } |
923 | )foo"; |
924 | |
925 | +const std::string FAKE_JSON_BOOTSTRAP = R"( |
926 | + { |
927 | + "_embedded": { |
928 | + "clickindex:department": [ |
929 | + { |
930 | + "has_children": false, |
931 | + "_links": { |
932 | + "self": { |
933 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/departments/fake-subdepartment"} |
934 | + }, |
935 | + "name": "Fake Subdepartment", "slug": "fake-subdepartment"} |
936 | + ], |
937 | + "clickindex:highlight": [ |
938 | + { |
939 | + "_embedded": { |
940 | + "clickindex:package": [ |
941 | + { |
942 | + "publisher": "Awesome Widget Company", |
943 | + "name": "org.example.awesomelauncher", |
944 | + "title": "Awesome Launcher", |
945 | + "price": 1.99, |
946 | + "_links": { |
947 | + "self": { |
948 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomelauncher"} |
949 | + }, |
950 | + "icon": "http://example.org/media/org.example.awesomelauncher/icons/icon16.png" |
951 | + }, |
952 | + { |
953 | + "publisher": "Awesome Widget Company", |
954 | + "name": "org.example.awesomewidget", |
955 | + "title": "Awesome Widget", "price": 1.99, |
956 | + "_links": { |
957 | + "self": { |
958 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomewidget" |
959 | + } |
960 | + }, |
961 | + "icon": "http://example.org/media/org.example.awesomewidget/icons/icon16.png"} |
962 | + ] |
963 | + }, |
964 | + "_links": { |
965 | + "self": { |
966 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/highlights/top-apps" |
967 | + } |
968 | + }, |
969 | + "name": "Top Apps", "slug": "top-apps" |
970 | + }, |
971 | + { |
972 | + "_embedded": { |
973 | + "clickindex:package": [ |
974 | + { |
975 | + "publisher": "Awesome Widget Company", |
976 | + "name": "org.example.awesomelauncher", |
977 | + "title": "Awesome Launcher", |
978 | + "price": 1.99, |
979 | + "_links": { |
980 | + "self": { |
981 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomelauncher" |
982 | + } |
983 | + }, |
984 | + "icon": "http://example.org/media/org.example.awesomelauncher/icons/icon16.png" |
985 | + }, |
986 | + { |
987 | + "publisher": "Awesome Widget Company", |
988 | + "name": "org.example.awesomewidget", |
989 | + "title": "Awesome Widget", |
990 | + "price": 1.99, |
991 | + "_links": { |
992 | + "self": { |
993 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomewidget" |
994 | + } |
995 | + }, |
996 | + "icon": "http://example.org/media/org.example.awesomewidget/icons/icon16.png" |
997 | + } |
998 | + ] |
999 | + }, |
1000 | + "_links": { |
1001 | + "self": { |
1002 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/highlights/most-purchased" |
1003 | + } |
1004 | + }, |
1005 | + "name": "Most Purchased", |
1006 | + "slug": "most-purchased" |
1007 | + }, |
1008 | + { |
1009 | + "_embedded": { |
1010 | + "clickindex:package": [ |
1011 | + { |
1012 | + "publisher": "Awesome Widget Company", |
1013 | + "name": "org.example.awesomelauncher", |
1014 | + "title": "Awesome Launcher", |
1015 | + "price": 1.99, |
1016 | + "_links": { |
1017 | + "self": { |
1018 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomelauncher" |
1019 | + } |
1020 | + }, |
1021 | + "icon": "http://example.org/media/org.example.awesomelauncher/icons/icon16.png" |
1022 | + }, |
1023 | + { |
1024 | + "publisher": "Awesome Widget Company", |
1025 | + "name": "org.example.awesomewidget", |
1026 | + "title": "Awesome Widget", |
1027 | + "price": 1.99, |
1028 | + "_links": { |
1029 | + "self": { |
1030 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/package/org.example.awesomewidget" |
1031 | + } |
1032 | + }, |
1033 | + "icon": "http://example.org/media/org.example.awesomewidget/icons/icon16.png" |
1034 | + } |
1035 | + ] |
1036 | + }, |
1037 | + "_links": { |
1038 | + "self": { |
1039 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/highlights/new-releases" |
1040 | + } |
1041 | + }, |
1042 | + "name": "New Releases", |
1043 | + "slug": "new-releases" |
1044 | + } |
1045 | + ] |
1046 | + }, "has_children": true, |
1047 | + "_links": { |
1048 | + "curies": [ |
1049 | + { |
1050 | + "href": "https://search.apps.staging.ubuntu.com/docs/v1/relations.html{#rel}", |
1051 | + "name": "clickindex", "templated": true |
1052 | + } |
1053 | + ], |
1054 | + "self": { |
1055 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/departments/fake-department-with-subdepartments" |
1056 | + }, |
1057 | + "collection": { |
1058 | + "href": "https://search.apps.staging.ubuntu.com/api/v1/departments" |
1059 | + } |
1060 | + }, |
1061 | + "name": "Fake Department With Subdepartments", |
1062 | + "slug": "fake-department-with-subdepartments" |
1063 | + })"; |
1064 | + |
1065 | +const std::string FAKE_JSON_DEPARTMENTS_ONLY = R"( |
1066 | + { |
1067 | + "_links": { |
1068 | + "self": { |
1069 | + "href": "https://search.apps.ubuntu.com/api/v1/departments" |
1070 | + }, |
1071 | + "curies": [ |
1072 | + { |
1073 | + "name": "clickindex", |
1074 | + "href": "https://search.apps.ubuntu.com/docs/v1/relations.html{#rel}", |
1075 | + "templated": true |
1076 | + } |
1077 | + ] |
1078 | + }, |
1079 | + "_embedded": { |
1080 | + "clickindex:department": [ |
1081 | + { |
1082 | + "name": "Games", |
1083 | + "_links": { |
1084 | + "self": { |
1085 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Games" |
1086 | + } |
1087 | + }, |
1088 | + "_embedded": { |
1089 | + "clickindex:department": [ |
1090 | + { |
1091 | + "name": "Board Games", |
1092 | + "_links": { |
1093 | + "self": { |
1094 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Games/Board+Games" |
1095 | + } |
1096 | + } |
1097 | + } |
1098 | + ] |
1099 | + } |
1100 | + }, |
1101 | + { |
1102 | + "name": "Graphics", |
1103 | + "_links": { |
1104 | + "self": { |
1105 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Graphics" |
1106 | + } |
1107 | + }, |
1108 | + "_embedded": { |
1109 | + "clickindex:department": [ |
1110 | + { |
1111 | + "name": "Drawing", |
1112 | + "_links": { |
1113 | + "self": { |
1114 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Graphics/Drawing" |
1115 | + } |
1116 | + } |
1117 | + } |
1118 | + ] |
1119 | + } |
1120 | + }, |
1121 | + { |
1122 | + "name": "Internet", |
1123 | + "_links": { |
1124 | + "self": { |
1125 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Internet" |
1126 | + } |
1127 | + }, |
1128 | + "_embedded": { |
1129 | + "clickindex:department": [ |
1130 | + { |
1131 | + "name": "Chat", |
1132 | + "_links": { |
1133 | + "self": { |
1134 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Internet/Chat" |
1135 | + } |
1136 | + } |
1137 | + }, |
1138 | + { |
1139 | + "name": "Mail", |
1140 | + "_links": { |
1141 | + "self": { |
1142 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Internet/Mail" |
1143 | + } |
1144 | + } |
1145 | + }, |
1146 | + { |
1147 | + "name": "Web Browsers", |
1148 | + "_links": { |
1149 | + "self": { |
1150 | + "href": "https://search.apps.ubuntu.com/api/v1/departments/Internet/Web+Browsers" |
1151 | + } |
1152 | + } |
1153 | + } |
1154 | + ] |
1155 | + } |
1156 | + } |
1157 | + ] |
1158 | + } |
1159 | +})"; |
1160 | + |
1161 | const std::string FAKE_JSON_MANIFEST_REMOVABLE = R"foo( |
1162 | { |
1163 | "_removable": 1, |
1164 | |
1165 | === modified file 'libclickscope/tests/mock_network_access_manager.h' |
1166 | --- libclickscope/tests/mock_network_access_manager.h 2014-05-20 19:33:41 +0000 |
1167 | +++ libclickscope/tests/mock_network_access_manager.h 2014-06-18 18:08:01 +0000 |
1168 | @@ -48,6 +48,7 @@ |
1169 | { |
1170 | // Set a default value for QByteArray-returning mocked methods. |
1171 | ::testing::DefaultValue<QByteArray>::Set(QByteArray("")); |
1172 | + ON_CALL(*this, attribute(::testing::_)).WillByDefault(::testing::Return(0)); |
1173 | } |
1174 | |
1175 | MOCK_METHOD0(abort, void()); |
1176 | |
1177 | === modified file 'libclickscope/tests/mock_webclient.h' |
1178 | --- libclickscope/tests/mock_webclient.h 2014-05-23 18:45:01 +0000 |
1179 | +++ libclickscope/tests/mock_webclient.h 2014-06-18 18:08:01 +0000 |
1180 | @@ -86,7 +86,7 @@ |
1181 | const click::web::CallParams& params)); |
1182 | QSharedPointer<click::web::Response> call( |
1183 | const std::string& iri, |
1184 | - const click::web::CallParams& params=click::web::CallParams()) { |
1185 | + const click::web::CallParams& params=click::web::CallParams()) override { |
1186 | return callImpl(iri, "GET", false, |
1187 | std::map<std::string, std::string>(), "", params); |
1188 | } |
1189 | @@ -96,7 +96,7 @@ |
1190 | bool sign = false, |
1191 | const std::map<std::string, std::string>& headers = std::map<std::string, std::string>(), |
1192 | const std::string& data = "", |
1193 | - const click::web::CallParams& params=click::web::CallParams()) { |
1194 | + const click::web::CallParams& params=click::web::CallParams()) override { |
1195 | return callImpl(iri, method, sign, headers, data, params); |
1196 | } |
1197 | }; |
1198 | |
1199 | === added file 'libclickscope/tests/test_bootstrap.cpp' |
1200 | --- libclickscope/tests/test_bootstrap.cpp 1970-01-01 00:00:00 +0000 |
1201 | +++ libclickscope/tests/test_bootstrap.cpp 2014-06-18 18:08:01 +0000 |
1202 | @@ -0,0 +1,73 @@ |
1203 | +/* |
1204 | + * Copyright (C) 2014 Canonical Ltd. |
1205 | + * |
1206 | + * This program is free software: you can redistribute it and/or modify it |
1207 | + * under the terms of the GNU General Public License version 3, as published |
1208 | + * by the Free Software Foundation. |
1209 | + * |
1210 | + * This program is distributed in the hope that it will be useful, but |
1211 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1212 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1213 | + * PURPOSE. See the GNU General Public License for more details. |
1214 | + * |
1215 | + * You should have received a copy of the GNU General Public License along |
1216 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1217 | + * |
1218 | + * In addition, as a special exception, the copyright holders give |
1219 | + * permission to link the code of portions of this program with the |
1220 | + * OpenSSL library under certain conditions as described in each |
1221 | + * individual source file, and distribute linked combinations |
1222 | + * including the two. |
1223 | + * You must obey the GNU General Public License in all respects |
1224 | + * for all of the code used other than OpenSSL. If you modify |
1225 | + * file(s) with this exception, you may extend this exception to your |
1226 | + * version of the file(s), but you are not obligated to do so. If you |
1227 | + * do not wish to do so, delete this exception statement from your |
1228 | + * version. If you delete this exception statement from all source |
1229 | + * files in the program, then also delete it here. |
1230 | + */ |
1231 | + |
1232 | +#include <gtest/gtest.h> |
1233 | +#include "fake_json.h" |
1234 | +#include <json/reader.h> |
1235 | +#include <json/value.h> |
1236 | +#include <click/highlights.h> |
1237 | +#include <click/departments.h> |
1238 | + |
1239 | +class BootstrapTest: public ::testing::Test |
1240 | +{ |
1241 | + protected: |
1242 | + void SetUp() override |
1243 | + { |
1244 | + } |
1245 | +}; |
1246 | + |
1247 | +TEST_F(BootstrapTest, testParsing) |
1248 | +{ |
1249 | + Json::Reader reader; |
1250 | + Json::Value root; |
1251 | + |
1252 | + EXPECT_TRUE(reader.parse(FAKE_JSON_BOOTSTRAP, root)); |
1253 | + |
1254 | + { |
1255 | + auto highlights = click::Highlight::from_json_root_node(root); |
1256 | + EXPECT_EQ(3u, highlights.size()); |
1257 | + auto it = highlights.begin(); |
1258 | + EXPECT_EQ("Top Apps", it->name()); |
1259 | + EXPECT_EQ(2u, it->packages().size()); |
1260 | + ++it; |
1261 | + EXPECT_EQ("Most Purchased", it->name()); |
1262 | + EXPECT_EQ(2u, it->packages().size()); |
1263 | + ++it; |
1264 | + EXPECT_EQ("New Releases", it->name()); |
1265 | + EXPECT_EQ(2u, it->packages().size()); |
1266 | + } |
1267 | + { |
1268 | + auto depts = click::Department::from_json_root_node(root); |
1269 | + EXPECT_EQ(1u, depts.size()); |
1270 | + auto it = depts.begin(); |
1271 | + EXPECT_EQ("Fake Subdepartment", (*it)->name()); |
1272 | + EXPECT_FALSE((*it)->has_children_flag()); |
1273 | + EXPECT_EQ("https://search.apps.staging.ubuntu.com/api/v1/departments/fake-subdepartment", (*it)->href()); |
1274 | + } |
1275 | +} |
1276 | |
1277 | === removed file 'libclickscope/tests/test_data.cpp' |
1278 | === added file 'libclickscope/tests/test_departments.cpp' |
1279 | --- libclickscope/tests/test_departments.cpp 1970-01-01 00:00:00 +0000 |
1280 | +++ libclickscope/tests/test_departments.cpp 2014-06-18 18:08:01 +0000 |
1281 | @@ -0,0 +1,108 @@ |
1282 | +/* |
1283 | + * Copyright (C) 2014 Canonical Ltd. |
1284 | + * |
1285 | + * This program is free software: you can redistribute it and/or modify it |
1286 | + * under the terms of the GNU General Public License version 3, as published |
1287 | + * by the Free Software Foundation. |
1288 | + * |
1289 | + * This program is distributed in the hope that it will be useful, but |
1290 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1291 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1292 | + * PURPOSE. See the GNU General Public License for more details. |
1293 | + * |
1294 | + * You should have received a copy of the GNU General Public License along |
1295 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1296 | + * |
1297 | + * In addition, as a special exception, the copyright holders give |
1298 | + * permission to link the code of portions of this program with the |
1299 | + * OpenSSL library under certain conditions as described in each |
1300 | + * individual source file, and distribute linked combinations |
1301 | + * including the two. |
1302 | + * You must obey the GNU General Public License in all respects |
1303 | + * for all of the code used other than OpenSSL. If you modify |
1304 | + * file(s) with this exception, you may extend this exception to your |
1305 | + * version of the file(s), but you are not obligated to do so. If you |
1306 | + * do not wish to do so, delete this exception statement from your |
1307 | + * version. If you delete this exception statement from all source |
1308 | + * files in the program, then also delete it here. |
1309 | + */ |
1310 | + |
1311 | +#include <gtest/gtest.h> |
1312 | +#include "fake_json.h" |
1313 | +#include <click/departments.h> |
1314 | +#include <click/department-lookup.h> |
1315 | + |
1316 | +class DepartmentsTest : public ::testing::Test |
1317 | +{ |
1318 | + protected: |
1319 | + void SetUp() override |
1320 | + { |
1321 | + } |
1322 | +}; |
1323 | + |
1324 | +TEST_F(DepartmentsTest, testParsing) |
1325 | +{ |
1326 | + const std::string jsonstr(FAKE_JSON_DEPARTMENTS_ONLY); |
1327 | + auto depts = click::Department::from_json(jsonstr); |
1328 | + EXPECT_EQ(3u, depts.size()); |
1329 | + auto it = depts.cbegin(); |
1330 | + { |
1331 | + auto dep = *it; |
1332 | + EXPECT_EQ("Games", dep->id()); |
1333 | + EXPECT_EQ("Games", dep->name()); |
1334 | + EXPECT_FALSE(dep->has_children_flag()); |
1335 | + auto subdepts = dep->sub_departments(); |
1336 | + EXPECT_EQ(1u, subdepts.size()); |
1337 | + auto sit = subdepts.cbegin(); |
1338 | + EXPECT_EQ("Board Games", (*sit)->name()); |
1339 | + } |
1340 | + { |
1341 | + ++it; |
1342 | + auto dep = *it; |
1343 | + EXPECT_EQ("Graphics", dep->id()); |
1344 | + EXPECT_EQ("Graphics", dep->name()); |
1345 | + EXPECT_FALSE(dep->has_children_flag()); |
1346 | + auto subdepts = dep->sub_departments(); |
1347 | + EXPECT_EQ(1u, subdepts.size()); |
1348 | + auto sit = subdepts.cbegin(); |
1349 | + EXPECT_EQ("Drawing", (*sit)->name()); |
1350 | + } |
1351 | + { |
1352 | + ++it; |
1353 | + auto dep = *it; |
1354 | + EXPECT_EQ("Internet", dep->id()); |
1355 | + EXPECT_EQ("Internet", dep->name()); |
1356 | + EXPECT_FALSE(dep->has_children_flag()); |
1357 | + auto subdepts = dep->sub_departments(); |
1358 | + EXPECT_EQ(3u, subdepts.size()); |
1359 | + auto sit = subdepts.cbegin(); |
1360 | + auto subdep = *sit; |
1361 | + EXPECT_EQ("Chat", subdep->name()); |
1362 | + subdep = *(++sit); |
1363 | + EXPECT_EQ("Mail", subdep->name()); |
1364 | + subdep = *(++sit); |
1365 | + EXPECT_EQ("Web Browsers", subdep->name()); |
1366 | + } |
1367 | +} |
1368 | + |
1369 | +TEST_F(DepartmentsTest, testLookup) |
1370 | +{ |
1371 | + auto dep_games = std::make_shared<click::Department>("games", "Games", "", false); |
1372 | + auto dep_rpg = std::make_shared<click::Department>("rpg", "RPG", "", false); |
1373 | + auto dep_strategy = std::make_shared<click::Department>("strategy", "Strategy", "", false); |
1374 | + const std::list<click::Department::SPtr> departments {dep_rpg, dep_strategy}; |
1375 | + dep_games->set_subdepartments(departments); |
1376 | + |
1377 | + const std::list<click::Department::SPtr> root {dep_games}; |
1378 | + click::DepartmentLookup lut; |
1379 | + lut.rebuild(root); |
1380 | + |
1381 | + EXPECT_EQ(2u, lut.size()); |
1382 | + EXPECT_EQ("games", lut.get_parent("strategy")->id()); |
1383 | + EXPECT_EQ("games", lut.get_parent("rpg")->id()); |
1384 | + EXPECT_EQ(nullptr, lut.get_parent("games")); |
1385 | + |
1386 | + lut.rebuild(root); |
1387 | + EXPECT_EQ(2u, lut.size()); |
1388 | +} |
1389 | + |
1390 | |
1391 | === modified file 'libclickscope/tests/test_index.cpp' |
1392 | --- libclickscope/tests/test_index.cpp 2014-06-12 21:05:25 +0000 |
1393 | +++ libclickscope/tests/test_index.cpp 2014-06-18 18:08:01 +0000 |
1394 | @@ -52,8 +52,8 @@ |
1395 | click::Index(client, configuration) |
1396 | { |
1397 | } |
1398 | - MOCK_METHOD1(build_index_query, std::string(const std::string&)); |
1399 | MOCK_METHOD0(build_headers, std::map<std::string, std::string>()); |
1400 | + MOCK_METHOD2(build_index_query, std::string(const std::string&, const std::string&)); |
1401 | }; |
1402 | |
1403 | class MockConfiguration : public click::Configuration { |
1404 | @@ -100,7 +100,7 @@ |
1405 | .Times(1) |
1406 | .WillOnce(Return(response)); |
1407 | |
1408 | - indexPtr->search("", [](click::Packages) {}); |
1409 | + indexPtr->search("", "", [](click::Packages, click::DepartmentList) {}); |
1410 | } |
1411 | |
1412 | TEST_F(IndexTest, testSearchSendsBuiltQueryAsParam) |
1413 | @@ -116,11 +116,11 @@ |
1414 | .Times(1) |
1415 | .WillOnce(Return(response)); |
1416 | |
1417 | - EXPECT_CALL(*indexPtr, build_index_query(FAKE_QUERY)) |
1418 | + EXPECT_CALL(*indexPtr, build_index_query(FAKE_QUERY, "")) |
1419 | .Times(1) |
1420 | .WillOnce(Return(FAKE_BUILT_QUERY)); |
1421 | |
1422 | - indexPtr->search(FAKE_QUERY, [](click::Packages) {}); |
1423 | + indexPtr->search(FAKE_QUERY, "", [](click::Packages, click::DepartmentList) {}); |
1424 | } |
1425 | |
1426 | TEST_F(IndexTest, testSearchSendsRightPath) |
1427 | @@ -133,7 +133,7 @@ |
1428 | .Times(1) |
1429 | .WillOnce(Return(response)); |
1430 | |
1431 | - indexPtr->search("", [](click::Packages) {}); |
1432 | + indexPtr->search("", "", [](click::Packages, click::DepartmentList) {}); |
1433 | } |
1434 | |
1435 | TEST_F(IndexTest, testSearchCallbackIsCalled) |
1436 | @@ -150,7 +150,7 @@ |
1437 | .WillOnce(Return(response)); |
1438 | EXPECT_CALL(*this, search_callback(_)).Times(1); |
1439 | |
1440 | - indexPtr->search("", [this](click::Packages packages){ |
1441 | + indexPtr->search("", "", [this](click::Packages packages, click::DepartmentList){ |
1442 | search_callback(packages); |
1443 | }); |
1444 | response->replyFinished(); |
1445 | @@ -171,7 +171,7 @@ |
1446 | click::Packages empty_package_list; |
1447 | EXPECT_CALL(*this, search_callback(empty_package_list)).Times(1); |
1448 | |
1449 | - indexPtr->search("", [this](click::Packages packages){ |
1450 | + indexPtr->search("", "", [this](click::Packages packages, click::DepartmentList){ |
1451 | search_callback(packages); |
1452 | }); |
1453 | response->replyFinished(); |
1454 | @@ -200,7 +200,7 @@ |
1455 | }; |
1456 | EXPECT_CALL(*this, search_callback(single_package_list)).Times(1); |
1457 | |
1458 | - indexPtr->search("", [this](click::Packages packages){ |
1459 | + indexPtr->search("", "", [this](click::Packages packages, click::DepartmentList){ |
1460 | search_callback(packages); |
1461 | }); |
1462 | response->replyFinished(); |
1463 | @@ -215,7 +215,7 @@ |
1464 | .Times(1) |
1465 | .WillOnce(Return(response)); |
1466 | |
1467 | - auto search_operation = indexPtr->search("", [](click::Packages) {}); |
1468 | + auto search_operation = indexPtr->search("", "", [](click::Packages, click::DepartmentList) {}); |
1469 | EXPECT_CALL(reply.instance, abort()).Times(1); |
1470 | search_operation.cancel(); |
1471 | } |
1472 | @@ -234,7 +234,7 @@ |
1473 | .Times(1) |
1474 | .WillOnce(Return(response)); |
1475 | EXPECT_CALL(reply.instance, errorString()).Times(1).WillOnce(Return("fake error")); |
1476 | - indexPtr->search("", [this](click::Packages packages){ |
1477 | + indexPtr->search("", "", [this](click::Packages packages, click::DepartmentList){ |
1478 | search_callback(packages); |
1479 | }); |
1480 | |
1481 | |
1482 | === modified file 'scope/clickapps/apps-query.cpp' |
1483 | --- scope/clickapps/apps-query.cpp 2014-06-10 21:09:52 +0000 |
1484 | +++ scope/clickapps/apps-query.cpp 2014-06-18 18:08:01 +0000 |
1485 | @@ -128,25 +128,24 @@ |
1486 | |
1487 | struct click::Query::Private |
1488 | { |
1489 | - Private(const unity::scopes::CannedQuery& query, click::Index& index, const scopes::SearchMetadata& metadata) |
1490 | - : query(query), |
1491 | - index(index), |
1492 | + Private(click::Index& index, const scopes::SearchMetadata& metadata) |
1493 | + : index(index), |
1494 | meta(metadata) |
1495 | { |
1496 | } |
1497 | - unity::scopes::CannedQuery query; |
1498 | click::Index& index; |
1499 | scopes::SearchMetadata meta; |
1500 | }; |
1501 | |
1502 | click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata) |
1503 | - : impl(new Private(query, index, metadata)) |
1504 | + : unity::scopes::SearchQueryBase(query, metadata), |
1505 | + impl(new Private(index, metadata)) |
1506 | { |
1507 | } |
1508 | |
1509 | void click::Query::cancelled() |
1510 | { |
1511 | - qDebug() << "cancelling search of" << QString::fromStdString(impl->query.query_string()); |
1512 | + qDebug() << "cancelling search of" << QString::fromStdString(query().query_string()); |
1513 | } |
1514 | |
1515 | click::Query::~Query() |
1516 | @@ -171,10 +170,10 @@ |
1517 | static const std::string title = _("Get more apps in Ubuntu store"); |
1518 | auto name = title; |
1519 | |
1520 | - std::string query = impl->query.query_string(); |
1521 | - std::transform(query.begin(), query.end(), query.begin(), ::tolower); |
1522 | + std::string querystr = query().query_string(); |
1523 | + std::transform(querystr.begin(), querystr.end(), querystr.begin(), ::tolower); |
1524 | std::transform(name.begin(), name.end(), name.begin(), ::tolower); |
1525 | - if (query.empty() || name.find(query) != std::string::npos) |
1526 | + if (querystr.empty() || name.find(querystr) != std::string::npos) |
1527 | { |
1528 | scopes::CategoryRenderer rdr(CATEGORY_STORE); |
1529 | auto cat = searchReply->register_category("store", "", "", rdr); |
1530 | @@ -196,13 +195,13 @@ |
1531 | |
1532 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) |
1533 | { |
1534 | - auto query = impl->query.query_string(); |
1535 | + auto querystr = query().query_string(); |
1536 | std::string categoryTemplate = CATEGORY_APPS_SEARCH; |
1537 | - if (query.empty()) { |
1538 | + if (querystr.empty()) { |
1539 | categoryTemplate = CATEGORY_APPS_DISPLAY; |
1540 | } |
1541 | auto localResults = clickInterfaceInstance().find_installed_apps( |
1542 | - query); |
1543 | + querystr); |
1544 | |
1545 | push_local_results( |
1546 | searchReply, |
1547 | |
1548 | === modified file 'scope/clickapps/apps-scope.cpp' |
1549 | --- scope/clickapps/apps-scope.cpp 2014-06-12 14:26:26 +0000 |
1550 | +++ scope/clickapps/apps-scope.cpp 2014-06-18 18:08:01 +0000 |
1551 | @@ -54,13 +54,11 @@ |
1552 | { |
1553 | } |
1554 | |
1555 | -int click::Scope::start(std::string const&, scopes::RegistryProxy const&) |
1556 | +void click::Scope::start(std::string const&, scopes::RegistryProxy const&) |
1557 | { |
1558 | setlocale(LC_ALL, ""); |
1559 | bindtextdomain(GETTEXT_PACKAGE, GETTEXT_LOCALEDIR); |
1560 | bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); |
1561 | - |
1562 | - return VERSION; |
1563 | } |
1564 | |
1565 | void click::Scope::run() |
1566 | @@ -91,14 +89,15 @@ |
1567 | } |
1568 | |
1569 | |
1570 | -unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& /* widget_id */, std::string const& action_id) |
1571 | +unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, |
1572 | + std::string const& /* widget_id */, std::string const& action_id) |
1573 | { |
1574 | if (action_id == click::Preview::Actions::CONFIRM_UNINSTALL) { |
1575 | const unity::scopes::CannedQuery cquery("clickscope"); |
1576 | - return scopes::ActivationQueryBase::UPtr(new PerformUninstallAction(result, unity::scopes::ActivationResponse(cquery))); |
1577 | + return scopes::ActivationQueryBase::UPtr(new PerformUninstallAction(result, metadata, unity::scopes::ActivationResponse(cquery))); |
1578 | } |
1579 | |
1580 | - auto activation = new ScopeActivation(); |
1581 | + auto activation = new ScopeActivation(result, metadata); |
1582 | qDebug() << "perform_action called with action_id" << QString().fromStdString(action_id); |
1583 | |
1584 | if (action_id == click::Preview::Actions::UNINSTALL_CLICK) { |
1585 | |
1586 | === modified file 'scope/clickapps/apps-scope.h' |
1587 | --- scope/clickapps/apps-scope.h 2014-05-27 06:57:52 +0000 |
1588 | +++ scope/clickapps/apps-scope.h 2014-06-18 18:08:01 +0000 |
1589 | @@ -49,14 +49,14 @@ |
1590 | Scope(); |
1591 | ~Scope(); |
1592 | |
1593 | - virtual int start(std::string const&, scopes::RegistryProxy const&) override; |
1594 | + virtual void start(std::string const&, scopes::RegistryProxy const&) override; |
1595 | |
1596 | virtual void run() override; |
1597 | virtual void stop() override; |
1598 | |
1599 | - virtual scopes::SearchQueryBase::UPtr search(scopes::CannedQuery const& q, scopes::SearchMetadata const&) override; |
1600 | + virtual scopes::SearchQueryBase::UPtr search(scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) override; |
1601 | unity::scopes::PreviewQueryBase::UPtr preview(const unity::scopes::Result&, |
1602 | - const unity::scopes::ActionMetadata&) override; |
1603 | + const unity::scopes::ActionMetadata& hints) override; |
1604 | |
1605 | virtual unity::scopes::ActivationQueryBase::UPtr perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id) override; |
1606 | |
1607 | |
1608 | === modified file 'scope/clickstore/store-query.cpp' |
1609 | --- scope/clickstore/store-query.cpp 2014-06-13 23:18:41 +0000 |
1610 | +++ scope/clickstore/store-query.cpp 2014-06-18 18:08:01 +0000 |
1611 | @@ -30,6 +30,7 @@ |
1612 | #include <click/application.h> |
1613 | #include <click/interface.h> |
1614 | #include "store-query.h" |
1615 | +#include "store-scope.h" |
1616 | #include <click/qtbridge.h> |
1617 | |
1618 | #include <click/key_file_locator.h> |
1619 | @@ -37,6 +38,7 @@ |
1620 | #include <unity/scopes/Annotation.h> |
1621 | #include <unity/scopes/CategoryRenderer.h> |
1622 | #include <unity/scopes/CategorisedResult.h> |
1623 | +#include <unity/scopes/Department.h> |
1624 | #include <unity/scopes/CannedQuery.h> |
1625 | #include <unity/scopes/SearchReply.h> |
1626 | #include <unity/scopes/SearchMetadata.h> |
1627 | @@ -93,20 +95,26 @@ |
1628 | |
1629 | struct click::Query::Private |
1630 | { |
1631 | - Private(const unity::scopes::CannedQuery& query, click::Index& index, const scopes::SearchMetadata& metadata) |
1632 | - : query(query), |
1633 | - index(index), |
1634 | + Private(click::Index& index, click::DepartmentLookup& depts, |
1635 | + click::HighlightList& highlights, const scopes::SearchMetadata& metadata) |
1636 | + : index(index), |
1637 | + department_lookup(depts), |
1638 | + highlights(highlights), |
1639 | meta(metadata) |
1640 | { |
1641 | } |
1642 | - unity::scopes::CannedQuery query; |
1643 | click::Index& index; |
1644 | + click::DepartmentLookup& department_lookup; |
1645 | + click::HighlightList& highlights; |
1646 | scopes::SearchMetadata meta; |
1647 | click::web::Cancellable search_operation; |
1648 | }; |
1649 | |
1650 | -click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata) |
1651 | - : impl(new Private(query, index, metadata)) |
1652 | +click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& depts, |
1653 | + click::HighlightList& highlights, |
1654 | + scopes::SearchMetadata const& metadata) |
1655 | + : unity::scopes::SearchQueryBase(query, metadata), |
1656 | + impl(new Private(index, depts, highlights, metadata)) |
1657 | { |
1658 | } |
1659 | |
1660 | @@ -117,7 +125,7 @@ |
1661 | |
1662 | void click::Query::cancelled() |
1663 | { |
1664 | - qDebug() << "cancelling search of" << QString::fromStdString(impl->query.query_string()); |
1665 | + qDebug() << "cancelling search of" << QString::fromStdString(query().query_string()); |
1666 | impl->search_operation.cancel(); |
1667 | } |
1668 | |
1669 | @@ -155,6 +163,166 @@ |
1670 | }); |
1671 | } |
1672 | |
1673 | +// |
1674 | +// creates department menu with narrowed-down list of subdepartments of current department, as |
1675 | +// returned by server call |
1676 | +void click::Query::populate_departments(const click::DepartmentList& subdepts, const std::string& current_dep_id, unity::scopes::Department::SPtr &root) |
1677 | +{ |
1678 | + unity::scopes::DepartmentList departments; |
1679 | + |
1680 | + // create a list of subdepartments of current department |
1681 | + foreach (auto d, subdepts) |
1682 | + { |
1683 | + unity::scopes::Department::SPtr department = unity::scopes::Department::create(d->id(), query(), d->name()); |
1684 | + if (d->has_children_flag()) |
1685 | + { |
1686 | + department->set_has_subdepartments(); |
1687 | + } |
1688 | + departments.push_back(department); |
1689 | + } |
1690 | + |
1691 | + if (current_dep_id != "") |
1692 | + { |
1693 | + auto curr_dpt = impl->department_lookup.get_department_info(current_dep_id); |
1694 | + if (curr_dpt != nullptr) |
1695 | + { |
1696 | + unity::scopes::Department::SPtr current = unity::scopes::Department::create(current_dep_id, query(), curr_dpt->name()); |
1697 | + if (departments.size() > 0) // this may be a leaf department |
1698 | + { |
1699 | + current->set_subdepartments(departments); |
1700 | + } |
1701 | + |
1702 | + auto parent_info = impl->department_lookup.get_parent(current_dep_id); |
1703 | + if (parent_info != nullptr) |
1704 | + { |
1705 | + root = unity::scopes::Department::create(parent_info->id(), query(), parent_info->name()); |
1706 | + root->set_subdepartments({current}); |
1707 | + return; |
1708 | + } |
1709 | + else |
1710 | + { |
1711 | + root = unity::scopes::Department::create("", query(), _("All departments")); |
1712 | + root->set_subdepartments({current}); |
1713 | + return; |
1714 | + } |
1715 | + } |
1716 | + else |
1717 | + { |
1718 | + qWarning() << "Unknown department:" << QString::fromStdString(current_dep_id); |
1719 | + } |
1720 | + } |
1721 | + |
1722 | + root = unity::scopes::Department::create("", query(), _("All departments")); |
1723 | + root->set_subdepartments(departments); |
1724 | +} |
1725 | + |
1726 | +void click::Query::push_package(const scopes::SearchReplyProxy& searchReply, scopes::Category::SCPtr category, const PackageSet &installedPackages, const Package& pkg) |
1727 | +{ |
1728 | + qDebug() << "pushing result" << QString::fromStdString(pkg.name); |
1729 | + try { |
1730 | + scopes::CategorisedResult res(category); |
1731 | + res.set_title(pkg.title); |
1732 | + res.set_art(pkg.icon_url); |
1733 | + res.set_uri(pkg.url); |
1734 | + res[click::Query::ResultKeys::NAME] = pkg.name; |
1735 | + auto installed = installedPackages.find(pkg); |
1736 | + if (installed != installedPackages.end()) { |
1737 | + res[click::Query::ResultKeys::INSTALLED] = true; |
1738 | + res["subtitle"] = _("✔ INSTALLED"); |
1739 | + res[click::Query::ResultKeys::VERSION] = installed->version; |
1740 | + } else { |
1741 | + res[click::Query::ResultKeys::INSTALLED] = false; |
1742 | + // TODO: get the real price from the webservice (upcoming branch) |
1743 | + res["subtitle"] = _("FREE"); |
1744 | + } |
1745 | + |
1746 | + this->push_result(searchReply, res); |
1747 | + } catch(const std::exception& e){ |
1748 | + qDebug() << "PackageDetails::loadJson: Exception thrown while decoding JSON: " << e.what() ; |
1749 | + } catch(...){ |
1750 | + qDebug() << "no reason to catch"; |
1751 | + } |
1752 | +} |
1753 | + |
1754 | +void click::Query::push_highlights(const scopes::SearchReplyProxy& searchReply, const HighlightList& highlights, const PackageSet &locallyInstalledApps) |
1755 | +{ |
1756 | + std::string categoryTemplate = CATEGORY_APPS_DISPLAY; //FIXME |
1757 | + scopes::CategoryRenderer renderer(categoryTemplate); |
1758 | + |
1759 | + for (auto const& hl: highlights) |
1760 | + { |
1761 | + auto category = register_category(searchReply, hl.name(), hl.name(), "", renderer); //FIXME: highlight slug |
1762 | + for (auto const& pkg: hl.packages()) |
1763 | + { |
1764 | + push_package(searchReply, category, locallyInstalledApps, pkg); |
1765 | + } |
1766 | + } |
1767 | + qDebug() << "Highlights pushed"; |
1768 | +} |
1769 | + |
1770 | +void click::Query::push_departments(const scopes::SearchReplyProxy& searchReply, const scopes::Department::SCPtr& root) |
1771 | +{ |
1772 | + if (root != nullptr) |
1773 | + { |
1774 | + try |
1775 | + { |
1776 | + qDebug() << "pushing departments"; |
1777 | + searchReply->register_departments(root); |
1778 | + } |
1779 | + catch (const std::exception& e) |
1780 | + { |
1781 | + qWarning() << "Failed to register departments for query " << QString::fromStdString(query().query_string()) << |
1782 | + ", current department " << QString::fromStdString(query().department_id()) << ": " << e.what(); |
1783 | + } |
1784 | + } |
1785 | + else |
1786 | + { |
1787 | + qWarning() << "No departments data for query " << QString::fromStdString(query().query_string()) << |
1788 | + "', current department " << QString::fromStdString(query().department_id()); |
1789 | + } |
1790 | +} |
1791 | + |
1792 | +// |
1793 | +// push highlights and departments |
1794 | +// use cached highlights for root department, otherwise run an async job for highlights of current department. |
1795 | +void click::Query::add_highlights(scopes::SearchReplyProxy const& searchReply, const PackageSet& locallyInstalledApps) |
1796 | +{ |
1797 | + auto curdep = impl->department_lookup.get_department_info(query().department_id()); |
1798 | + assert(curdep); |
1799 | + auto subdepts = curdep->sub_departments(); |
1800 | + if (query().department_id() == "") // top-level departments |
1801 | + { |
1802 | + unity::scopes::Department::SPtr root; |
1803 | + populate_departments(subdepts, query().department_id(), root); |
1804 | + push_departments(searchReply, root); |
1805 | + |
1806 | + qDebug() << "pushing cached highlights"; |
1807 | + push_highlights(searchReply, impl->highlights, locallyInstalledApps); |
1808 | + this->finished(searchReply); //FIXME: this shouldn't be needed |
1809 | + } |
1810 | + else |
1811 | + { |
1812 | + qDebug() << "starting departments call for department" << QString::fromStdString(curdep->id()) << ", href" << QString::fromStdString(curdep->href()); |
1813 | + impl->search_operation = impl->index.departments(curdep->href(), [this, locallyInstalledApps, searchReply](const DepartmentList& depts, |
1814 | + const HighlightList& highlights, Index::Error error) |
1815 | + { |
1816 | + if (error == click::Index::Error::NoError) |
1817 | + { |
1818 | + qDebug() << "departments call completed"; |
1819 | + unity::scopes::Department::SPtr root; |
1820 | + populate_departments(depts, query().department_id(), root); |
1821 | + push_departments(searchReply, root); |
1822 | + push_highlights(searchReply, highlights, locallyInstalledApps); |
1823 | + } |
1824 | + else |
1825 | + { |
1826 | + qWarning() << "departments call failed"; |
1827 | + } |
1828 | + this->finished(searchReply); //FIXME: this shouldn't be needed |
1829 | + }); |
1830 | + } |
1831 | +} |
1832 | + |
1833 | void click::Query::add_available_apps(scopes::SearchReplyProxy const& searchReply, |
1834 | const PackageSet& installedPackages, |
1835 | const std::string& categoryTemplate) |
1836 | @@ -162,12 +330,14 @@ |
1837 | scopes::CategoryRenderer categoryRenderer(categoryTemplate); |
1838 | auto category = register_category(searchReply, "appstore", _("Available"), "", categoryRenderer); |
1839 | |
1840 | + assert(searchReply); |
1841 | + |
1842 | run_under_qt([=]() |
1843 | { |
1844 | - auto search_cb = [this, searchReply, category, installedPackages](Packages packages) { |
1845 | + auto search_cb = [this, searchReply, category, installedPackages](Packages packages, DepartmentList) { |
1846 | qDebug("search callback"); |
1847 | |
1848 | - // handle packages data |
1849 | + // handle packages data; FIXME: use push_package() |
1850 | foreach (auto p, packages) { |
1851 | qDebug() << "pushing result" << QString::fromStdString(p.name); |
1852 | try { |
1853 | @@ -195,11 +365,58 @@ |
1854 | } |
1855 | } |
1856 | qDebug() << "search completed"; |
1857 | - this->finished(searchReply); |
1858 | - }; |
1859 | - |
1860 | - qDebug() << "starting search of" << QString::fromStdString(impl->query.query_string()); |
1861 | - impl->search_operation = impl->index.search(impl->query.query_string(), search_cb); |
1862 | + this->finished(searchReply); //FIXME: this shouldn't be needed |
1863 | + }; |
1864 | + |
1865 | + // this is the case when we do bootstrap for the first time, or it failed last time |
1866 | + if (impl->department_lookup.size() == 0 && !click::Scope::use_old_api()) |
1867 | + { |
1868 | + qDebug() << "performing bootstrap request"; |
1869 | + impl->search_operation = impl->index.bootstrap([this, search_cb, searchReply, installedPackages](const DepartmentList& deps, const |
1870 | + HighlightList& highlights, click::Index::Error error, int error_code) { |
1871 | + if (error == click::Index::Error::NoError) |
1872 | + { |
1873 | + qDebug() << "bootstrap request completed"; |
1874 | + auto root = std::make_shared<click::Department>("", "All Departments", "", true); |
1875 | + root->set_subdepartments(deps); |
1876 | + DepartmentList rdeps { root }; |
1877 | + impl->department_lookup.rebuild(rdeps); |
1878 | + impl->highlights = highlights; |
1879 | + qDebug() << "Total number of departments:" << impl->department_lookup.size() << ", highlights:" << highlights.size(); |
1880 | + } |
1881 | + else |
1882 | + { |
1883 | + qWarning() << "bootstrap request failed"; |
1884 | + if (error_code == 405) // method not allowed |
1885 | + { |
1886 | + qDebug() << "bootstrap not available, using old API"; |
1887 | + click::Scope::set_use_old_api(); |
1888 | + } |
1889 | + } |
1890 | + |
1891 | + if (query().query_string().empty() && !click::Scope::use_old_api()) |
1892 | + { |
1893 | + add_highlights(searchReply, installedPackages); |
1894 | + } |
1895 | + else |
1896 | + { |
1897 | + qDebug() << "starting search of" << QString::fromStdString(query().query_string()); |
1898 | + impl->search_operation = impl->index.search(query().query_string(), query().department_id(), search_cb); |
1899 | + } |
1900 | + }); |
1901 | + } |
1902 | + else |
1903 | + { |
1904 | + if (query().query_string().empty() && !click::Scope::use_old_api()) |
1905 | + { |
1906 | + add_highlights(searchReply, installedPackages); |
1907 | + } |
1908 | + else // normal search |
1909 | + { |
1910 | + qDebug() << "starting search of" << QString::fromStdString(query().query_string()); |
1911 | + impl->search_operation = impl->index.search(query().query_string(), query().department_id(), search_cb); |
1912 | + } |
1913 | + } |
1914 | }); |
1915 | } |
1916 | |
1917 | @@ -222,9 +439,9 @@ |
1918 | |
1919 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) |
1920 | { |
1921 | - auto query = impl->query.query_string(); |
1922 | + auto q = query().query_string(); |
1923 | std::string categoryTemplate = CATEGORY_APPS_SEARCH; |
1924 | - if (query.empty()) { |
1925 | + if (q.empty()) { |
1926 | categoryTemplate = CATEGORY_APPS_DISPLAY; |
1927 | } |
1928 | |
1929 | |
1930 | === modified file 'scope/clickstore/store-query.h' |
1931 | --- scope/clickstore/store-query.h 2014-06-16 14:09:21 +0000 |
1932 | +++ scope/clickstore/store-query.h 2014-06-18 18:08:01 +0000 |
1933 | @@ -32,10 +32,16 @@ |
1934 | |
1935 | |
1936 | #include <unity/scopes/SearchQueryBase.h> |
1937 | +#include <unity/scopes/Department.h> |
1938 | |
1939 | namespace scopes = unity::scopes; |
1940 | |
1941 | #include <QSharedPointer> |
1942 | +#include <set> |
1943 | + |
1944 | +#include <click/department-lookup.h> |
1945 | +#include <click/package.h> |
1946 | +#include <click/highlights.h> |
1947 | #include <click/interface.h> |
1948 | |
1949 | namespace click |
1950 | @@ -43,6 +49,7 @@ |
1951 | |
1952 | class Application; |
1953 | class Index; |
1954 | +class DepartmentLookup; |
1955 | |
1956 | class Query : public scopes::SearchQueryBase |
1957 | { |
1958 | @@ -69,7 +76,8 @@ |
1959 | constexpr static const char* VERSION{"version"}; |
1960 | }; |
1961 | |
1962 | - Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata); |
1963 | + Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& dept_lookup, click::HighlightList& highlights, |
1964 | + scopes::SearchMetadata const& metadata); |
1965 | virtual ~Query(); |
1966 | |
1967 | virtual void cancelled() override; |
1968 | @@ -77,8 +85,10 @@ |
1969 | virtual void run(scopes::SearchReplyProxy const& reply) override; |
1970 | |
1971 | protected: |
1972 | - virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, |
1973 | - const PackageSet &installedPackages, const std::string &category); |
1974 | + virtual void populate_departments(const click::DepartmentList& depts, const std::string& current_department_id, unity::scopes::Department::SPtr &root); |
1975 | + virtual void push_departments(const scopes::SearchReplyProxy& searchReply, const scopes::Department::SCPtr& root); |
1976 | + virtual void add_highlights(scopes::SearchReplyProxy const& searchReply, const PackageSet& installedPackages); |
1977 | + virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, const PackageSet &installedPackages, const std::string &category); |
1978 | virtual click::Interface& clickInterfaceInstance(); |
1979 | virtual PackageSet get_installed_packages(); |
1980 | virtual bool push_result(const scopes::SearchReplyProxy &searchReply, scopes::CategorisedResult const& res); |
1981 | @@ -88,6 +98,9 @@ |
1982 | std::string const& title, |
1983 | std::string const& icon, |
1984 | scopes::CategoryRenderer const& renderer_template); |
1985 | + virtual void push_package(const scopes::SearchReplyProxy& searchReply, scopes::Category::SCPtr category, const PackageSet &locallyInstalledApps, |
1986 | + const click::Package& pkg); |
1987 | + virtual void push_highlights(const scopes::SearchReplyProxy& searchReply, const HighlightList& highlights, const PackageSet &locallyInstalledApps); |
1988 | virtual void run_under_qt(const std::function<void()> &task); |
1989 | |
1990 | private: |
1991 | |
1992 | === modified file 'scope/clickstore/store-scope.cpp' |
1993 | --- scope/clickstore/store-scope.cpp 2014-06-17 21:32:44 +0000 |
1994 | +++ scope/clickstore/store-scope.cpp 2014-06-18 18:08:01 +0000 |
1995 | @@ -28,6 +28,7 @@ |
1996 | */ |
1997 | |
1998 | #include <click/qtbridge.h> |
1999 | +#include <click/department-lookup.h> |
2000 | #include "store-scope.h" |
2001 | #include "store-query.h" |
2002 | #include <click/preview.h> |
2003 | @@ -42,27 +43,38 @@ |
2004 | |
2005 | #include <logging.h> |
2006 | |
2007 | +bool click::Scope::old_api = false; |
2008 | |
2009 | click::Scope::Scope() |
2010 | { |
2011 | nam.reset(new click::network::AccessManager()); |
2012 | client.reset(new click::web::Client(nam)); |
2013 | index.reset(new click::Index(client)); |
2014 | + depts.reset(new click::DepartmentLookup()); |
2015 | + highlights.reset(new click::HighlightList()); |
2016 | } |
2017 | |
2018 | click::Scope::~Scope() |
2019 | { |
2020 | } |
2021 | |
2022 | -int click::Scope::start(std::string const&, scopes::RegistryProxy const&) |
2023 | +void click::Scope::set_use_old_api() |
2024 | +{ |
2025 | + old_api = true; |
2026 | +} |
2027 | + |
2028 | +bool click::Scope::use_old_api() |
2029 | +{ |
2030 | + return old_api; |
2031 | +} |
2032 | + |
2033 | +void click::Scope::start(std::string const&, scopes::RegistryProxy const&) |
2034 | { |
2035 | setlocale(LC_ALL, ""); |
2036 | // FIXME: This is wrong, but needed for json-cpp workaround. |
2037 | setlocale(LC_MONETARY, "C"); |
2038 | bindtextdomain(GETTEXT_PACKAGE, GETTEXT_LOCALEDIR); |
2039 | bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); |
2040 | - |
2041 | - return VERSION; |
2042 | } |
2043 | |
2044 | void click::Scope::run() |
2045 | @@ -70,7 +82,6 @@ |
2046 | static const int zero = 0; |
2047 | auto emptyCb = [this]() |
2048 | { |
2049 | - |
2050 | }; |
2051 | |
2052 | qt::core::world::build_and_run(zero, nullptr, emptyCb); |
2053 | @@ -83,7 +94,7 @@ |
2054 | |
2055 | scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) |
2056 | { |
2057 | - return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, metadata)); |
2058 | + return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, *depts, *highlights, metadata)); |
2059 | } |
2060 | |
2061 | |
2062 | @@ -93,12 +104,21 @@ |
2063 | return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam)}; |
2064 | } |
2065 | |
2066 | +<<<<<<< TREE |
2067 | unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& /* result */, unity::scopes::ActionMetadata const& metadata, |
2068 | std::string const& widget_id, std::string const& _action_id) |
2069 | +======= |
2070 | +unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& /* widget_id */, std::string const& action_id) |
2071 | +>>>>>>> MERGE-SOURCE |
2072 | { |
2073 | +<<<<<<< TREE |
2074 | std::string action_id = _action_id; |
2075 | auto activation = new ScopeActivation(); |
2076 | qDebug() << "perform_action called with widget_id" << QString::fromStdString(widget_id) << "and action_id:" << QString::fromStdString(action_id); |
2077 | +======= |
2078 | + auto activation = new ScopeActivation(result, metadata); |
2079 | + qDebug() << "perform_action called with action_id" << QString().fromStdString(action_id); |
2080 | +>>>>>>> MERGE-SOURCE |
2081 | |
2082 | // if the purchase is completed, do the install |
2083 | if (action_id == "purchaseCompleted") { |
2084 | |
2085 | === modified file 'scope/clickstore/store-scope.h' |
2086 | --- scope/clickstore/store-scope.h 2014-05-27 06:57:52 +0000 |
2087 | +++ scope/clickstore/store-scope.h 2014-06-18 18:08:01 +0000 |
2088 | @@ -30,6 +30,7 @@ |
2089 | #ifndef CLICK_SCOPE_H |
2090 | #define CLICK_SCOPE_H |
2091 | |
2092 | +#include <memory> |
2093 | #include <click/network_access_manager.h> |
2094 | #include <click/webclient.h> |
2095 | |
2096 | @@ -43,29 +44,38 @@ |
2097 | |
2098 | namespace click |
2099 | { |
2100 | + |
2101 | +class DepartmentLookup; |
2102 | + |
2103 | class Scope : public scopes::ScopeBase |
2104 | { |
2105 | public: |
2106 | Scope(); |
2107 | ~Scope(); |
2108 | |
2109 | - virtual int start(std::string const&, scopes::RegistryProxy const&) override; |
2110 | + virtual void start(std::string const&, scopes::RegistryProxy const&) override; |
2111 | |
2112 | virtual void run() override; |
2113 | virtual void stop() override; |
2114 | |
2115 | - virtual scopes::SearchQueryBase::UPtr search(scopes::CannedQuery const& q, scopes::SearchMetadata const&) override; |
2116 | + virtual scopes::SearchQueryBase::UPtr search(scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) override; |
2117 | unity::scopes::PreviewQueryBase::UPtr preview(const unity::scopes::Result&, |
2118 | const unity::scopes::ActionMetadata&) override; |
2119 | |
2120 | virtual unity::scopes::ActivationQueryBase::UPtr perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id) override; |
2121 | |
2122 | + static void set_use_old_api(); |
2123 | + static bool use_old_api(); |
2124 | + |
2125 | private: |
2126 | QSharedPointer<click::network::AccessManager> nam; |
2127 | QSharedPointer<click::web::Client> client; |
2128 | QSharedPointer<click::Index> index; |
2129 | + std::shared_ptr<click::DepartmentLookup> depts; |
2130 | + std::shared_ptr<click::HighlightList> highlights; |
2131 | |
2132 | std::string installApplication(unity::scopes::Result const& result); |
2133 | + static bool old_api; |
2134 | }; |
2135 | } |
2136 | #endif // CLICK_SCOPE_H |
2137 | |
2138 | === modified file 'scope/tests/integration/webclient_integration.cpp' |
2139 | --- scope/tests/integration/webclient_integration.cpp 2014-06-12 21:05:25 +0000 |
2140 | +++ scope/tests/integration/webclient_integration.cpp 2014-06-18 18:08:01 +0000 |
2141 | @@ -30,6 +30,7 @@ |
2142 | #include <click/network_access_manager.h> |
2143 | #include <click/webclient.h> |
2144 | #include <click/index.h> |
2145 | +#include <click/departments.h> |
2146 | |
2147 | #include <QCoreApplication> |
2148 | #include <QDebug> |
2149 | @@ -102,7 +103,8 @@ |
2150 | new click::web::Client(namPtr)); |
2151 | click::Index index(clientPtr); |
2152 | click::Packages packages; |
2153 | - index.search("qr,architecture:armhf", [&, this](click::Packages found_packages){ |
2154 | + index.search("qr,architecture:armhf", "", [&, this](click::Packages found_packages, click::DepartmentList){ |
2155 | + //TODO departments |
2156 | packages = found_packages; |
2157 | Quit(); |
2158 | }); |
2159 | |
2160 | === modified file 'scope/tests/test_query.cpp' |
2161 | --- scope/tests/test_query.cpp 2014-06-12 22:17:42 +0000 |
2162 | +++ scope/tests/test_query.cpp 2014-06-18 18:08:01 +0000 |
2163 | @@ -45,6 +45,7 @@ |
2164 | #include <unity/scopes/CannedQuery.h> |
2165 | #include <unity/scopes/ScopeBase.h> |
2166 | #include <unity/scopes/SearchReply.h> |
2167 | +#include <unity/scopes/testing/MockSearchReply.h> |
2168 | |
2169 | using namespace ::testing; |
2170 | using namespace click; |
2171 | @@ -57,30 +58,45 @@ |
2172 | |
2173 | class MockIndex : public click::Index { |
2174 | click::Packages packages; |
2175 | + click::DepartmentList departments; |
2176 | + click::DepartmentList bootstrap_departments; |
2177 | + click::HighlightList bootstrap_highlights; |
2178 | public: |
2179 | - MockIndex(click::Packages packages = click::Packages()) |
2180 | + MockIndex(click::Packages packages = click::Packages(), |
2181 | + click::DepartmentList departments = click::DepartmentList(), |
2182 | + click::DepartmentList boot_departments = click::DepartmentList()) |
2183 | : Index(QSharedPointer<click::web::Client>()), |
2184 | - packages(packages) |
2185 | - { |
2186 | - |
2187 | - } |
2188 | - |
2189 | - click::web::Cancellable search(const std::string &query, std::function<void (click::Packages)> callback) override |
2190 | - { |
2191 | - do_search(query, callback); |
2192 | - callback(packages); |
2193 | - return click::web::Cancellable(); |
2194 | - } |
2195 | - |
2196 | - MOCK_METHOD2(do_search, |
2197 | - void(const std::string&, |
2198 | - std::function<void(click::Packages)>)); |
2199 | + packages(packages), |
2200 | + departments(departments), |
2201 | + bootstrap_departments(boot_departments) |
2202 | + { |
2203 | + |
2204 | + } |
2205 | + |
2206 | + click::web::Cancellable search(const std::string &query, const std::string& department, std::function<void (click::Packages, click::DepartmentList)> callback) override |
2207 | + { |
2208 | + do_search(query, department, callback); |
2209 | + callback(packages, departments); |
2210 | + return click::web::Cancellable(); |
2211 | + } |
2212 | + |
2213 | + click::web::Cancellable bootstrap(std::function<void(const click::DepartmentList&, const click::HighlightList&, Error, int)> callback) override |
2214 | + { |
2215 | + callback(bootstrap_departments, bootstrap_highlights, click::Index::Error::NoError, 0); |
2216 | + return click::web::Cancellable(); |
2217 | + } |
2218 | + |
2219 | + MOCK_METHOD3(do_search, |
2220 | + void(const std::string&, const std::string&, |
2221 | + std::function<void(click::Packages, click::DepartmentList)>)); |
2222 | }; |
2223 | |
2224 | class MockQueryBase : public click::Query { |
2225 | public: |
2226 | MockQueryBase(const unity::scopes::CannedQuery& query, click::Index& index, |
2227 | - scopes::SearchMetadata const& metadata) : click::Query(query, index, metadata) |
2228 | + click::DepartmentLookup& depts, |
2229 | + click::HighlightList& highlights, |
2230 | + scopes::SearchMetadata const& metadata) : click::Query(query, index, depts, highlights, metadata) |
2231 | { |
2232 | |
2233 | } |
2234 | @@ -94,7 +110,9 @@ |
2235 | class MockQuery : public MockQueryBase { |
2236 | public: |
2237 | MockQuery(const unity::scopes::CannedQuery& query, click::Index& index, |
2238 | - scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, metadata) |
2239 | + click::DepartmentLookup& depts, |
2240 | + click::HighlightList& highlights, |
2241 | + scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata) |
2242 | { |
2243 | |
2244 | } |
2245 | @@ -118,7 +136,9 @@ |
2246 | class MockQueryRun : public MockQueryBase { |
2247 | public: |
2248 | MockQueryRun(const unity::scopes::CannedQuery& query, click::Index& index, |
2249 | - scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, metadata) |
2250 | + click::DepartmentLookup& depts, |
2251 | + click::HighlightList& highlights, |
2252 | + scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata) |
2253 | { |
2254 | |
2255 | } |
2256 | @@ -147,12 +167,16 @@ |
2257 | TEST(QueryTest, testAddAvailableAppsCallsClickIndex) |
2258 | { |
2259 | MockIndex mock_index; |
2260 | + click::DepartmentLookup dept_lookup; |
2261 | + click::HighlightList highlights; |
2262 | scopes::SearchMetadata metadata("en_EN", "phone"); |
2263 | PackageSet no_installed_packages; |
2264 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2265 | - MockQuery q(query, mock_index, metadata); |
2266 | - EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)).Times(1); |
2267 | - scopes::SearchReplyProxy reply; |
2268 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2269 | + EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _, _)).Times(1); |
2270 | + |
2271 | + scopes::testing::MockSearchReply mock_reply; |
2272 | + scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
2273 | |
2274 | scopes::CategoryRenderer renderer("{}"); |
2275 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
2276 | @@ -166,17 +190,21 @@ |
2277 | {"name", "title", 0.0, "icon", "uri"} |
2278 | }; |
2279 | MockIndex mock_index(packages); |
2280 | + click::DepartmentLookup dept_lookup; |
2281 | + click::HighlightList highlights; |
2282 | scopes::SearchMetadata metadata("en_EN", "phone"); |
2283 | PackageSet no_installed_packages; |
2284 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2285 | - MockQuery q(query, mock_index, metadata); |
2286 | - EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
2287 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2288 | + EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _, _)); |
2289 | |
2290 | scopes::CategoryRenderer renderer("{}"); |
2291 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
2292 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
2293 | |
2294 | - scopes::SearchReplyProxy reply; |
2295 | + scopes::testing::MockSearchReply mock_reply; |
2296 | + scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
2297 | + |
2298 | auto expected_title = packages.front().title; |
2299 | EXPECT_CALL(q, push_result(_, Property(&scopes::CategorisedResult::title, expected_title))); |
2300 | q.wrap_add_available_apps(reply, no_installed_packages, FAKE_CATEGORY_TEMPLATE); |
2301 | @@ -188,17 +216,20 @@ |
2302 | {"name", "title", 0.0, "icon", "uri"} |
2303 | }; |
2304 | MockIndex mock_index(packages); |
2305 | + click::DepartmentLookup dept_lookup; |
2306 | + click::HighlightList highlights; |
2307 | scopes::SearchMetadata metadata("en_EN", "phone"); |
2308 | PackageSet no_installed_packages; |
2309 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2310 | - MockQuery q(query, mock_index, metadata); |
2311 | - EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
2312 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2313 | + EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _, _)); |
2314 | |
2315 | scopes::CategoryRenderer renderer("{}"); |
2316 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
2317 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
2318 | |
2319 | - scopes::SearchReplyProxy reply; |
2320 | + scopes::testing::MockSearchReply mock_reply; |
2321 | + scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
2322 | EXPECT_CALL(q, finished(_)); |
2323 | q.wrap_add_available_apps(reply, no_installed_packages, FAKE_CATEGORY_TEMPLATE); |
2324 | } |
2325 | @@ -209,10 +240,12 @@ |
2326 | {"name", "title", 0.0, "icon", "uri"} |
2327 | }; |
2328 | MockIndex mock_index(packages); |
2329 | + click::DepartmentLookup dept_lookup; |
2330 | + click::HighlightList highlights; |
2331 | scopes::SearchMetadata metadata("en_EN", "phone"); |
2332 | PackageSet no_installed_packages; |
2333 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2334 | - MockQueryRun q(query, mock_index, metadata); |
2335 | + MockQueryRun q(query, mock_index, dept_lookup, highlights, metadata); |
2336 | auto reply = scopes::SearchReplyProxy(); |
2337 | EXPECT_CALL(q, get_installed_packages()).WillOnce(Return(no_installed_packages)); |
2338 | EXPECT_CALL(q, add_available_apps(reply, no_installed_packages, _)); |
2339 | @@ -234,15 +267,18 @@ |
2340 | PackageSet one_installed_package { |
2341 | {"org.example.app2", "0.2"} |
2342 | }; |
2343 | + click::DepartmentLookup dept_lookup; |
2344 | + click::HighlightList highlights; |
2345 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2346 | - MockQuery q(query, mock_index, metadata); |
2347 | - EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
2348 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2349 | + EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _, _)); |
2350 | |
2351 | scopes::CategoryRenderer renderer("{}"); |
2352 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
2353 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
2354 | |
2355 | - scopes::SearchReplyProxy reply; |
2356 | + scopes::testing::MockSearchReply mock_reply; |
2357 | + scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
2358 | auto expected_name1 = packages.front().name; |
2359 | EXPECT_CALL(q, push_result(_, HasPackageName(expected_name1))); |
2360 | auto expected_name2 = packages.back().name; |
2361 | @@ -261,15 +297,18 @@ |
2362 | PackageSet one_installed_package { |
2363 | {"org.example.app2", "0.2"} |
2364 | }; |
2365 | + click::DepartmentLookup dept_lookup; |
2366 | + click::HighlightList highlights; |
2367 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2368 | - MockQuery q(query, mock_index, metadata); |
2369 | - EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _)); |
2370 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2371 | + EXPECT_CALL(mock_index, do_search(FAKE_QUERY, _, _)); |
2372 | |
2373 | scopes::CategoryRenderer renderer("{}"); |
2374 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); |
2375 | EXPECT_CALL(q, register_category(_, _, _, _, _)).WillOnce(Return(ptrCat)); |
2376 | |
2377 | - scopes::SearchReplyProxy reply; |
2378 | + scopes::testing::MockSearchReply mock_reply; |
2379 | + scopes::SearchReplyProxy reply(&mock_reply, [](unity::scopes::SearchReply*){}); |
2380 | EXPECT_CALL(q, push_result(_, IsInstalled(true))); |
2381 | EXPECT_CALL(q, push_result(_, IsInstalled(false))); |
2382 | q.wrap_add_available_apps(reply, one_installed_package, FAKE_CATEGORY_TEMPLATE); |
2383 | @@ -288,8 +327,10 @@ |
2384 | }; |
2385 | MockIndex mock_index(uninstalled_packages); |
2386 | scopes::SearchMetadata metadata("en_EN", "phone"); |
2387 | + click::DepartmentLookup dept_lookup; |
2388 | + click::HighlightList highlights; |
2389 | const unity::scopes::CannedQuery query("foo.scope", FAKE_QUERY, ""); |
2390 | - MockQuery q(query, mock_index, metadata); |
2391 | + MockQuery q(query, mock_index, dept_lookup, highlights, metadata); |
2392 | PackageSet installed_packages{{"package_1", "0.1"}}; |
2393 | |
2394 | FakeInterface fake_interface; |
426 +std::map< std::string, std::string> Index:: build_headers( const std::string& language) click:: web::Response> response( client- >call( BOOTSTRAP_ PATH, "GET", false, build_headers( "en"), "", params)); //TODO: language
438 + {"Accept-Language", language},
486 + QSharedPointer<
487 + get_base_url() + click::
You don't need to do all this work to pass the language around or set Accept-Language manually. It is already added automatically in web::Client::cal().