| Index: components/ntp_snippets/ntp_snippet.cc
|
| diff --git a/components/ntp_snippets/ntp_snippet.cc b/components/ntp_snippets/ntp_snippet.cc
|
| index 037fe51b2c11abc029ec88884aa1c92b4d133224..d7ca20c3392fd76c088a5de45aff7ebf92527627 100644
|
| --- a/components/ntp_snippets/ntp_snippet.cc
|
| +++ b/components/ntp_snippets/ntp_snippet.cc
|
| @@ -7,6 +7,7 @@
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/values.h"
|
| +#include "components/ntp_snippets/proto/ntp_snippets.pb.h"
|
|
|
| namespace {
|
|
|
| @@ -30,7 +31,7 @@ const char kAmpUrl[] = "ampUrl";
|
| namespace ntp_snippets {
|
|
|
| NTPSnippet::NTPSnippet(const std::string& id)
|
| - : id_(id), score_(0), best_source_index_(0) {}
|
| + : id_(id), score_(0), is_discarded_(false), best_source_index_(0) {}
|
|
|
| NTPSnippet::~NTPSnippet() {}
|
|
|
| @@ -41,9 +42,9 @@ std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromDictionary(
|
| if (!dict.GetDictionary(kContentInfo, &content))
|
| return nullptr;
|
|
|
| - // Need at least the url.
|
| + // Need at least the id.
|
| std::string id;
|
| - if (!content->GetString(kId, &id))
|
| + if (!content->GetString(kId, &id) || id.empty())
|
| return nullptr;
|
|
|
| std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(id));
|
| @@ -112,33 +113,14 @@ std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromDictionary(
|
| amp_url.is_valid() ? amp_url : GURL());
|
| snippet->add_source(source);
|
| }
|
| - // The previous url we have saved can be one of several sources for the
|
| - // article. For example, the same article can be hosted by nytimes.com,
|
| - // cnn.com, etc. We need to parse the list of sources for this article and
|
| - // find the best match. In order of preference:
|
| - // 1) A source that has url, publisher name, AMP url
|
| - // 2) A source that has url, publisher name
|
| - // 3) A source that has url and AMP url, or url only (since we won't show
|
| - // the snippet to users if the article does not have a publisher name, it
|
| - // doesn't matter whether the snippet has the AMP url or not)
|
| - size_t best_source_index = 0;
|
| - for (size_t i = 0; i < snippet->sources_.size(); ++i) {
|
| - const SnippetSource& source = snippet->sources_[i];
|
| - if (!source.publisher_name.empty()) {
|
| - best_source_index = i;
|
| - if (!source.amp_url.is_empty()) {
|
| - // This is the best possible source, stop looking.
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - snippet->set_source_index(best_source_index);
|
|
|
| if (snippet->sources_.empty()) {
|
| DLOG(WARNING) << "No sources found for article " << id;
|
| return nullptr;
|
| }
|
|
|
| + snippet->FindBestSource();
|
| +
|
| double score;
|
| if (dict.GetDouble(kScore, &score))
|
| snippet->set_score(score);
|
| @@ -147,6 +129,53 @@ std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromDictionary(
|
| }
|
|
|
| // static
|
| +std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromProto(
|
| + const SnippetProto& proto) {
|
| + // Need at least the id.
|
| + if (!proto.has_id() || proto.id().empty())
|
| + return nullptr;
|
| +
|
| + std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(proto.id()));
|
| +
|
| + snippet->set_title(proto.title());
|
| + snippet->set_snippet(proto.snippet());
|
| + snippet->set_salient_image_url(GURL(proto.salient_image_url()));
|
| + snippet->set_publish_date(
|
| + base::Time::FromInternalValue(proto.publish_date()));
|
| + snippet->set_expiry_date(base::Time::FromInternalValue(proto.expiry_date()));
|
| + snippet->set_score(proto.score());
|
| + snippet->set_discarded(proto.discarded());
|
| +
|
| + for (int i = 0; i < proto.sources_size(); ++i) {
|
| + const SnippetSourceProto& source_proto = proto.sources(i);
|
| + GURL url(source_proto.url());
|
| + if (!url.is_valid()) {
|
| + // We must at least have a valid source URL.
|
| + DLOG(WARNING) << "Invalid article url " << source_proto.url();
|
| + continue;
|
| + }
|
| + std::string publisher_name = source_proto.publisher_name();
|
| + GURL amp_url;
|
| + if (source_proto.has_amp_url()) {
|
| + amp_url = GURL(source_proto.amp_url());
|
| + DLOG_IF(WARNING, !amp_url.is_valid()) << "Invalid AMP URL "
|
| + << source_proto.amp_url();
|
| + }
|
| +
|
| + snippet->add_source(SnippetSource(url, publisher_name, amp_url));
|
| + }
|
| +
|
| + if (snippet->sources_.empty()) {
|
| + DLOG(WARNING) << "No sources found for article " << snippet->id();
|
| + return nullptr;
|
| + }
|
| +
|
| + snippet->FindBestSource();
|
| +
|
| + return snippet;
|
| +}
|
| +
|
| +// static
|
| bool NTPSnippet::AddFromListValue(const base::ListValue& list,
|
| PtrVector* snippets) {
|
| for (const auto& value : list) {
|
| @@ -163,44 +192,32 @@ bool NTPSnippet::AddFromListValue(const base::ListValue& list,
|
| return true;
|
| }
|
|
|
| -std::unique_ptr<base::DictionaryValue> NTPSnippet::ToDictionary() const {
|
| - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
|
| +SnippetProto NTPSnippet::ToProto() const {
|
| + SnippetProto result;
|
|
|
| - dict->SetString(kId, id_);
|
| + result.set_id(id_);
|
| if (!title_.empty())
|
| - dict->SetString(kTitle, title_);
|
| - if (salient_image_url_.is_valid())
|
| - dict->SetString(kSalientImageUrl, salient_image_url_.spec());
|
| + result.set_title(title_);
|
| if (!snippet_.empty())
|
| - dict->SetString(kSnippet, snippet_);
|
| + result.set_snippet(snippet_);
|
| + if (salient_image_url_.is_valid())
|
| + result.set_salient_image_url(salient_image_url_.spec());
|
| if (!publish_date_.is_null())
|
| - dict->SetString(kPublishDate, TimeToJsonString(publish_date_));
|
| + result.set_publish_date(publish_date_.ToInternalValue());
|
| if (!expiry_date_.is_null())
|
| - dict->SetString(kExpiryDate, TimeToJsonString(expiry_date_));
|
| + result.set_expiry_date(expiry_date_.ToInternalValue());
|
| + result.set_score(score_);
|
| + result.set_discarded(is_discarded_);
|
|
|
| - std::unique_ptr<base::ListValue> corpus_infos_list(new base::ListValue);
|
| for (const SnippetSource& source : sources_) {
|
| - std::unique_ptr<base::DictionaryValue> corpus_info_dict(
|
| - new base::DictionaryValue);
|
| -
|
| - corpus_info_dict->SetString(kCorpusId, source.url.spec());
|
| - if (!source.amp_url.is_empty())
|
| - corpus_info_dict->SetString(kAmpUrl, source.amp_url.spec());
|
| + SnippetSourceProto* source_proto = result.add_sources();
|
| + source_proto->set_url(source.url.spec());
|
| if (!source.publisher_name.empty())
|
| - corpus_info_dict->SetString(
|
| - base::StringPrintf("%s.%s", kPublisherData, kSiteTitle),
|
| - source.publisher_name);
|
| -
|
| - corpus_infos_list->Append(std::move(corpus_info_dict));
|
| + source_proto->set_publisher_name(source.publisher_name);
|
| + if (source.amp_url.is_valid())
|
| + source_proto->set_amp_url(source.amp_url.spec());
|
| }
|
|
|
| - dict->Set(kSourceCorpusInfo, std::move(corpus_infos_list));
|
| -
|
| - std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue);
|
| - result->Set(kContentInfo, std::move(dict));
|
| -
|
| - result->SetDouble(kScore, score_);
|
| -
|
| return result;
|
| }
|
|
|
| @@ -220,4 +237,26 @@ std::string NTPSnippet::TimeToJsonString(const base::Time& time) {
|
| return base::Int64ToString((time - base::Time::UnixEpoch()).InSeconds());
|
| }
|
|
|
| +void NTPSnippet::FindBestSource() {
|
| + // The same article can be hosted by multiple sources, e.g. nytimes.com,
|
| + // cnn.com, etc. We need to parse the list of sources for this article and
|
| + // find the best match. In order of preference:
|
| + // 1) A source that has URL, publisher name, AMP URL
|
| + // 2) A source that has URL, publisher name
|
| + // 3) A source that has URL and AMP URL, or URL only (since we won't show
|
| + // the snippet to users if the article does not have a publisher name, it
|
| + // doesn't matter whether the snippet has the AMP URL or not)
|
| + best_source_index_ = 0;
|
| + for (size_t i = 0; i < sources_.size(); ++i) {
|
| + const SnippetSource& source = sources_[i];
|
| + if (!source.publisher_name.empty()) {
|
| + best_source_index_ = i;
|
| + if (!source.amp_url.is_empty()) {
|
| + // This is the best possible source, stop looking.
|
| + break;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace ntp_snippets
|
|
|