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

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

Issue 2553643003: [NTP::PhysicalWeb] Implement Fetch for "More" button. (Closed)
Patch Set: treib@ comments. Created 4 years 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 <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 11 matching lines...) Expand all
22 using base::DictionaryValue; 22 using base::DictionaryValue;
23 using base::ListValue; 23 using base::ListValue;
24 using base::Value; 24 using base::Value;
25 25
26 namespace ntp_snippets { 26 namespace ntp_snippets {
27 27
28 namespace { 28 namespace {
29 29
30 const size_t kMaxSuggestionsCount = 10; 30 const size_t kMaxSuggestionsCount = 10;
31 31
32 std::string GetPageId(const DictionaryValue& page_dictionary) {
33 std::string raw_resolved_url;
34 if (!page_dictionary.GetString(physical_web::kResolvedUrlKey,
35 &raw_resolved_url)) {
36 LOG(DFATAL) << "resolvedUrl field is missing.";
Marc Treib 2016/12/06 10:01:34 I'd write this as LOG(DFATAL) << physical_web::kRe
vitaliii 2016/12/06 12:45:52 Done.
37 }
38 return raw_resolved_url;
39 }
40
32 } // namespace 41 } // namespace
33 42
34 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( 43 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider(
35 ContentSuggestionsProvider::Observer* observer, 44 ContentSuggestionsProvider::Observer* observer,
36 CategoryFactory* category_factory, 45 CategoryFactory* category_factory,
37 physical_web::PhysicalWebDataSource* physical_web_data_source) 46 physical_web::PhysicalWebDataSource* physical_web_data_source)
38 : ContentSuggestionsProvider(observer, category_factory), 47 : ContentSuggestionsProvider(observer, category_factory),
39 category_status_(CategoryStatus::AVAILABLE), 48 category_status_(CategoryStatus::AVAILABLE),
40 provided_category_(category_factory->FromKnownCategory( 49 provided_category_(category_factory->FromKnownCategory(
41 KnownCategories::PHYSICAL_WEB_PAGES)), 50 KnownCategories::PHYSICAL_WEB_PAGES)),
(...skipping 10 matching lines...) Expand all
52 61
53 CategoryStatus PhysicalWebPageSuggestionsProvider::GetCategoryStatus( 62 CategoryStatus PhysicalWebPageSuggestionsProvider::GetCategoryStatus(
54 Category category) { 63 Category category) {
55 return category_status_; 64 return category_status_;
56 } 65 }
57 66
58 CategoryInfo PhysicalWebPageSuggestionsProvider::GetCategoryInfo( 67 CategoryInfo PhysicalWebPageSuggestionsProvider::GetCategoryInfo(
59 Category category) { 68 Category category) {
60 // TODO(vitaliii): Use the proper string once it has been agreed on. 69 // TODO(vitaliii): Use the proper string once it has been agreed on.
61 // TODO(vitaliii): Use a translateable string. (crbug.com/667764) 70 // TODO(vitaliii): Use a translateable string. (crbug.com/667764)
62 // TODO(vitaliii): Implement More action. (crbug.com/667759)
63 return CategoryInfo( 71 return CategoryInfo(
64 base::ASCIIToUTF16("Physical web pages"), 72 base::ASCIIToUTF16("Physical web pages"),
65 ContentSuggestionsCardLayout::FULL_CARD, 73 ContentSuggestionsCardLayout::FULL_CARD,
66 /*has_more_action=*/false, 74 /*has_more_action=*/true,
67 /*has_reload_action=*/false, 75 /*has_reload_action=*/false,
68 /*has_view_all_action=*/false, 76 /*has_view_all_action=*/false,
69 /*show_if_empty=*/false, 77 /*show_if_empty=*/false,
70 l10n_util::GetStringUTF16(IDS_NTP_SUGGESTIONS_SECTION_EMPTY)); 78 l10n_util::GetStringUTF16(IDS_NTP_SUGGESTIONS_SECTION_EMPTY));
71 } 79 }
72 80
73 void PhysicalWebPageSuggestionsProvider::DismissSuggestion( 81 void PhysicalWebPageSuggestionsProvider::DismissSuggestion(
74 const ContentSuggestion::ID& suggestion_id) { 82 const ContentSuggestion::ID& suggestion_id) {
75 // TODO(vitaliii): Implement this and then 83 // TODO(vitaliii): Implement this and then
76 // ClearDismissedSuggestionsForDebugging. (crbug.com/667766) 84 // ClearDismissedSuggestionsForDebugging. (crbug.com/667766)
77 } 85 }
78 86
79 void PhysicalWebPageSuggestionsProvider::FetchSuggestionImage( 87 void PhysicalWebPageSuggestionsProvider::FetchSuggestionImage(
80 const ContentSuggestion::ID& suggestion_id, 88 const ContentSuggestion::ID& suggestion_id,
81 const ImageFetchedCallback& callback) { 89 const ImageFetchedCallback& callback) {
82 // TODO(vitaliii): Implement. (crbug.com/667765) 90 // TODO(vitaliii): Implement. (crbug.com/667765)
83 base::ThreadTaskRunnerHandle::Get()->PostTask( 91 base::ThreadTaskRunnerHandle::Get()->PostTask(
84 FROM_HERE, base::Bind(callback, gfx::Image())); 92 FROM_HERE, base::Bind(callback, gfx::Image()));
85 } 93 }
86 94
87 void PhysicalWebPageSuggestionsProvider::Fetch( 95 void PhysicalWebPageSuggestionsProvider::Fetch(
88 const Category& category, 96 const Category& category,
89 const std::set<std::string>& known_suggestion_ids, 97 const std::set<std::string>& known_suggestion_ids,
90 const FetchDoneCallback& callback) { 98 const FetchDoneCallback& callback) {
91 LOG(DFATAL) 99 DCHECK_EQ(category, provided_category_);
92 << "PhysicalWebPageSuggestionsProvider has no |Fetch| functionality!";
93 base::ThreadTaskRunnerHandle::Get()->PostTask( 100 base::ThreadTaskRunnerHandle::Get()->PostTask(
94 FROM_HERE, 101 FROM_HERE,
95 base::Bind(callback, Status(StatusCode::PERMANENT_ERROR, 102 base::Bind(callback, Status(StatusCode::SUCCESS),
96 "PhysicalWebPageSuggestionsProvider " 103 base::Passed(GetMostRecentPhysicalWebPagesWithFilter(
97 "has no |Fetch| functionality!"), 104 kMaxSuggestionsCount, known_suggestion_ids))));
98 base::Passed(std::vector<ContentSuggestion>())));
99 } 105 }
100 106
101 void PhysicalWebPageSuggestionsProvider::ClearHistory( 107 void PhysicalWebPageSuggestionsProvider::ClearHistory(
102 base::Time begin, 108 base::Time begin,
103 base::Time end, 109 base::Time end,
104 const base::Callback<bool(const GURL& url)>& filter) { 110 const base::Callback<bool(const GURL& url)>& filter) {
105 ClearDismissedSuggestionsForDebugging(provided_category_); 111 ClearDismissedSuggestionsForDebugging(provided_category_);
106 } 112 }
107 113
108 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions( 114 void PhysicalWebPageSuggestionsProvider::ClearCachedSuggestions(
(...skipping 20 matching lines...) Expand all
129 CategoryStatus new_status) { 135 CategoryStatus new_status) {
130 if (category_status_ == new_status) { 136 if (category_status_ == new_status) {
131 return; 137 return;
132 } 138 }
133 category_status_ = new_status; 139 category_status_ = new_status;
134 observer()->OnCategoryStatusChanged(this, provided_category_, new_status); 140 observer()->OnCategoryStatusChanged(this, provided_category_, new_status);
135 } 141 }
136 142
137 void PhysicalWebPageSuggestionsProvider::FetchPhysicalWebPages() { 143 void PhysicalWebPageSuggestionsProvider::FetchPhysicalWebPages() {
138 NotifyStatusChanged(CategoryStatus::AVAILABLE); 144 NotifyStatusChanged(CategoryStatus::AVAILABLE);
145 observer()->OnNewSuggestions(this, provided_category_,
146 GetMostRecentPhysicalWebPagesWithFilter(
147 kMaxSuggestionsCount,
148 /*excluded_ids=*/std::set<std::string>()));
149 }
150
151 std::vector<ContentSuggestion>
152 PhysicalWebPageSuggestionsProvider::GetMostRecentPhysicalWebPagesWithFilter(
153 int max_quantity,
154 const std::set<std::string>& excluded_ids) {
139 std::unique_ptr<ListValue> page_values = 155 std::unique_ptr<ListValue> page_values =
140 physical_web_data_source_->GetMetadata(); 156 physical_web_data_source_->GetMetadata();
141 157
142 std::vector<const DictionaryValue*> page_dictionaries; 158 std::vector<const DictionaryValue*> page_dictionaries;
143 for (const std::unique_ptr<Value>& page_value : *page_values) { 159 for (const std::unique_ptr<Value>& page_value : *page_values) {
144 const DictionaryValue* page_dictionary; 160 const DictionaryValue* page_dictionary;
145 if (!page_value->GetAsDictionary(&page_dictionary)) { 161 if (!page_value->GetAsDictionary(&page_dictionary)) {
146 LOG(DFATAL) << "Physical Web page is not a dictionary."; 162 LOG(DFATAL) << "Physical Web page is not a dictionary.";
147 } 163 }
148 page_dictionaries.push_back(page_dictionary); 164 if (!excluded_ids.count(GetPageId(*page_dictionary))) {
Marc Treib 2016/12/06 10:01:34 page_dictionary can be null or uninitialized. LOG(
vitaliii 2016/12/06 12:45:52 Done.
165 page_dictionaries.push_back(page_dictionary);
166 }
149 } 167 }
150 168
151 std::sort(page_dictionaries.begin(), page_dictionaries.end(), 169 std::sort(page_dictionaries.begin(), page_dictionaries.end(),
152 [](const DictionaryValue* left, const DictionaryValue* right) { 170 [](const DictionaryValue* left, const DictionaryValue* right) {
153 double left_distance, right_distance; 171 double left_distance, right_distance;
154 bool success = left->GetDouble(physical_web::kDistanceEstimateKey, 172 bool success = left->GetDouble(physical_web::kDistanceEstimateKey,
155 &left_distance); 173 &left_distance);
156 success = right->GetDouble(physical_web::kDistanceEstimateKey, 174 success = right->GetDouble(physical_web::kDistanceEstimateKey,
157 &right_distance) && 175 &right_distance) &&
158 success; 176 success;
159 if (!success) { 177 if (!success) {
160 LOG(DFATAL) << "Distance field is missing."; 178 LOG(DFATAL) << "Distance field is missing.";
161 } 179 }
162 return left_distance < right_distance; 180 return left_distance < right_distance;
163 }); 181 });
164 182
165 std::vector<ContentSuggestion> suggestions; 183 std::vector<ContentSuggestion> suggestions;
166 for (const DictionaryValue* page_dictionary : page_dictionaries) { 184 for (const DictionaryValue* page_dictionary : page_dictionaries) {
167 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); 185 if (static_cast<int>(suggestions.size()) == max_quantity) {
168 if (suggestions.size() == kMaxSuggestionsCount) {
169 break; 186 break;
170 } 187 }
188 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary));
171 } 189 }
172 190
173 observer()->OnNewSuggestions(this, provided_category_, 191 return suggestions;
174 std::move(suggestions));
175 } 192 }
176 193
177 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( 194 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage(
178 const DictionaryValue& page) const { 195 const DictionaryValue& page) const {
179 std::string scanned_url, raw_resolved_url, title, description; 196 std::string scanned_url, raw_resolved_url, title, description;
180 int scan_timestamp; 197 int scan_timestamp;
181 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url); 198 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url);
182 success = page.GetInteger(physical_web::kScanTimestampKey, &scan_timestamp) && 199 success = page.GetInteger(physical_web::kScanTimestampKey, &scan_timestamp) &&
183 success; 200 success;
184 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) && 201 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) &&
185 success; 202 success;
186 success = page.GetString(physical_web::kTitleKey, &title) && success; 203 success = page.GetString(physical_web::kTitleKey, &title) && success;
187 success = 204 success =
188 page.GetString(physical_web::kDescriptionKey, &description) && success; 205 page.GetString(physical_web::kDescriptionKey, &description) && success;
189 if (!success) { 206 if (!success) {
190 LOG(DFATAL) << "Expected field is missing."; 207 LOG(DFATAL) << "Expected field is missing.";
191 } 208 }
192 209
193 const GURL resolved_url(raw_resolved_url); 210 const GURL resolved_url(raw_resolved_url);
194 ContentSuggestion suggestion(provided_category_, resolved_url.spec(), 211 ContentSuggestion suggestion(provided_category_, GetPageId(page),
195 resolved_url); 212 resolved_url);
196 DCHECK(base::IsStringUTF8(title)); 213 DCHECK(base::IsStringUTF8(title));
197 suggestion.set_title(base::UTF8ToUTF16(title)); 214 suggestion.set_title(base::UTF8ToUTF16(title));
198 // TODO(vitaliii): Set the time properly once the proper value is provided 215 // TODO(vitaliii): Set the time properly once the proper value is provided
199 // (see crbug.com/667722). 216 // (see crbug.com/667722).
200 suggestion.set_publish_date( 217 suggestion.set_publish_date(
201 base::Time::FromTimeT(static_cast<time_t>(scan_timestamp))); 218 base::Time::FromTimeT(static_cast<time_t>(scan_timestamp)));
202 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host())); 219 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host()));
203 DCHECK(base::IsStringUTF8(description)); 220 DCHECK(base::IsStringUTF8(description));
204 suggestion.set_snippet_text(base::UTF8ToUTF16(description)); 221 suggestion.set_snippet_text(base::UTF8ToUTF16(description));
(...skipping 10 matching lines...) Expand all
215 FetchPhysicalWebPages(); 232 FetchPhysicalWebPages();
216 } 233 }
217 234
218 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged( 235 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged(
219 const std::string& url, 236 const std::string& url,
220 double distance_estimate) { 237 double distance_estimate) {
221 FetchPhysicalWebPages(); 238 FetchPhysicalWebPages();
222 } 239 }
223 240
224 } // namespace ntp_snippets 241 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698