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

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@ nit. 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) << physical_web::kResolvedUrlKey << " field is missing.";
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 19 matching lines...) Expand all
128 void PhysicalWebPageSuggestionsProvider::NotifyStatusChanged( 134 void PhysicalWebPageSuggestionsProvider::NotifyStatusChanged(
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 DCHECK_EQ(CategoryStatus::AVAILABLE, category_status_);
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.";
163 continue;
147 } 164 }
148 page_dictionaries.push_back(page_dictionary); 165 if (!excluded_ids.count(GetPageId(*page_dictionary))) {
166 page_dictionaries.push_back(page_dictionary);
167 }
149 } 168 }
150 169
151 std::sort(page_dictionaries.begin(), page_dictionaries.end(), 170 std::sort(page_dictionaries.begin(), page_dictionaries.end(),
152 [](const DictionaryValue* left, const DictionaryValue* right) { 171 [](const DictionaryValue* left, const DictionaryValue* right) {
153 double left_distance, right_distance; 172 double left_distance, right_distance;
154 bool success = left->GetDouble(physical_web::kDistanceEstimateKey, 173 bool success = left->GetDouble(physical_web::kDistanceEstimateKey,
155 &left_distance); 174 &left_distance);
156 success = right->GetDouble(physical_web::kDistanceEstimateKey, 175 success = right->GetDouble(physical_web::kDistanceEstimateKey,
157 &right_distance) && 176 &right_distance) &&
158 success; 177 success;
159 if (!success) { 178 if (!success) {
160 LOG(DFATAL) << "Distance field is missing."; 179 LOG(DFATAL) << "Distance field is missing.";
161 } 180 }
162 return left_distance < right_distance; 181 return left_distance < right_distance;
163 }); 182 });
164 183
165 std::vector<ContentSuggestion> suggestions; 184 std::vector<ContentSuggestion> suggestions;
166 for (const DictionaryValue* page_dictionary : page_dictionaries) { 185 for (const DictionaryValue* page_dictionary : page_dictionaries) {
167 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary)); 186 if (static_cast<int>(suggestions.size()) == max_quantity) {
168 if (suggestions.size() == kMaxSuggestionsCount) {
169 break; 187 break;
170 } 188 }
189 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary));
171 } 190 }
172 191
173 observer()->OnNewSuggestions(this, provided_category_, 192 return suggestions;
174 std::move(suggestions));
175 } 193 }
176 194
177 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage( 195 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage(
178 const DictionaryValue& page) const { 196 const DictionaryValue& page) const {
179 std::string scanned_url, raw_resolved_url, title, description; 197 std::string scanned_url, raw_resolved_url, title, description;
180 int scan_timestamp; 198 int scan_timestamp;
181 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url); 199 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url);
182 success = page.GetInteger(physical_web::kScanTimestampKey, &scan_timestamp) && 200 success = page.GetInteger(physical_web::kScanTimestampKey, &scan_timestamp) &&
183 success; 201 success;
184 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) && 202 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) &&
185 success; 203 success;
186 success = page.GetString(physical_web::kTitleKey, &title) && success; 204 success = page.GetString(physical_web::kTitleKey, &title) && success;
187 success = 205 success =
188 page.GetString(physical_web::kDescriptionKey, &description) && success; 206 page.GetString(physical_web::kDescriptionKey, &description) && success;
189 if (!success) { 207 if (!success) {
190 LOG(DFATAL) << "Expected field is missing."; 208 LOG(DFATAL) << "Expected field is missing.";
191 } 209 }
192 210
193 const GURL resolved_url(raw_resolved_url); 211 const GURL resolved_url(raw_resolved_url);
194 ContentSuggestion suggestion(provided_category_, resolved_url.spec(), 212 ContentSuggestion suggestion(provided_category_, GetPageId(page),
195 resolved_url); 213 resolved_url);
196 DCHECK(base::IsStringUTF8(title)); 214 DCHECK(base::IsStringUTF8(title));
197 suggestion.set_title(base::UTF8ToUTF16(title)); 215 suggestion.set_title(base::UTF8ToUTF16(title));
198 // TODO(vitaliii): Set the time properly once the proper value is provided 216 // TODO(vitaliii): Set the time properly once the proper value is provided
199 // (see crbug.com/667722). 217 // (see crbug.com/667722).
200 suggestion.set_publish_date( 218 suggestion.set_publish_date(
201 base::Time::FromTimeT(static_cast<time_t>(scan_timestamp))); 219 base::Time::FromTimeT(static_cast<time_t>(scan_timestamp)));
202 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host())); 220 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host()));
203 DCHECK(base::IsStringUTF8(description)); 221 DCHECK(base::IsStringUTF8(description));
204 suggestion.set_snippet_text(base::UTF8ToUTF16(description)); 222 suggestion.set_snippet_text(base::UTF8ToUTF16(description));
(...skipping 10 matching lines...) Expand all
215 FetchPhysicalWebPages(); 233 FetchPhysicalWebPages();
216 } 234 }
217 235
218 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged( 236 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged(
219 const std::string& url, 237 const std::string& url,
220 double distance_estimate) { 238 double distance_estimate) {
221 FetchPhysicalWebPages(); 239 FetchPhysicalWebPages();
222 } 240 }
223 241
224 } // namespace ntp_snippets 242 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698