Merge lp:~stolowski/unity-lens-applications/show-more-apps-on-no-query into lp:unity-lens-applications
- show-more-apps-on-no-query
- Merge into trunk
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Neil J. Patel (community) | Approve | ||
Review via email: mp+123983@code.launchpad.net |
Commit message
List 10 'What's new' apps and the 12 'Top Rated' apps from Software Center in 'Apps Available for Download' before user performs any search if no filters are active.
List 100 top rated apps according to active filters if search string is empty.
Description of the change
List 10 'What's new' apps and the 12 'Top Rated' apps from Software Center in 'Apps Available for Download' before user performs any search if no filters are active.
List 100 top rated apps according to active filters if search string is empty.
WARNING! Don't approve until Software Center changes are merged.
- 300. By Paweł Stołowski
-
Updated comment.
Michal Hruby (mhr3) wrote : | # |
Michal Hruby (mhr3) wrote : | # |
465 +typedef int (*AppFilterCall
Shouldn't this return a gboolean instead? Or an enum perhaps? It's not obvious what the callback should be returning.
- 301. By Paweł Stołowski
-
Make filtering callback use bool return value.
- 302. By Paweł Stołowski
-
Use 'unity-whats-new' and 'unity-top-rated' categories instead of 'What's new' (requiring utf)
and 'Top Rated'. Requires lp:~mvo/software-center/extra-unity-categories.
Paweł Stołowski (stolowski) wrote : | # |
Software Center has been fixed to provide unity-whats-new and unity-top-rated categories instead. Updated the code. Ready for re-review.
Neil J. Patel (njpatel) wrote : | # |
Hi, this is approved pending that we can get the Software Centre bits landed for b2.
DO NOT APPROVE THIS UNTIL THEN.
Preview Diff
1 | === modified file 'src/Makefile.am' | |||
2 | --- src/Makefile.am 2012-08-08 16:30:35 +0000 | |||
3 | +++ src/Makefile.am 2012-09-17 15:59:25 +0000 | |||
4 | @@ -61,6 +61,7 @@ | |||
5 | 61 | utils.vala \ | 61 | utils.vala \ |
6 | 62 | aptd-client.vala \ | 62 | aptd-client.vala \ |
7 | 63 | software-center-data-provider.vala \ | 63 | software-center-data-provider.vala \ |
8 | 64 | software-center-data-cache.vala \ | ||
9 | 64 | $(NULL) | 65 | $(NULL) |
10 | 65 | 66 | ||
11 | 66 | unity-package-search.o : $(srcdir)/unity-package-search.cc $(srcdir)/unity-package-search.h | 67 | unity-package-search.o : $(srcdir)/unity-package-search.cc $(srcdir)/unity-package-search.h |
12 | 67 | 68 | ||
13 | === modified file 'src/daemon.vala' | |||
14 | --- src/daemon.vala 2012-09-13 17:12:02 +0000 | |||
15 | +++ src/daemon.vala 2012-09-17 15:59:25 +0000 | |||
16 | @@ -26,6 +26,20 @@ | |||
17 | 26 | 26 | ||
18 | 27 | namespace Unity.ApplicationsLens { | 27 | namespace Unity.ApplicationsLens { |
19 | 28 | 28 | ||
20 | 29 | /* Number of 'Apps available for download' to show if no search query is provided AND a filter is active. | ||
21 | 30 | It shouldn't be too high as this may impact lens performance. | ||
22 | 31 | */ | ||
23 | 32 | const uint MAX_APP_FOR_DOWNLOAD_FOR_EMPTY_QUERY = 100; | ||
24 | 33 | |||
25 | 34 | /* Number of top rated apps to show in 'Apps available for download' if no search query is provided AND NO filter is active. */ | ||
26 | 35 | const uint MAX_TOP_RATED_APPS_FOR_EMPTY_QUERY = 12; | ||
27 | 36 | |||
28 | 37 | /* Number of "What's new" apps to show in 'Apps available for download' if no search query is provided AND NO filter is active. */ | ||
29 | 38 | const uint MAX_WHATS_NEW_APPS_FOR_EMPTY_QUERY = 10; | ||
30 | 39 | |||
31 | 40 | /* Time between queries to SoftwareCenterDataProvider */ | ||
32 | 41 | const int64 TOP_RATED_ITEMS_CACHE_LIFETIME = 24*3600; // 24 hours | ||
33 | 42 | |||
34 | 29 | const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/places/svg/"; | 43 | const string ICON_PATH = Config.DATADIR + "/icons/unity-icon-theme/places/svg/"; |
35 | 30 | const string ICON_APP_INSTALL_PATH = Config.DATADIR + "/app-install/icons"; | 44 | const string ICON_APP_INSTALL_PATH = Config.DATADIR + "/app-install/icons"; |
36 | 31 | 45 | ||
37 | @@ -462,6 +476,14 @@ | |||
38 | 462 | } | 476 | } |
39 | 463 | } | 477 | } |
40 | 464 | 478 | ||
41 | 479 | /* Returns TRUE if application is NOT installed */ | ||
42 | 480 | public bool filter_cb (Unity.Package.PackageInfo pkginfo) | ||
43 | 481 | { | ||
44 | 482 | var appmanager = AppInfoManager.get_default(); | ||
45 | 483 | AppInfo? app = appmanager.lookup (pkginfo.desktop_file); | ||
46 | 484 | return app == null; | ||
47 | 485 | } | ||
48 | 486 | |||
49 | 465 | private async void update_scope_search (Unity.LensSearch search, | 487 | private async void update_scope_search (Unity.LensSearch search, |
50 | 466 | Cancellable cancellable) | 488 | Cancellable cancellable) |
51 | 467 | { | 489 | { |
52 | @@ -475,6 +497,7 @@ | |||
53 | 475 | 497 | ||
54 | 476 | string pkg_search_string = prepare_pkg_search_string (search, filter); | 498 | string pkg_search_string = prepare_pkg_search_string (search, filter); |
55 | 477 | 499 | ||
56 | 500 | bool has_filter = (filter != null && filter.filtering); | ||
57 | 478 | bool has_search = !Utils.is_search_empty (search); | 501 | bool has_search = !Utils.is_search_empty (search); |
58 | 479 | 502 | ||
59 | 480 | Timer timer = new Timer (); | 503 | Timer timer = new Timer (); |
60 | @@ -556,16 +579,43 @@ | |||
61 | 556 | debug ("Entry search listed %i Available apps in %fms for query: %s", | 579 | debug ("Entry search listed %i Available apps in %fms for query: %s", |
62 | 557 | pkgresults.num_hits, timer.elapsed ()*1000, pkg_search_string); | 580 | pkgresults.num_hits, timer.elapsed ()*1000, pkg_search_string); |
63 | 558 | } | 581 | } |
65 | 559 | else | 582 | else if (has_filter) /* Empty search string + active filters should get lots of results from selected categories */ |
66 | 560 | { | 583 | { |
67 | 561 | timer.start (); | 584 | timer.start (); |
68 | 562 | string? filter_query = prepare_pkg_search_string (search, filter); | 585 | string? filter_query = prepare_pkg_search_string (search, filter); |
75 | 563 | var random_pkgresults = pkgsearcher.get_random_apps (filter_query, 12); | 586 | |
76 | 564 | add_pkg_search_result (random_pkgresults, installed_uris, available_uris, | 587 | var pkgresults = pkgsearcher.get_apps (filter_query, MAX_APP_FOR_DOWNLOAD_FOR_EMPTY_QUERY, filter_cb); |
77 | 565 | model, Category.AVAILABLE, 6); | 588 | add_pkg_search_result (pkgresults, installed_uris, available_uris, model, Category.AVAILABLE, MAX_APP_FOR_DOWNLOAD_FOR_EMPTY_QUERY); |
78 | 566 | timer.stop (); | 589 | timer.stop (); |
79 | 567 | debug ("Entry search listed %i random Available apps in %fms", | 590 | debug ("Entry search listed %i Available apps in %fms", |
80 | 568 | random_pkgresults.num_hits, timer.elapsed ()*1000); | 591 | pkgresults.num_hits, timer.elapsed ()*1000); |
81 | 592 | } | ||
82 | 593 | else | ||
83 | 594 | { | ||
84 | 595 | timer.start (); | ||
85 | 596 | |||
86 | 597 | uint hits = 0; | ||
87 | 598 | try | ||
88 | 599 | { | ||
89 | 600 | Set<string> duplicates_lookup = new HashSet<string> (); | ||
90 | 601 | |||
91 | 602 | if (sc_data_provider == null) | ||
92 | 603 | sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME); | ||
93 | 604 | |||
94 | 605 | var whats_new = sc_data_provider.get_items_for_category ("unity-whats-new"); | ||
95 | 606 | hits = add_sc_category_results (whats_new, model, Category.AVAILABLE, ref duplicates_lookup, MAX_WHATS_NEW_APPS_FOR_EMPTY_QUERY); | ||
96 | 607 | |||
97 | 608 | var top_rated = sc_data_provider.get_items_for_category ("unity-top-rated"); | ||
98 | 609 | hits += add_sc_category_results (top_rated, model, Category.AVAILABLE, ref duplicates_lookup, MAX_TOP_RATED_APPS_FOR_EMPTY_QUERY); | ||
99 | 610 | } | ||
100 | 611 | catch (GLib.Error e) | ||
101 | 612 | { | ||
102 | 613 | warning ("Failed to get top rated apps: %s", e.message); | ||
103 | 614 | } | ||
104 | 615 | |||
105 | 616 | timer.stop (); | ||
106 | 617 | debug ("Entry search listed %u top rated/new available apps in %fms", | ||
107 | 618 | hits, timer.elapsed ()*1000); | ||
108 | 569 | } | 619 | } |
109 | 570 | } | 620 | } |
110 | 571 | 621 | ||
111 | @@ -749,25 +799,25 @@ | |||
112 | 749 | return default_icon.to_string (); | 799 | return default_icon.to_string (); |
113 | 750 | } | 800 | } |
114 | 751 | 801 | ||
116 | 752 | public Icon find_pkg_icon (Unity.Package.PackageInfo pkginfo) | 802 | public Icon find_pkg_icon (string desktop_file, string icon_name) |
117 | 753 | { | 803 | { |
119 | 754 | string desktop_id = Path.get_basename (pkginfo.desktop_file); | 804 | string desktop_id = Path.get_basename (desktop_file); |
120 | 755 | bool installed = AppInfoManager.get_default().lookup (desktop_id) != null; | 805 | bool installed = AppInfoManager.get_default().lookup (desktop_id) != null; |
121 | 756 | 806 | ||
122 | 757 | /* If the app is already installed we should be able to pull the | 807 | /* If the app is already installed we should be able to pull the |
123 | 758 | * icon from the theme */ | 808 | * icon from the theme */ |
124 | 759 | if (installed) | 809 | if (installed) |
126 | 760 | return new ThemedIcon (pkginfo.icon); | 810 | return new ThemedIcon (icon_name); |
127 | 761 | 811 | ||
128 | 762 | /* App is not installed - we need to find the right icon in the bowels | 812 | /* App is not installed - we need to find the right icon in the bowels |
129 | 763 | * of the software center */ | 813 | * of the software center */ |
131 | 764 | if (pkginfo.icon.has_prefix ("/")) | 814 | if (icon_name.has_prefix ("/")) |
132 | 765 | { | 815 | { |
134 | 766 | return new FileIcon (File.new_for_path (pkginfo.icon)); | 816 | return new FileIcon (File.new_for_path (icon_name)); |
135 | 767 | } | 817 | } |
136 | 768 | else | 818 | else |
137 | 769 | { | 819 | { |
139 | 770 | Icon icon = file_icon_cache.lookup (pkginfo.icon); | 820 | Icon icon = file_icon_cache.lookup (icon_name); |
140 | 771 | 821 | ||
141 | 772 | if (icon != null) | 822 | if (icon != null) |
142 | 773 | return icon; | 823 | return icon; |
143 | @@ -775,24 +825,24 @@ | |||
144 | 775 | /* If the icon name contains a . it probably already have a | 825 | /* If the icon name contains a . it probably already have a |
145 | 776 | * type postfix - so test icon name directly */ | 826 | * type postfix - so test icon name directly */ |
146 | 777 | string path; | 827 | string path; |
148 | 778 | if ("." in pkginfo.icon) | 828 | if ("." in icon_name) |
149 | 779 | { | 829 | { |
151 | 780 | path = @"$(Config.DATADIR)/app-install/icons/$(pkginfo.icon)"; | 830 | path = @"$(Config.DATADIR)/app-install/icons/$(icon_name)"; |
152 | 781 | if (FileUtils.test (path, FileTest.EXISTS)) | 831 | if (FileUtils.test (path, FileTest.EXISTS)) |
153 | 782 | { | 832 | { |
154 | 783 | icon = new FileIcon (File.new_for_path (path)); | 833 | icon = new FileIcon (File.new_for_path (path)); |
156 | 784 | file_icon_cache.insert (pkginfo.icon, icon); | 834 | file_icon_cache.insert (icon_name, icon); |
157 | 785 | return icon; | 835 | return icon; |
158 | 786 | } | 836 | } |
159 | 787 | /* Try also software center cache dir */ | 837 | /* Try also software center cache dir */ |
160 | 788 | path = Path.build_filename (Environment.get_user_cache_dir (), | 838 | path = Path.build_filename (Environment.get_user_cache_dir (), |
161 | 789 | "software-center", | 839 | "software-center", |
162 | 790 | "icons", | 840 | "icons", |
164 | 791 | pkginfo.icon); | 841 | icon_name); |
165 | 792 | if (FileUtils.test (path, FileTest.EXISTS)) | 842 | if (FileUtils.test (path, FileTest.EXISTS)) |
166 | 793 | { | 843 | { |
167 | 794 | icon = new FileIcon (File.new_for_path (path)); | 844 | icon = new FileIcon (File.new_for_path (path)); |
169 | 795 | file_icon_cache.insert (pkginfo.icon, icon); | 845 | file_icon_cache.insert (icon_name, icon); |
170 | 796 | return icon; | 846 | return icon; |
171 | 797 | } | 847 | } |
172 | 798 | } | 848 | } |
173 | @@ -800,12 +850,12 @@ | |||
174 | 800 | /* Now try appending all the image extensions we know */ | 850 | /* Now try appending all the image extensions we know */ |
175 | 801 | foreach (var ext in image_extensions) | 851 | foreach (var ext in image_extensions) |
176 | 802 | { | 852 | { |
178 | 803 | path = @"$(Config.DATADIR)/app-install/icons/$(pkginfo.icon).$(ext)"; | 853 | path = @"$(Config.DATADIR)/app-install/icons/$(icon_name).$(ext)"; |
179 | 804 | if (FileUtils.test (path, FileTest.EXISTS)) | 854 | if (FileUtils.test (path, FileTest.EXISTS)) |
180 | 805 | { | 855 | { |
181 | 806 | /* Got it! Cache the icon path and return the icon */ | 856 | /* Got it! Cache the icon path and return the icon */ |
182 | 807 | icon = new FileIcon (File.new_for_path (path)); | 857 | icon = new FileIcon (File.new_for_path (path)); |
184 | 808 | file_icon_cache.insert (pkginfo.icon, icon); | 858 | file_icon_cache.insert (icon_name, icon); |
185 | 809 | return icon; | 859 | return icon; |
186 | 810 | } | 860 | } |
187 | 811 | } | 861 | } |
188 | @@ -813,7 +863,7 @@ | |||
189 | 813 | 863 | ||
190 | 814 | /* Cache the fact that we couldn't find this icon */ | 864 | /* Cache the fact that we couldn't find this icon */ |
191 | 815 | var icon = new ThemedIcon ("applications-other"); | 865 | var icon = new ThemedIcon ("applications-other"); |
193 | 816 | file_icon_cache.insert (pkginfo.icon, icon); | 866 | file_icon_cache.insert (icon_name, icon); |
194 | 817 | 867 | ||
195 | 818 | return icon; | 868 | return icon; |
196 | 819 | } | 869 | } |
197 | @@ -880,6 +930,41 @@ | |||
198 | 880 | return GLib.Path.get_basename (name); | 930 | return GLib.Path.get_basename (name); |
199 | 881 | } | 931 | } |
200 | 882 | 932 | ||
201 | 933 | /** | ||
202 | 934 | * Add all results obtained from SoftwareCenterDataProvider | ||
203 | 935 | */ | ||
204 | 936 | private uint add_sc_category_results (SoftwareCenterDataProviderService.AppInfo?[] results, | ||
205 | 937 | Dee.Model model, | ||
206 | 938 | Category category, | ||
207 | 939 | ref Set<string> duplicates_lookup, | ||
208 | 940 | uint max_results) | ||
209 | 941 | { | ||
210 | 942 | uint i = 0; | ||
211 | 943 | foreach (SoftwareCenterDataProviderService.AppInfo app in results) | ||
212 | 944 | { | ||
213 | 945 | string uri = @"unity-install://$(app.package_name)/$(app.application_name)"; | ||
214 | 946 | |||
215 | 947 | if (uri in duplicates_lookup) | ||
216 | 948 | { | ||
217 | 949 | continue; | ||
218 | 950 | } | ||
219 | 951 | |||
220 | 952 | Icon icon = find_pkg_icon (app.desktop_file, app.icon); | ||
221 | 953 | |||
222 | 954 | model.append (uri, icon.to_string (), | ||
223 | 955 | category, | ||
224 | 956 | "application/x-desktop", | ||
225 | 957 | app.application_name, | ||
226 | 958 | "", //comment | ||
227 | 959 | "file://" + app.desktop_file); | ||
228 | 960 | duplicates_lookup.add (uri); | ||
229 | 961 | i++; | ||
230 | 962 | if (i == max_results) | ||
231 | 963 | break; | ||
232 | 964 | } | ||
233 | 965 | return i; | ||
234 | 966 | } | ||
235 | 967 | |||
236 | 883 | private void add_pkg_search_result (Unity.Package.SearchResult results, | 968 | private void add_pkg_search_result (Unity.Package.SearchResult results, |
237 | 884 | Set<string> installed_uris, | 969 | Set<string> installed_uris, |
238 | 885 | Set<string> available_uris, | 970 | Set<string> available_uris, |
239 | @@ -953,7 +1038,7 @@ | |||
240 | 953 | available_uris.add (uri); | 1038 | available_uris.add (uri); |
241 | 954 | } | 1039 | } |
242 | 955 | 1040 | ||
244 | 956 | Icon icon = find_pkg_icon (pkginfo); | 1041 | Icon icon = find_pkg_icon (pkginfo.desktop_file, pkginfo.icon); |
245 | 957 | 1042 | ||
246 | 958 | model.append (uri, icon.to_string (), | 1043 | model.append (uri, icon.to_string (), |
247 | 959 | category,"application/x-desktop", | 1044 | category,"application/x-desktop", |
248 | @@ -1159,7 +1244,7 @@ | |||
249 | 1159 | try { | 1244 | try { |
250 | 1160 | if (sc_data_provider == null) | 1245 | if (sc_data_provider == null) |
251 | 1161 | { | 1246 | { |
253 | 1162 | sc_data_provider = new SoftwareCenterDataProviderProxy (); | 1247 | sc_data_provider = new SoftwareCenterDataCache (TOP_RATED_ITEMS_CACHE_LIFETIME); |
254 | 1163 | sc_data_provider.connect_to (); | 1248 | sc_data_provider.connect_to (); |
255 | 1164 | } | 1249 | } |
256 | 1165 | 1250 | ||
257 | 1166 | 1251 | ||
258 | === modified file 'src/runner.vala' | |||
259 | --- src/runner.vala 2012-08-14 14:32:55 +0000 | |||
260 | +++ src/runner.vala 2012-09-17 15:59:25 +0000 | |||
261 | @@ -415,7 +415,7 @@ | |||
262 | 415 | continue; | 415 | continue; |
263 | 416 | 416 | ||
264 | 417 | // pick the first one | 417 | // pick the first one |
266 | 418 | icon = this.daemon.find_pkg_icon (pkginfo); | 418 | icon = this.daemon.find_pkg_icon (pkginfo.desktop_file, pkginfo.icon); |
267 | 419 | return exec_string; | 419 | return exec_string; |
268 | 420 | 420 | ||
269 | 421 | } | 421 | } |
270 | 422 | 422 | ||
271 | === added file 'src/software-center-data-cache.vala' | |||
272 | --- src/software-center-data-cache.vala 1970-01-01 00:00:00 +0000 | |||
273 | +++ src/software-center-data-cache.vala 2012-09-17 15:59:25 +0000 | |||
274 | @@ -0,0 +1,71 @@ | |||
275 | 1 | /* | ||
276 | 2 | * Copyright (C) 2012 Canonical Ltd | ||
277 | 3 | * | ||
278 | 4 | * This program is free software: you can redistribute it and/or modify | ||
279 | 5 | * it under the terms of the GNU General Public License version 3 as | ||
280 | 6 | * published by the Free Software Foundation. | ||
281 | 7 | * | ||
282 | 8 | * This program is distributed in the hope that it will be useful, | ||
283 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
284 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
285 | 11 | * GNU General Public License for more details. | ||
286 | 12 | * | ||
287 | 13 | * You should have received a copy of the GNU General Public License | ||
288 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
289 | 15 | * | ||
290 | 16 | * Authored by Pawel Stolowski <pawel.stolowski@canonical.com> | ||
291 | 17 | */ | ||
292 | 18 | |||
293 | 19 | namespace Unity.ApplicationsLens { | ||
294 | 20 | |||
295 | 21 | public class SoftwareCenterDataCache: SoftwareCenterDataProviderProxy | ||
296 | 22 | { | ||
297 | 23 | public int64 category_items_lifetime { get; set; } | ||
298 | 24 | private HashTable<string, int64?> category_items_last_update; | ||
299 | 25 | private HashTable<string, Gee.ArrayList<SoftwareCenterDataProviderService.AppInfo?>> category_items_cached; | ||
300 | 26 | |||
301 | 27 | public SoftwareCenterDataCache (int64 category_items_lifetime) | ||
302 | 28 | { | ||
303 | 29 | category_items_last_update = new HashTable<string, int64?> (str_hash, str_equal); | ||
304 | 30 | category_items_cached = new HashTable<string, Gee.ArrayList<SoftwareCenterDataProviderService.AppInfo?>> (str_hash, str_equal); | ||
305 | 31 | this.category_items_lifetime = category_items_lifetime; | ||
306 | 32 | } | ||
307 | 33 | |||
308 | 34 | internal static bool outdated (ref int64 last_update, int64 lifetime) | ||
309 | 35 | { | ||
310 | 36 | var current_time = new GLib.DateTime.now_utc (); | ||
311 | 37 | int64 current_unix_time = current_time.to_unix (); | ||
312 | 38 | if (current_unix_time > last_update + lifetime) | ||
313 | 39 | { | ||
314 | 40 | last_update = current_unix_time; | ||
315 | 41 | return true; | ||
316 | 42 | } | ||
317 | 43 | return false; | ||
318 | 44 | } | ||
319 | 45 | |||
320 | 46 | public override SoftwareCenterDataProviderService.AppInfo?[] get_items_for_category (string category_name) throws Error | ||
321 | 47 | { | ||
322 | 48 | int64 last_update = 0; | ||
323 | 49 | if (category_items_last_update.contains (category_name)) | ||
324 | 50 | { | ||
325 | 51 | last_update = category_items_last_update[category_name]; | ||
326 | 52 | } | ||
327 | 53 | |||
328 | 54 | if (outdated (ref last_update, category_items_lifetime)) | ||
329 | 55 | { | ||
330 | 56 | category_items_last_update[category_name] = last_update; | ||
331 | 57 | |||
332 | 58 | var data = base.get_items_for_category (category_name); | ||
333 | 59 | var results = new Gee.ArrayList<SoftwareCenterDataProviderService.AppInfo?> (); | ||
334 | 60 | foreach (var item in data) | ||
335 | 61 | { | ||
336 | 62 | results.add (item); | ||
337 | 63 | } | ||
338 | 64 | category_items_cached[category_name] = results; | ||
339 | 65 | return data; | ||
340 | 66 | } | ||
341 | 67 | return category_items_cached[category_name].to_array (); | ||
342 | 68 | } | ||
343 | 69 | } | ||
344 | 70 | |||
345 | 71 | } | ||
346 | 0 | \ No newline at end of file | 72 | \ No newline at end of file |
347 | 1 | 73 | ||
348 | === modified file 'src/software-center-data-provider.vala' | |||
349 | --- src/software-center-data-provider.vala 2012-09-06 08:11:17 +0000 | |||
350 | +++ src/software-center-data-provider.vala 2012-09-17 15:59:25 +0000 | |||
351 | @@ -24,7 +24,18 @@ | |||
352 | 24 | [DBus (name = "com.ubuntu.SoftwareCenterDataProvider")] | 24 | [DBus (name = "com.ubuntu.SoftwareCenterDataProvider")] |
353 | 25 | public interface SoftwareCenterDataProviderService: GLib.Object | 25 | public interface SoftwareCenterDataProviderService: GLib.Object |
354 | 26 | { | 26 | { |
355 | 27 | public struct AppInfo | ||
356 | 28 | { | ||
357 | 29 | string application_name; | ||
358 | 30 | string package_name; | ||
359 | 31 | string icon; | ||
360 | 32 | string desktop_file; | ||
361 | 33 | } | ||
362 | 34 | |||
363 | 27 | public abstract HashTable<string, Variant> get_app_details (string appname, string pkgname) throws Error; | 35 | public abstract HashTable<string, Variant> get_app_details (string appname, string pkgname) throws Error; |
364 | 36 | public abstract string[] get_available_categories () throws Error; | ||
365 | 37 | public abstract string[] get_available_subcategories () throws Error; | ||
366 | 38 | public abstract AppInfo?[] get_items_for_category (string category_name) throws Error; | ||
367 | 28 | } | 39 | } |
368 | 29 | 40 | ||
369 | 30 | public class SoftwareCenterDataProviderProxy: GLib.Object | 41 | public class SoftwareCenterDataProviderProxy: GLib.Object |
370 | @@ -125,6 +136,15 @@ | |||
371 | 125 | return data; | 136 | return data; |
372 | 126 | } | 137 | } |
373 | 127 | 138 | ||
374 | 139 | public virtual SoftwareCenterDataProviderService.AppInfo?[] get_items_for_category (string category_name) throws Error | ||
375 | 140 | { | ||
376 | 141 | if (_service == null) | ||
377 | 142 | connect_to (); | ||
378 | 143 | |||
379 | 144 | SoftwareCenterDataProviderService.AppInfo?[] data = _service.get_items_for_category (category_name); | ||
380 | 145 | return data; | ||
381 | 146 | } | ||
382 | 147 | |||
383 | 128 | private SoftwareCenterDataProviderService _service; | 148 | private SoftwareCenterDataProviderService _service; |
384 | 129 | } | 149 | } |
385 | 130 | } | 150 | } |
386 | 131 | 151 | ||
387 | === modified file 'src/unity-package-search.cc' | |||
388 | --- src/unity-package-search.cc 2012-08-08 16:57:47 +0000 | |||
389 | +++ src/unity-package-search.cc 2012-09-17 15:59:25 +0000 | |||
390 | @@ -475,6 +475,68 @@ | |||
391 | 475 | return result; | 475 | return result; |
392 | 476 | } | 476 | } |
393 | 477 | 477 | ||
394 | 478 | /** | ||
395 | 479 | * Get applications matching given xapian filter query and additionally filter results out | ||
396 | 480 | * using AppFilterCallback, until n_apps matching apps are found. | ||
397 | 481 | * Results are filtered out if AppFilterCallback returns FALSE. | ||
398 | 482 | */ | ||
399 | 483 | UnityPackageSearchResult* unity_package_searcher_get_apps (UnityPackageSearcher *searcher, | ||
400 | 484 | const gchar *filter_query, | ||
401 | 485 | guint n_apps, | ||
402 | 486 | AppFilterCallback cb, | ||
403 | 487 | gpointer data) | ||
404 | 488 | { | ||
405 | 489 | UnityPackageSearchResult *result; | ||
406 | 490 | GHashTable *unique; | ||
407 | 491 | guint num_matches = 0; | ||
408 | 492 | |||
409 | 493 | g_return_val_if_fail (searcher != NULL, NULL); | ||
410 | 494 | |||
411 | 495 | unique = g_hash_table_new (g_str_hash, g_str_equal); | ||
412 | 496 | |||
413 | 497 | result = g_slice_new0 (UnityPackageSearchResult); | ||
414 | 498 | |||
415 | 499 | g_debug ("FILTER %s", filter_query); | ||
416 | 500 | |||
417 | 501 | Xapian::Query query; | ||
418 | 502 | try | ||
419 | 503 | { | ||
420 | 504 | query = searcher->query_parser->parse_query (filter_query, QUERY_PARSER_FILTER_FLAGS); | ||
421 | 505 | searcher->enquire->set_sort_by_relevance (); | ||
422 | 506 | searcher->enquire->set_query(query); | ||
423 | 507 | |||
424 | 508 | Xapian::MSet matches = searcher->enquire->get_mset(0, searcher->db->get_doccount ()); | ||
425 | 509 | Xapian::MSetIterator iter = matches.begin(); | ||
426 | 510 | while (num_matches < n_apps && iter != matches.end()) | ||
427 | 511 | { | ||
428 | 512 | Xapian::Document doc = iter.get_document (); | ||
429 | 513 | UnityPackageInfo *pkginfo = _pkginfo_from_document (doc); | ||
430 | 514 | |||
431 | 515 | if (g_hash_table_lookup_extended (unique, pkginfo->package_name, NULL, NULL) || cb(pkginfo, data) == FALSE) | ||
432 | 516 | { | ||
433 | 517 | _free_package_info (pkginfo); | ||
434 | 518 | } | ||
435 | 519 | else | ||
436 | 520 | { | ||
437 | 521 | g_hash_table_insert (unique, pkginfo->package_name, NULL); | ||
438 | 522 | result->results = g_slist_prepend (result->results, pkginfo); | ||
439 | 523 | num_matches++; | ||
440 | 524 | } | ||
441 | 525 | ++iter; | ||
442 | 526 | } | ||
443 | 527 | } | ||
444 | 528 | catch (Xapian::Error e) | ||
445 | 529 | { | ||
446 | 530 | g_debug ("Error getting apps for query '%s': %s", filter_query, e.get_msg().c_str()); | ||
447 | 531 | return g_slice_new0 (UnityPackageSearchResult); | ||
448 | 532 | } | ||
449 | 533 | |||
450 | 534 | g_hash_table_unref (unique); | ||
451 | 535 | |||
452 | 536 | result->num_hits = num_matches; | ||
453 | 537 | return result; | ||
454 | 538 | } | ||
455 | 539 | |||
456 | 478 | UnityPackageSearchResult* | 540 | UnityPackageSearchResult* |
457 | 479 | unity_package_searcher_get_random_apps (UnityPackageSearcher *searcher, | 541 | unity_package_searcher_get_random_apps (UnityPackageSearcher *searcher, |
458 | 480 | const gchar *filter_query, | 542 | const gchar *filter_query, |
459 | 481 | 543 | ||
460 | === modified file 'src/unity-package-search.h' | |||
461 | --- src/unity-package-search.h 2012-07-26 14:07:49 +0000 | |||
462 | +++ src/unity-package-search.h 2012-09-17 15:59:25 +0000 | |||
463 | @@ -49,9 +49,12 @@ | |||
464 | 49 | gint relevancy; | 49 | gint relevancy; |
465 | 50 | } UnityPackageInfo; | 50 | } UnityPackageInfo; |
466 | 51 | 51 | ||
467 | 52 | typedef gboolean (*AppFilterCallback)(UnityPackageInfo *, void *); | ||
468 | 53 | |||
469 | 52 | #ifdef __cplusplus | 54 | #ifdef __cplusplus |
470 | 53 | extern "C" { | 55 | extern "C" { |
471 | 54 | #endif | 56 | #endif |
472 | 57 | |||
473 | 55 | 58 | ||
474 | 56 | UnityPackageSearcher* unity_package_searcher_new (); | 59 | UnityPackageSearcher* unity_package_searcher_new (); |
475 | 57 | 60 | ||
476 | @@ -69,6 +72,12 @@ | |||
477 | 69 | const gchar *filter_query, | 72 | const gchar *filter_query, |
478 | 70 | guint n_apps); | 73 | guint n_apps); |
479 | 71 | 74 | ||
480 | 75 | UnityPackageSearchResult* unity_package_searcher_get_apps (UnityPackageSearcher *searcher, | ||
481 | 76 | const gchar *filter_query, | ||
482 | 77 | guint n_apps, | ||
483 | 78 | AppFilterCallback cb, | ||
484 | 79 | gpointer data); | ||
485 | 80 | |||
486 | 72 | void unity_package_search_result_free (UnityPackageSearchResult *result); | 81 | void unity_package_search_result_free (UnityPackageSearchResult *result); |
487 | 73 | 82 | ||
488 | 74 | void unity_package_package_info_free (UnityPackageInfo *pkginfo); | 83 | void unity_package_package_info_free (UnityPackageInfo *pkginfo); |
489 | 75 | 84 | ||
490 | === modified file 'vapi/unity-package-search.vapi' | |||
491 | --- vapi/unity-package-search.vapi 2012-08-08 13:52:11 +0000 | |||
492 | +++ vapi/unity-package-search.vapi 2012-09-17 15:59:25 +0000 | |||
493 | @@ -18,6 +18,8 @@ | |||
494 | 18 | BY_RELEVANCY | 18 | BY_RELEVANCY |
495 | 19 | } | 19 | } |
496 | 20 | 20 | ||
497 | 21 | public delegate bool AppFilterCallback (PackageInfo pkginfo); | ||
498 | 22 | |||
499 | 21 | [Compact] | 23 | [Compact] |
500 | 22 | [CCode (free_function = "unity_package_searcher_free", cheader_filename = "unity-package-search.h")] | 24 | [CCode (free_function = "unity_package_searcher_free", cheader_filename = "unity-package-search.h")] |
501 | 23 | public class Searcher { | 25 | public class Searcher { |
502 | @@ -27,6 +29,7 @@ | |||
503 | 27 | public Searcher.for_menu(GMenu.Tree menu); | 29 | public Searcher.for_menu(GMenu.Tree menu); |
504 | 28 | public SearchResult search (string search_string, uint max_hits, Unity.Package.SearchType search_type, Unity.Package.Sort sort); | 30 | public SearchResult search (string search_string, uint max_hits, Unity.Package.SearchType search_type, Unity.Package.Sort sort); |
505 | 29 | public SearchResult get_random_apps (string? filter_query, uint n_apps); | 31 | public SearchResult get_random_apps (string? filter_query, uint n_apps); |
506 | 32 | public SearchResult get_apps (string? filter_query, uint n_apps, AppFilterCallback cb); | ||
507 | 30 | public PackageInfo? get_by_desktop_file (string desktop_file); | 33 | public PackageInfo? get_by_desktop_file (string desktop_file); |
508 | 31 | } | 34 | } |
509 | 32 | 35 |
93 + var whats_new = sc_data_ provider. get_items_ for_category ("What’s New"); //make sure there is unicode char U+2019 (right quotation mark)
Very nasty that we need to pass an exact unicode string, imo the service should be fixed.