Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Side by Side Diff: components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.cc

Issue 2640773002: [NTP::PhysicalWeb] Filter our pages with same group_id. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h" 5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 19 matching lines...) Expand all
30 using base::DictionaryValue; 30 using base::DictionaryValue;
31 using base::ListValue; 31 using base::ListValue;
32 using base::Value; 32 using base::Value;
33 33
34 namespace ntp_snippets { 34 namespace ntp_snippets {
35 35
36 namespace { 36 namespace {
37 37
38 const size_t kMaxSuggestionsCount = 10; 38 const size_t kMaxSuggestionsCount = 10;
39 39
40 std::string GetPageId(const DictionaryValue& page_dictionary) { 40 std::string GetPageId(const DictionaryValue& page_dictionary) {
Marc Treib 2017/01/18 11:24:01 Maybe make a GetGroupId function similar to this,
vitaliii 2017/01/18 11:48:16 Done. They do, but they may do this after BP. htt
41 std::string raw_resolved_url; 41 std::string raw_resolved_url;
42 if (!page_dictionary.GetString(physical_web::kResolvedUrlKey, 42 if (!page_dictionary.GetString(physical_web::kResolvedUrlKey,
43 &raw_resolved_url)) { 43 &raw_resolved_url)) {
44 LOG(DFATAL) << physical_web::kResolvedUrlKey << " field is missing."; 44 LOG(DFATAL) << physical_web::kResolvedUrlKey << " field is missing.";
45 } 45 }
46 return raw_resolved_url; 46 return raw_resolved_url;
47 } 47 }
48 48
49 bool CompareByDistanceClosestFirst(const DictionaryValue* left,
Marc Treib 2017/01/18 11:24:01 nit: "ClosestFirst" IMO isn't necessary to state,
vitaliii 2017/01/18 11:48:15 Done.
50 const DictionaryValue* right) {
51 double left_distance, right_distance;
52 bool success =
53 left->GetDouble(physical_web::kDistanceEstimateKey, &left_distance);
54 success =
55 right->GetDouble(physical_web::kDistanceEstimateKey, &right_distance) &&
56 success;
57 if (!success) {
58 LOG(DFATAL) << "Distance field is missing.";
59 }
60
61 // When there is no estimate, the value is <= 0, so we need to treat this case
62 // manually.
Marc Treib 2017/01/18 11:24:01 nit: Treat how, exactly? Or maybe actually just as
vitaliii 2017/01/18 11:48:16 Do you how to get infinity for double? I rewrote
Marc Treib 2017/01/18 11:54:47 std::numeric_limits<double>::infinity(); (or there
vitaliii 2017/01/18 14:02:27 Acknowledged.
63 bool is_left_estimated = left_distance > 0;
64 bool is_right_estimated = right_distance > 0;
65
66 if (is_left_estimated != is_right_estimated)
67 return is_left_estimated;
68 return left_distance < right_distance;
69 }
70
71 void FilterOutByGroupId(
72 std::vector<const DictionaryValue*>* page_dictionaries) {
73 // |std::unique| only removes duplicates that immediately follow each other.
74 // Thus, first, we have to sort by group_id and distance and only then remove
75 // duplicates.
76 std::sort(page_dictionaries->begin(), page_dictionaries->end(),
77 [](const DictionaryValue* left, const DictionaryValue* right) {
78 std::string left_group_id, right_group_id;
79 bool success =
80 left->GetString(physical_web::kGroupIdKey, &left_group_id);
81 success = right->GetString(physical_web::kGroupIdKey,
82 &right_group_id) &&
83 success;
84 if (!success) {
85 LOG(DFATAL) << "Group id field is missing.";
Marc Treib 2017/01/18 11:24:01 So the field must always be there, even if it's em
vitaliii 2017/01/18 11:48:16 As experiments show, yes. This won't be a problem
86 }
87
88 if (left_group_id != right_group_id) {
89 return left_group_id < right_group_id;
90 }
91
92 // We want closest pages first, so in case of same group_id we
93 // sort by distance.
94 return CompareByDistanceClosestFirst(left, right);
95 });
96
97 // Empty group_id must be treated as unique, so we do not apply std::unique to
Marc Treib 2017/01/18 11:24:01 nit: *Each* empty group id must be...
vitaliii 2017/01/18 11:48:16 Done.
98 // them at all.
99 std::vector<const DictionaryValue*>::iterator nonempty_group_id_begin =
Marc Treib 2017/01/18 11:24:01 optional: You could use auto here
vitaliii 2017/01/18 11:48:16 Done.
100 page_dictionaries->begin();
101 for (; nonempty_group_id_begin != page_dictionaries->end();
Marc Treib 2017/01/18 11:24:01 Since you're already using std algorithms quite he
vitaliii 2017/01/18 11:48:16 Done. Good observation.
102 ++nonempty_group_id_begin) {
103 std::string group_id;
104
105 (*nonempty_group_id_begin)->GetString(physical_web::kGroupIdKey, &group_id);
106 if (!group_id.empty()) {
107 break;
108 }
109 }
110
111 std::vector<const DictionaryValue*>::iterator new_end = std::unique(
Marc Treib 2017/01/18 11:24:01 optional: auto
vitaliii 2017/01/18 11:48:15 Done.
112 nonempty_group_id_begin, page_dictionaries->end(),
113 [](const DictionaryValue* left, const DictionaryValue* right) {
114 std::string left_group_id, right_group_id;
115
116 left->GetString(physical_web::kGroupIdKey, &left_group_id);
117 right->GetString(physical_web::kGroupIdKey, &right_group_id);
118 return left_group_id == right_group_id;
119 });
120
121 page_dictionaries->erase(new_end, page_dictionaries->end());
122 }
123
49 } // namespace 124 } // namespace
50 125
51 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( 126 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider(
52 ContentSuggestionsProvider::Observer* observer, 127 ContentSuggestionsProvider::Observer* observer,
53 physical_web::PhysicalWebDataSource* physical_web_data_source, 128 physical_web::PhysicalWebDataSource* physical_web_data_source,
54 PrefService* pref_service) 129 PrefService* pref_service)
55 : ContentSuggestionsProvider(observer), 130 : ContentSuggestionsProvider(observer),
56 category_status_(CategoryStatus::AVAILABLE), 131 category_status_(CategoryStatus::AVAILABLE),
57 provided_category_( 132 provided_category_(
58 Category::FromKnownCategory(KnownCategories::PHYSICAL_WEB_PAGES)), 133 Category::FromKnownCategory(KnownCategories::PHYSICAL_WEB_PAGES)),
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 290
216 if (old_dismissed_ids.count(page_id)) { 291 if (old_dismissed_ids.count(page_id)) {
217 new_dismissed_ids.insert(page_id); 292 new_dismissed_ids.insert(page_id);
218 } 293 }
219 } 294 }
220 295
221 if (old_dismissed_ids.size() != new_dismissed_ids.size()) { 296 if (old_dismissed_ids.size() != new_dismissed_ids.size()) {
222 StoreDismissedIDsToPrefs(new_dismissed_ids); 297 StoreDismissedIDsToPrefs(new_dismissed_ids);
223 } 298 }
224 299
300 FilterOutByGroupId(&page_dictionaries);
301
225 std::sort(page_dictionaries.begin(), page_dictionaries.end(), 302 std::sort(page_dictionaries.begin(), page_dictionaries.end(),
226 [](const DictionaryValue* left, const DictionaryValue* right) { 303 CompareByDistanceClosestFirst);
227 double left_distance, right_distance;
228 bool success = left->GetDouble(physical_web::kDistanceEstimateKey,
229 &left_distance);
230 success = right->GetDouble(physical_web::kDistanceEstimateKey,
231 &right_distance) &&
232 success;
233 if (!success) {
234 LOG(DFATAL) << "Distance field is missing.";
235 }
236 return left_distance < right_distance;
237 });
238 304
239 std::vector<ContentSuggestion> suggestions; 305 std::vector<ContentSuggestion> suggestions;
240 for (const DictionaryValue* page_dictionary : page_dictionaries) { 306 for (const DictionaryValue* page_dictionary : page_dictionaries) {
241 if (static_cast<int>(suggestions.size()) == max_quantity) { 307 if (static_cast<int>(suggestions.size()) == max_quantity) {
242 break; 308 break;
243 } 309 }
244 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); 310 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary));
245 } 311 }
246 312
247 return suggestions; 313 return suggestions;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 } 373 }
308 374
309 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( 375 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs(
310 const std::set<std::string>& dismissed_ids) { 376 const std::set<std::string>& dismissed_ids) {
311 prefs::StoreDismissedIDsToPrefs(pref_service_, 377 prefs::StoreDismissedIDsToPrefs(pref_service_,
312 prefs::kDismissedPhysicalWebPageSuggestions, 378 prefs::kDismissedPhysicalWebPageSuggestions,
313 dismissed_ids); 379 dismissed_ids);
314 } 380 }
315 381
316 } // namespace ntp_snippets 382 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698