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

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

Issue 2677983002: Merge of "Replace deprecated calls to GetMetadata in Zine provider." (Closed)
Patch Set: Created 3 years, 10 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>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "components/grit/components_scaled_resources.h" 19 #include "components/grit/components_scaled_resources.h"
20 #include "components/ntp_snippets/pref_names.h" 20 #include "components/ntp_snippets/pref_names.h"
21 #include "components/ntp_snippets/pref_util.h" 21 #include "components/ntp_snippets/pref_util.h"
22 #include "components/physical_web/data_source/physical_web_data_source.h"
22 #include "components/prefs/pref_registry_simple.h" 23 #include "components/prefs/pref_registry_simple.h"
23 #include "components/prefs/pref_service.h" 24 #include "components/prefs/pref_service.h"
24 #include "grit/components_strings.h" 25 #include "grit/components_strings.h"
25 #include "ui/base/l10n/l10n_util.h" 26 #include "ui/base/l10n/l10n_util.h"
26 #include "ui/base/resource/resource_bundle.h" 27 #include "ui/base/resource/resource_bundle.h"
27 #include "ui/gfx/image/image.h" 28 #include "ui/gfx/image/image.h"
28 #include "url/gurl.h" 29 #include "url/gurl.h"
29 30
30 using base::DictionaryValue;
31 using base::ListValue;
32 using base::Value;
33
34 namespace ntp_snippets { 31 namespace ntp_snippets {
35 32
36 namespace { 33 namespace {
37 34
38 const size_t kMaxSuggestionsCount = 10; 35 const size_t kMaxSuggestionsCount = 10;
39 36
40 std::string GetGroupId(const DictionaryValue& page_dictionary) { 37 std::string GetPageId(const physical_web::Metadata& page_metadata) {
41 std::string group_id; 38 return page_metadata.resolved_url.spec();
42 if (!page_dictionary.GetString(physical_web::kGroupIdKey, &group_id)) {
43 LOG(DFATAL) << physical_web::kGroupIdKey << " field is missing.";
44 }
45 return group_id;
46 } 39 }
47 40
48 std::string GetPageId(const DictionaryValue& page_dictionary) { 41 bool CompareByDistance(const physical_web::Metadata& left,
49 std::string raw_resolved_url; 42 const physical_web::Metadata& right) {
50 if (!page_dictionary.GetString(physical_web::kResolvedUrlKey,
51 &raw_resolved_url)) {
52 LOG(DFATAL) << physical_web::kResolvedUrlKey << " field is missing.";
53 }
54 return raw_resolved_url;
55 }
56
57 bool CompareByDistance(const DictionaryValue* left,
58 const DictionaryValue* right) {
59 double left_distance, right_distance;
60 bool success =
61 left->GetDouble(physical_web::kDistanceEstimateKey, &left_distance);
62 success =
63 right->GetDouble(physical_web::kDistanceEstimateKey, &right_distance) &&
64 success;
65 if (!success) {
66 LOG(DFATAL) << "Distance field is missing.";
67 }
68
69 // When there is no estimate, the value is <= 0, so we implicitly treat it as 43 // When there is no estimate, the value is <= 0, so we implicitly treat it as
70 // infinity. 44 // infinity.
71 bool is_left_estimated = left_distance > 0; 45 bool is_left_estimated = left.distance_estimate > 0;
72 bool is_right_estimated = right_distance > 0; 46 bool is_right_estimated = right.distance_estimate > 0;
73 47
74 if (is_left_estimated != is_right_estimated) 48 if (is_left_estimated != is_right_estimated)
75 return is_left_estimated; 49 return is_left_estimated;
76 return left_distance < right_distance; 50 return left.distance_estimate < right.distance_estimate;
77 } 51 }
78 52
79 void FilterOutByGroupId( 53 void FilterOutByGroupId(
80 std::vector<const DictionaryValue*>* page_dictionaries) { 54 physical_web::MetadataList& page_metadata_list) {
81 // |std::unique| only removes duplicates that immediately follow each other. 55 // |std::unique| only removes duplicates that immediately follow each other.
82 // Thus, first, we have to sort by group_id and distance and only then remove 56 // Thus, first, we have to sort by group_id and distance and only then remove
83 // duplicates. 57 // duplicates.
84 std::sort(page_dictionaries->begin(), page_dictionaries->end(), 58 std::sort(page_metadata_list.begin(), page_metadata_list.end(),
85 [](const DictionaryValue* left, const DictionaryValue* right) { 59 [](const physical_web::Metadata& left,
86 std::string left_group_id = GetGroupId(*left); 60 const physical_web::Metadata& right) {
87 std::string right_group_id = GetGroupId(*right); 61 if (left.group_id != right.group_id) {
88 62 return left.group_id < right.group_id;
89 if (left_group_id != right_group_id) {
90 return left_group_id < right_group_id;
91 } 63 }
92 64
93 // We want closest pages first, so in case of same group_id we 65 // We want closest pages first, so in case of same group_id we
94 // sort by distance. 66 // sort by distance.
95 return CompareByDistance(left, right); 67 return CompareByDistance(left, right);
96 }); 68 });
97 69
98 // Each empty group_id must be treated as unique, so we do not apply 70 // Each empty group_id must be treated as unique, so we do not apply
99 // std::unique to them at all. 71 // std::unique to them at all.
100 auto nonempty_group_id_begin = std::find_if( 72 auto nonempty_group_id_begin = std::find_if(
101 page_dictionaries->begin(), page_dictionaries->end(), 73 page_metadata_list.begin(), page_metadata_list.end(),
102 [](const DictionaryValue* page) { return !GetGroupId(*page).empty(); }); 74 [](const physical_web::Metadata& page) {
75 return !page.group_id.empty();
76 });
103 77
104 auto new_end = std::unique( 78 auto new_end = std::unique(
105 nonempty_group_id_begin, page_dictionaries->end(), 79 nonempty_group_id_begin, page_metadata_list.end(),
106 [](const DictionaryValue* left, const DictionaryValue* right) { 80 [](const physical_web::Metadata& left,
107 return GetGroupId(*left) == GetGroupId(*right); 81 const physical_web::Metadata& right) {
82 return left.group_id == right.group_id;
108 }); 83 });
109 84
110 page_dictionaries->erase(new_end, page_dictionaries->end()); 85 page_metadata_list.erase(new_end, page_metadata_list.end());
111 } 86 }
112 87
113 } // namespace 88 } // namespace
114 89
115 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( 90 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider(
116 ContentSuggestionsProvider::Observer* observer, 91 ContentSuggestionsProvider::Observer* observer,
117 physical_web::PhysicalWebDataSource* physical_web_data_source, 92 physical_web::PhysicalWebDataSource* physical_web_data_source,
118 PrefService* pref_service) 93 PrefService* pref_service)
119 : ContentSuggestionsProvider(observer), 94 : ContentSuggestionsProvider(observer),
120 category_status_(CategoryStatus::AVAILABLE), 95 category_status_(CategoryStatus::AVAILABLE),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 168
194 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions( 169 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions(
195 Category category) { 170 Category category) {
196 // Ignored 171 // Ignored
197 } 172 }
198 173
199 void PhysicalWebPageSuggestionsProvider::GetDismissedSuggestionsForDebugging( 174 void PhysicalWebPageSuggestionsProvider::GetDismissedSuggestionsForDebugging(
200 Category category, 175 Category category,
201 const DismissedSuggestionsCallback& callback) { 176 const DismissedSuggestionsCallback& callback) {
202 DCHECK_EQ(provided_category_, category); 177 DCHECK_EQ(provided_category_, category);
203 std::unique_ptr<ListValue> page_values = 178 std::unique_ptr<physical_web::MetadataList> page_metadata_list =
204 physical_web_data_source_->GetMetadata(); 179 physical_web_data_source_->GetMetadataList();
205 const std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs(); 180 const std::set<std::string> dismissed_ids = ReadDismissedIDsFromPrefs();
206 std::vector<ContentSuggestion> suggestions; 181 std::vector<ContentSuggestion> suggestions;
207 for (const std::unique_ptr<Value>& page_value : *page_values) { 182 for (const auto& page_metadata : *page_metadata_list) {
208 const DictionaryValue* page_dictionary; 183 if (dismissed_ids.count(GetPageId(page_metadata))) {
209 if (!page_value->GetAsDictionary(&page_dictionary)) { 184 suggestions.push_back(ConvertPhysicalWebPage(page_metadata));
210 LOG(DFATAL) << "Physical Web page is not a dictionary.";
211 continue;
212 }
213
214 if (dismissed_ids.count(GetPageId(*page_dictionary))) {
215 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary));
216 } 185 }
217 } 186 }
218 187
219 callback.Run(std::move(suggestions)); 188 callback.Run(std::move(suggestions));
220 } 189 }
221 190
222 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( 191 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
223 Category category) { 192 Category category) {
224 DCHECK_EQ(provided_category_, category); 193 DCHECK_EQ(provided_category_, category);
225 StoreDismissedIDsToPrefs(std::set<std::string>()); 194 StoreDismissedIDsToPrefs(std::set<std::string>());
(...skipping 23 matching lines...) Expand all
249 observer()->OnNewSuggestions(this, provided_category_, 218 observer()->OnNewSuggestions(this, provided_category_,
250 GetMostRecentPhysicalWebPagesWithFilter( 219 GetMostRecentPhysicalWebPagesWithFilter(
251 kMaxSuggestionsCount, 220 kMaxSuggestionsCount,
252 /*excluded_ids=*/std::set<std::string>())); 221 /*excluded_ids=*/std::set<std::string>()));
253 } 222 }
254 223
255 std::vector<ContentSuggestion> 224 std::vector<ContentSuggestion>
256 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter( 225 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter(
257 int max_quantity, 226 int max_quantity,
258 const std::set<std::string>& excluded_ids) { 227 const std::set<std::string>& excluded_ids) {
259 std::unique_ptr<ListValue> page_values = 228 std::unique_ptr<physical_web::MetadataList> page_metadata_list =
260 physical_web_data_source_->GetMetadata(); 229 physical_web_data_source_->GetMetadataList();
261 230
262 // These is to filter out dismissed suggestions and at the same time prune the 231 // These is to filter out dismissed suggestions and at the same time prune the
263 // dismissed IDs list removing nonavailable pages (this is need since some 232 // dismissed IDs list removing nonavailable pages (this is need since some
264 // OnLost() calls may have been missed). 233 // OnLost() calls may have been missed).
265 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs(); 234 const std::set<std::string> old_dismissed_ids = ReadDismissedIDsFromPrefs();
266 std::set<std::string> new_dismissed_ids; 235 std::set<std::string> new_dismissed_ids;
267 std::vector<const DictionaryValue*> page_dictionaries; 236 physical_web::MetadataList filtered_metadata_list;
268 for (const std::unique_ptr<Value>& page_value : *page_values) { 237 for (const auto& page_metadata : *page_metadata_list) {
269 const DictionaryValue* page_dictionary; 238 const std::string page_id = GetPageId(page_metadata);
270 if (!page_value->GetAsDictionary(&page_dictionary)) {
271 LOG(DFATAL) << "Physical Web page is not a dictionary.";
272 continue;
273 }
274
275 const std::string page_id = GetPageId(*page_dictionary);
276 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) { 239 if (!excluded_ids.count(page_id) && !old_dismissed_ids.count(page_id)) {
277 page_dictionaries.push_back(page_dictionary); 240 filtered_metadata_list.push_back(page_metadata);
278 } 241 }
279 242
280 if (old_dismissed_ids.count(page_id)) { 243 if (old_dismissed_ids.count(page_id)) {
281 new_dismissed_ids.insert(page_id); 244 new_dismissed_ids.insert(page_id);
282 } 245 }
283 } 246 }
284 247
285 if (old_dismissed_ids.size() != new_dismissed_ids.size()) { 248 if (old_dismissed_ids.size() != new_dismissed_ids.size()) {
286 StoreDismissedIDsToPrefs(new_dismissed_ids); 249 StoreDismissedIDsToPrefs(new_dismissed_ids);
287 } 250 }
288 251
289 FilterOutByGroupId(&page_dictionaries); 252 FilterOutByGroupId(filtered_metadata_list);
290 253
291 std::sort(page_dictionaries.begin(), page_dictionaries.end(), 254 std::sort(filtered_metadata_list.begin(), filtered_metadata_list.end(),
292 CompareByDistance); 255 CompareByDistance);
293 256
294 std::vector<ContentSuggestion> suggestions; 257 std::vector<ContentSuggestion> suggestions;
295 for (const DictionaryValue* page_dictionary : page_dictionaries) { 258 for (const auto& page_metadata : filtered_metadata_list) {
296 if (static_cast<int>(suggestions.size()) == max_quantity) { 259 if (static_cast<int>(suggestions.size()) == max_quantity) {
297 break; 260 break;
298 } 261 }
299 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); 262 suggestions.push_back(ConvertPhysicalWebPage(page_metadata));
300 } 263 }
301 264
302 return suggestions; 265 return suggestions;
303 } 266 }
304 267
305 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( 268 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage(
306 const DictionaryValue& page) const { 269 const physical_web::Metadata& page) const {
307 std::string scanned_url, raw_resolved_url, title, description;
308 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url);
309 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) &&
310 success;
311 success = page.GetString(physical_web::kTitleKey, &title) && success;
312 success =
313 page.GetString(physical_web::kDescriptionKey, &description) && success;
314 if (!success) {
315 LOG(DFATAL) << "Expected field is missing.";
316 }
317
318 const GURL resolved_url(raw_resolved_url);
319 ContentSuggestion suggestion(provided_category_, GetPageId(page), 270 ContentSuggestion suggestion(provided_category_, GetPageId(page),
320 resolved_url); 271 page.resolved_url);
321 DCHECK(base::IsStringUTF8(title)); 272 DCHECK(base::IsStringUTF8(page.title));
322 suggestion.set_title(base::UTF8ToUTF16(title)); 273 suggestion.set_title(base::UTF8ToUTF16(page.title));
323 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host())); 274 suggestion.set_publisher_name(base::UTF8ToUTF16(page.resolved_url.host()));
324 DCHECK(base::IsStringUTF8(description)); 275 DCHECK(base::IsStringUTF8(page.description));
325 suggestion.set_snippet_text(base::UTF8ToUTF16(description)); 276 suggestion.set_snippet_text(base::UTF8ToUTF16(page.description));
326 return suggestion; 277 return suggestion;
327 } 278 }
328 279
329 // PhysicalWebListener implementation. 280 // PhysicalWebListener implementation.
330 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) { 281 void PhysicalWebPageSuggestionsProvider::OnFound(const GURL& url) {
331 FetchPhysicalWebPages(); 282 FetchPhysicalWebPages();
332 } 283 }
333 284
334 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) { 285 void PhysicalWebPageSuggestionsProvider::OnLost(const GURL& url) {
335 InvalidateSuggestion(url.spec()); 286 InvalidateSuggestion(url.spec());
(...skipping 26 matching lines...) Expand all
362 } 313 }
363 314
364 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs( 315 void PhysicalWebPageSuggestionsProvider::StoreDismissedIDsToPrefs(
365 const std::set<std::string>& dismissed_ids) { 316 const std::set<std::string>& dismissed_ids) {
366 prefs::StoreDismissedIDsToPrefs(pref_service_, 317 prefs::StoreDismissedIDsToPrefs(pref_service_,
367 prefs::kDismissedPhysicalWebPageSuggestions, 318 prefs::kDismissedPhysicalWebPageSuggestions,
368 dismissed_ids); 319 dismissed_ids);
369 } 320 }
370 321
371 } // namespace ntp_snippets 322 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698