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

Side by Side Diff: components/ntp_snippets/remote/remote_suggestion.cc

Issue 2686063003: [remote suggestions] Attach the fetch time to RemoteSnippets, ContentSnippets and SnippetArticle (Closed)
Patch Set: Update comments 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/remote/remote_suggestion.h" 5 #include "components/ntp_snippets/remote/remote_suggestion.h"
6 6
7 #include "base/feature_list.h" 7 #include "base/feature_list.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
Marc Treib 2017/02/10 16:16:56 nit: not required, it's already included in the he
markusheintz_ 2017/02/13 09:59:55 Done.
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "components/ntp_snippets/category.h" 14 #include "components/ntp_snippets/category.h"
14 #include "components/ntp_snippets/features.h" 15 #include "components/ntp_snippets/features.h"
15 #include "components/ntp_snippets/remote/proto/ntp_snippets.pb.h" 16 #include "components/ntp_snippets/remote/proto/ntp_snippets.pb.h"
16 17
17 namespace { 18 namespace {
18 19
19 struct SnippetSource { 20 struct SnippetSource {
20 SnippetSource(const GURL& url, 21 SnippetSource(const GURL& url,
21 const std::string& publisher_name, 22 const std::string& publisher_name,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 score_(0), 90 score_(0),
90 is_dismissed_(false), 91 is_dismissed_(false),
91 remote_category_id_(remote_category_id), 92 remote_category_id_(remote_category_id),
92 should_notify_(false) {} 93 should_notify_(false) {}
93 94
94 RemoteSuggestion::~RemoteSuggestion() = default; 95 RemoteSuggestion::~RemoteSuggestion() = default;
95 96
96 // static 97 // static
97 std::unique_ptr<RemoteSuggestion> 98 std::unique_ptr<RemoteSuggestion>
98 RemoteSuggestion::CreateFromChromeReaderDictionary( 99 RemoteSuggestion::CreateFromChromeReaderDictionary(
99 const base::DictionaryValue& dict) { 100 const base::DictionaryValue& dict,
101 const base::Time& fetch_time) {
100 const base::DictionaryValue* content = nullptr; 102 const base::DictionaryValue* content = nullptr;
101 if (!dict.GetDictionary("contentInfo", &content)) { 103 if (!dict.GetDictionary("contentInfo", &content)) {
102 return nullptr; 104 return nullptr;
103 } 105 }
104 106
105 // Need at least a primary id. 107 // Need at least a primary id.
106 std::string primary_id; 108 std::string primary_id;
107 if (!content->GetString("url", &primary_id) || primary_id.empty()) { 109 if (!content->GetString("url", &primary_id) || primary_id.empty()) {
108 return nullptr; 110 return nullptr;
109 } 111 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // this for the primary ID). 162 // this for the primary ID).
161 ids.push_back(corpus_id_str); 163 ids.push_back(corpus_id_str);
162 } 164 }
163 if (sources.empty()) { 165 if (sources.empty()) {
164 DLOG(WARNING) << "No sources found for article " << primary_id; 166 DLOG(WARNING) << "No sources found for article " << primary_id;
165 return nullptr; 167 return nullptr;
166 } 168 }
167 169
168 std::unique_ptr<RemoteSuggestion> snippet( 170 std::unique_ptr<RemoteSuggestion> snippet(
169 new RemoteSuggestion(ids, kArticlesRemoteId)); 171 new RemoteSuggestion(ids, kArticlesRemoteId));
172 snippet->fetch_time_ = fetch_time;
170 173
171 std::string title; 174 std::string title;
172 if (content->GetString("title", &title)) { 175 if (content->GetString("title", &title)) {
173 snippet->title_ = title; 176 snippet->title_ = title;
174 } 177 }
175 std::string salient_image_url; 178 std::string salient_image_url;
176 if (content->GetString("thumbnailUrl", &salient_image_url)) { 179 if (content->GetString("thumbnailUrl", &salient_image_url)) {
177 snippet->salient_image_url_ = GURL(salient_image_url); 180 snippet->salient_image_url_ = GURL(salient_image_url);
178 } 181 }
179 std::string snippet_str; 182 std::string snippet_str;
(...skipping 30 matching lines...) Expand all
210 snippet->score_ = score; 213 snippet->score_ = score;
211 } 214 }
212 215
213 return snippet; 216 return snippet;
214 } 217 }
215 218
216 // static 219 // static
217 std::unique_ptr<RemoteSuggestion> 220 std::unique_ptr<RemoteSuggestion>
218 RemoteSuggestion::CreateFromContentSuggestionsDictionary( 221 RemoteSuggestion::CreateFromContentSuggestionsDictionary(
219 const base::DictionaryValue& dict, 222 const base::DictionaryValue& dict,
220 int remote_category_id) { 223 int remote_category_id,
224 const base::Time& fetch_time) {
221 const base::ListValue* ids; 225 const base::ListValue* ids;
222 if (!dict.GetList("ids", &ids)) { 226 if (!dict.GetList("ids", &ids)) {
223 return nullptr; 227 return nullptr;
224 } 228 }
225 std::vector<std::string> parsed_ids; 229 std::vector<std::string> parsed_ids;
226 for (const auto& value : *ids) { 230 for (const auto& value : *ids) {
227 std::string id; 231 std::string id;
228 if (!value->GetAsString(&id)) { 232 if (!value->GetAsString(&id)) {
229 return nullptr; 233 return nullptr;
230 } 234 }
231 parsed_ids.push_back(id); 235 parsed_ids.push_back(id);
232 } 236 }
233 237
234 if (parsed_ids.empty()) { 238 if (parsed_ids.empty()) {
235 return nullptr; 239 return nullptr;
236 } 240 }
237 auto snippet = MakeUnique(parsed_ids, remote_category_id); 241 auto snippet = MakeUnique(parsed_ids, remote_category_id);
242 snippet->fetch_time_ = fetch_time;
238 243
239 if (!(dict.GetString("title", &snippet->title_) && 244 if (!(dict.GetString("title", &snippet->title_) &&
240 dict.GetString("snippet", &snippet->snippet_) && 245 dict.GetString("snippet", &snippet->snippet_) &&
241 GetTimeValue(dict, "creationTime", &snippet->publish_date_) && 246 GetTimeValue(dict, "creationTime", &snippet->publish_date_) &&
242 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) && 247 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) &&
243 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) && 248 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) &&
244 dict.GetString("attribution", &snippet->publisher_name_) && 249 dict.GetString("attribution", &snippet->publisher_name_) &&
245 GetURLValue(dict, "fullPageUrl", &snippet->url_))) { 250 GetURLValue(dict, "fullPageUrl", &snippet->url_))) {
246 return nullptr; 251 return nullptr;
247 } 252 }
(...skipping 26 matching lines...) Expand all
274 // Need at least the id. 279 // Need at least the id.
275 if (proto.ids_size() == 0 || proto.ids(0).empty()) { 280 if (proto.ids_size() == 0 || proto.ids(0).empty()) {
276 return nullptr; 281 return nullptr;
277 } 282 }
278 283
279 int remote_category_id = proto.has_remote_category_id() 284 int remote_category_id = proto.has_remote_category_id()
280 ? proto.remote_category_id() 285 ? proto.remote_category_id()
281 : kArticlesRemoteId; 286 : kArticlesRemoteId;
282 287
283 std::vector<std::string> ids(proto.ids().begin(), proto.ids().end()); 288 std::vector<std::string> ids(proto.ids().begin(), proto.ids().end());
289
284 auto snippet = MakeUnique(ids, remote_category_id); 290 auto snippet = MakeUnique(ids, remote_category_id);
285 291
286 snippet->title_ = proto.title(); 292 snippet->title_ = proto.title();
287 snippet->snippet_ = proto.snippet(); 293 snippet->snippet_ = proto.snippet();
288 snippet->salient_image_url_ = GURL(proto.salient_image_url()); 294 snippet->salient_image_url_ = GURL(proto.salient_image_url());
289 snippet->publish_date_ = base::Time::FromInternalValue(proto.publish_date()); 295 snippet->publish_date_ = base::Time::FromInternalValue(proto.publish_date());
290 snippet->expiry_date_ = base::Time::FromInternalValue(proto.expiry_date()); 296 snippet->expiry_date_ = base::Time::FromInternalValue(proto.expiry_date());
291 snippet->score_ = proto.score(); 297 snippet->score_ = proto.score();
292 snippet->is_dismissed_ = proto.dismissed(); 298 snippet->is_dismissed_ = proto.dismissed();
293 299
(...skipping 18 matching lines...) Expand all
312 318
313 if (sources.empty()) { 319 if (sources.empty()) {
314 DLOG(WARNING) << "No sources found for article " << snippet->id(); 320 DLOG(WARNING) << "No sources found for article " << snippet->id();
315 return nullptr; 321 return nullptr;
316 } 322 }
317 const SnippetSource& source = FindBestSource(sources); 323 const SnippetSource& source = FindBestSource(sources);
318 snippet->url_ = source.url; 324 snippet->url_ = source.url;
319 snippet->publisher_name_ = source.publisher_name; 325 snippet->publisher_name_ = source.publisher_name;
320 snippet->amp_url_ = source.amp_url; 326 snippet->amp_url_ = source.amp_url;
321 327
328 if (proto.has_fetch_time()) {
329 snippet->fetch_time_ = base::Time::FromInternalValue(proto.fetch_time());
330 }
331
322 return snippet; 332 return snippet;
323 } 333 }
324 334
325 // static 335 // static
326 std::unique_ptr<RemoteSuggestion> RemoteSuggestion::CreateForTesting( 336 std::unique_ptr<RemoteSuggestion> RemoteSuggestion::CreateForTesting(
327 const std::string& id, 337 const std::string& id,
328 int remote_category_id, 338 int remote_category_id,
329 const GURL& url, 339 const GURL& url,
330 const std::string& publisher_name, 340 const std::string& publisher_name,
331 const GURL& amp_url) { 341 const GURL& amp_url) {
342 // TODO(markusheintz):
jkrcal 2017/02/10 16:14:42 can you please fill in the todo?
Marc Treib 2017/02/10 16:16:56 ?
markusheintz_ 2017/02/13 09:59:55 sorry forgot to remove :-( Removed now.
332 auto snippet = 343 auto snippet =
333 MakeUnique(std::vector<std::string>(1, id), remote_category_id); 344 MakeUnique(std::vector<std::string>(1, id), remote_category_id);
334 snippet->url_ = url; 345 snippet->url_ = url;
335 snippet->publisher_name_ = publisher_name; 346 snippet->publisher_name_ = publisher_name;
336 snippet->amp_url_ = amp_url; 347 snippet->amp_url_ = amp_url;
337 348
338 return snippet; 349 return snippet;
339 } 350 }
340 351
341 SnippetProto RemoteSuggestion::ToProto() const { 352 SnippetProto RemoteSuggestion::ToProto() const {
(...skipping 22 matching lines...) Expand all
364 375
365 SnippetSourceProto* source_proto = result.add_sources(); 376 SnippetSourceProto* source_proto = result.add_sources();
366 source_proto->set_url(url_.spec()); 377 source_proto->set_url(url_.spec());
367 if (!publisher_name_.empty()) { 378 if (!publisher_name_.empty()) {
368 source_proto->set_publisher_name(publisher_name_); 379 source_proto->set_publisher_name(publisher_name_);
369 } 380 }
370 if (amp_url_.is_valid()) { 381 if (amp_url_.is_valid()) {
371 source_proto->set_amp_url(amp_url_.spec()); 382 source_proto->set_amp_url(amp_url_.spec());
372 } 383 }
373 384
385 if (!fetch_time_.is_null()) {
386 result.set_fetch_time(fetch_time_.ToInternalValue());
387 }
374 return result; 388 return result;
375 } 389 }
376 390
377 ContentSuggestion RemoteSuggestion::ToContentSuggestion( 391 ContentSuggestion RemoteSuggestion::ToContentSuggestion(
378 Category category) const { 392 Category category) const {
379 GURL url = url_; 393 GURL url = url_;
380 if (base::FeatureList::IsEnabled(kPreferAmpUrlsFeature) && 394 if (base::FeatureList::IsEnabled(kPreferAmpUrlsFeature) &&
381 !amp_url_.is_empty()) { 395 !amp_url_.is_empty()) {
382 url = amp_url_; 396 url = amp_url_;
383 } 397 }
384 ContentSuggestion suggestion(category, id(), url); 398 ContentSuggestion suggestion(category, id(), url);
385 suggestion.set_title(base::UTF8ToUTF16(title_)); 399 suggestion.set_title(base::UTF8ToUTF16(title_));
386 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet_)); 400 suggestion.set_snippet_text(base::UTF8ToUTF16(snippet_));
387 suggestion.set_publish_date(publish_date_); 401 suggestion.set_publish_date(publish_date_);
388 suggestion.set_publisher_name(base::UTF8ToUTF16(publisher_name_)); 402 suggestion.set_publisher_name(base::UTF8ToUTF16(publisher_name_));
389 suggestion.set_score(score_); 403 suggestion.set_score(score_);
390 if (should_notify_) { 404 if (should_notify_) {
391 NotificationExtra extra; 405 NotificationExtra extra;
392 extra.deadline = notification_deadline_; 406 extra.deadline = notification_deadline_;
393 suggestion.set_notification_extra( 407 suggestion.set_notification_extra(
394 base::MakeUnique<NotificationExtra>(extra)); 408 base::MakeUnique<NotificationExtra>(extra));
395 } 409 }
410 suggestion.set_fetch_time(fetch_time_);
396 return suggestion; 411 return suggestion;
397 } 412 }
398 413
399 // static 414 // static
400 base::Time RemoteSuggestion::TimeFromJsonString( 415 base::Time RemoteSuggestion::TimeFromJsonString(
401 const std::string& timestamp_str) { 416 const std::string& timestamp_str) {
402 int64_t timestamp; 417 int64_t timestamp;
403 if (!base::StringToInt64(timestamp_str, &timestamp)) { 418 if (!base::StringToInt64(timestamp_str, &timestamp)) {
404 // Even if there's an error in the conversion, some garbage data may still 419 // Even if there's an error in the conversion, some garbage data may still
405 // be written to the output var, so reset it. 420 // be written to the output var, so reset it.
406 DLOG(WARNING) << "Invalid json timestamp: " << timestamp_str; 421 DLOG(WARNING) << "Invalid json timestamp: " << timestamp_str;
407 timestamp = 0; 422 timestamp = 0;
408 } 423 }
409 return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(timestamp); 424 return base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(timestamp);
410 } 425 }
411 426
412 // static 427 // static
413 std::string RemoteSuggestion::TimeToJsonString(const base::Time& time) { 428 std::string RemoteSuggestion::TimeToJsonString(const base::Time& time) {
414 return base::Int64ToString((time - base::Time::UnixEpoch()).InSeconds()); 429 return base::Int64ToString((time - base::Time::UnixEpoch()).InSeconds());
415 } 430 }
416 431
417 // static 432 // static
418 std::unique_ptr<RemoteSuggestion> RemoteSuggestion::MakeUnique( 433 std::unique_ptr<RemoteSuggestion> RemoteSuggestion::MakeUnique(
419 const std::vector<std::string>& ids, 434 const std::vector<std::string>& ids,
420 int remote_category_id) { 435 int remote_category_id) {
421 return base::WrapUnique(new RemoteSuggestion(ids, remote_category_id)); 436 return base::WrapUnique(new RemoteSuggestion(ids, remote_category_id));
422 } 437 }
423 438
424 } // namespace ntp_snippets 439 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698