| OLD | NEW |
| 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/ntp_snippet.h" | 5 #include "components/ntp_snippets/remote/ntp_snippet.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 | 11 #include "components/ntp_snippets/category.h" |
| 12 #include "components/ntp_snippets/remote/proto/ntp_snippets.pb.h" | 12 #include "components/ntp_snippets/remote/proto/ntp_snippets.pb.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 // dict.Get() specialization for base::Time values | 16 // dict.Get() specialization for base::Time values |
| 17 bool GetTimeValue(const base::DictionaryValue& dict, | 17 bool GetTimeValue(const base::DictionaryValue& dict, |
| 18 const std::string& key, | 18 const std::string& key, |
| 19 base::Time* time) { | 19 base::Time* time) { |
| 20 std::string time_value; | 20 std::string time_value; |
| 21 return dict.GetString(key, &time_value) && | 21 return dict.GetString(key, &time_value) && |
| 22 base::Time::FromString(time_value.c_str(), time); | 22 base::Time::FromString(time_value.c_str(), time); |
| 23 } | 23 } |
| 24 | 24 |
| 25 // dict.Get() specialization for GURL values | 25 // dict.Get() specialization for GURL values |
| 26 bool GetURLValue(const base::DictionaryValue& dict, | 26 bool GetURLValue(const base::DictionaryValue& dict, |
| 27 const std::string& key, | 27 const std::string& key, |
| 28 GURL* url) { | 28 GURL* url) { |
| 29 std::string spec; | 29 std::string spec; |
| 30 if (!dict.GetString(key, &spec)) { | 30 if (!dict.GetString(key, &spec)) { |
| 31 return false; | 31 return false; |
| 32 } | 32 } |
| 33 *url = GURL(spec); | 33 *url = GURL(spec); |
| 34 return url->is_valid(); | 34 return url->is_valid(); |
| 35 } | 35 } |
| 36 | 36 |
| 37 } // namespace | 37 } // namespace |
| 38 | 38 |
| 39 namespace ntp_snippets { | 39 namespace ntp_snippets { |
| 40 | 40 |
| 41 NTPSnippet::NTPSnippet(const std::string& id) | 41 const int kArticlesRemoteId = 1; |
| 42 : id_(id), score_(0), is_dismissed_(false), best_source_index_(0) {} | 42 static_assert( |
| 43 static_cast<int>(KnownCategories::ARTICLES) - |
| 44 static_cast<int>(KnownCategories::REMOTE_CATEGORIES_OFFSET) == |
| 45 kArticlesRemoteId, |
| 46 "kArticlesRemoteId has a wrong value?!"); |
| 47 |
| 48 NTPSnippet::NTPSnippet(const std::string& id, int remote_category_id) |
| 49 : id_(id), |
| 50 score_(0), |
| 51 is_dismissed_(false), |
| 52 remote_category_id_(remote_category_id), |
| 53 best_source_index_(0) {} |
| 43 | 54 |
| 44 NTPSnippet::~NTPSnippet() = default; | 55 NTPSnippet::~NTPSnippet() = default; |
| 45 | 56 |
| 46 // static | 57 // static |
| 47 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromChromeReaderDictionary( | 58 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromChromeReaderDictionary( |
| 48 const base::DictionaryValue& dict) { | 59 const base::DictionaryValue& dict) { |
| 49 const base::DictionaryValue* content = nullptr; | 60 const base::DictionaryValue* content = nullptr; |
| 50 if (!dict.GetDictionary("contentInfo", &content)) | 61 if (!dict.GetDictionary("contentInfo", &content)) |
| 51 return nullptr; | 62 return nullptr; |
| 52 | 63 |
| 53 // Need at least the id. | 64 // Need at least the id. |
| 54 std::string id; | 65 std::string id; |
| 55 if (!content->GetString("url", &id) || id.empty()) | 66 if (!content->GetString("url", &id) || id.empty()) |
| 56 return nullptr; | 67 return nullptr; |
| 57 | 68 |
| 58 std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(id)); | 69 std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(id, kArticlesRemoteId)); |
| 59 | 70 |
| 60 std::string title; | 71 std::string title; |
| 61 if (content->GetString("title", &title)) | 72 if (content->GetString("title", &title)) |
| 62 snippet->set_title(title); | 73 snippet->set_title(title); |
| 63 std::string salient_image_url; | 74 std::string salient_image_url; |
| 64 if (content->GetString("thumbnailUrl", &salient_image_url)) | 75 if (content->GetString("thumbnailUrl", &salient_image_url)) |
| 65 snippet->set_salient_image_url(GURL(salient_image_url)); | 76 snippet->set_salient_image_url(GURL(salient_image_url)); |
| 66 std::string snippet_str; | 77 std::string snippet_str; |
| 67 if (content->GetString("snippet", &snippet_str)) | 78 if (content->GetString("snippet", &snippet_str)) |
| 68 snippet->set_snippet(snippet_str); | 79 snippet->set_snippet(snippet_str); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 142 |
| 132 double score; | 143 double score; |
| 133 if (dict.GetDouble("score", &score)) | 144 if (dict.GetDouble("score", &score)) |
| 134 snippet->set_score(score); | 145 snippet->set_score(score); |
| 135 | 146 |
| 136 return snippet; | 147 return snippet; |
| 137 } | 148 } |
| 138 | 149 |
| 139 // static | 150 // static |
| 140 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromContentSuggestionsDictionary( | 151 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromContentSuggestionsDictionary( |
| 141 const base::DictionaryValue& dict) { | 152 const base::DictionaryValue& dict, |
| 153 int remote_category_id) { |
| 142 const base::ListValue* ids; | 154 const base::ListValue* ids; |
| 143 std::string id; | 155 std::string id; |
| 144 if (!(dict.GetList("ids", &ids) && | 156 if (!(dict.GetList("ids", &ids) && |
| 145 ids->GetString(0, &id))) { // TODO(sfiera): multiple IDs | 157 ids->GetString(0, &id))) { // TODO(sfiera): multiple IDs |
| 146 return nullptr; | 158 return nullptr; |
| 147 } | 159 } |
| 148 | 160 |
| 149 auto snippet = base::MakeUnique<NTPSnippet>(id); | 161 auto snippet = base::MakeUnique<NTPSnippet>(id, remote_category_id); |
| 150 snippet->sources_.emplace_back(GURL(), std::string(), GURL()); | 162 snippet->sources_.emplace_back(GURL(), std::string(), GURL()); |
| 151 auto* source = &snippet->sources_.back(); | 163 auto* source = &snippet->sources_.back(); |
| 152 snippet->best_source_index_ = 0; | 164 snippet->best_source_index_ = 0; |
| 153 | 165 |
| 154 if (!(dict.GetString("title", &snippet->title_) && | 166 if (!(dict.GetString("title", &snippet->title_) && |
| 155 dict.GetString("snippet", &snippet->snippet_) && | 167 dict.GetString("snippet", &snippet->snippet_) && |
| 156 GetTimeValue(dict, "creationTime", &snippet->publish_date_) && | 168 GetTimeValue(dict, "creationTime", &snippet->publish_date_) && |
| 157 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) && | 169 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) && |
| 158 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) && | 170 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) && |
| 159 dict.GetString("attribution", &source->publisher_name) && | 171 dict.GetString("attribution", &source->publisher_name) && |
| 160 GetURLValue(dict, "fullPageUrl", &source->url))) { | 172 GetURLValue(dict, "fullPageUrl", &source->url))) { |
| 161 return nullptr; | 173 return nullptr; |
| 162 } | 174 } |
| 163 GetURLValue(dict, "ampUrl", &source->amp_url); // May fail; OK. | 175 GetURLValue(dict, "ampUrl", &source->amp_url); // May fail; OK. |
| 164 // TODO(sfiera): also favicon URL. | 176 // TODO(sfiera): also favicon URL. |
| 165 | 177 |
| 166 snippet->score_ = 0.0; // TODO(sfiera): put score in protocol. | 178 snippet->score_ = 0.0; // TODO(sfiera): put score in protocol. |
| 167 | 179 |
| 168 return snippet; | 180 return snippet; |
| 169 } | 181 } |
| 170 | 182 |
| 171 // static | 183 // static |
| 172 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromProto( | 184 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromProto( |
| 173 const SnippetProto& proto) { | 185 const SnippetProto& proto) { |
| 174 // Need at least the id. | 186 // Need at least the id. |
| 175 if (!proto.has_id() || proto.id().empty()) | 187 if (!proto.has_id() || proto.id().empty()) |
| 176 return nullptr; | 188 return nullptr; |
| 177 | 189 |
| 178 std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(proto.id())); | 190 int remote_category_id = proto.has_remote_category_id() |
| 191 ? proto.remote_category_id() |
| 192 : kArticlesRemoteId; |
| 193 |
| 194 std::unique_ptr<NTPSnippet> snippet( |
| 195 new NTPSnippet(proto.id(), remote_category_id)); |
| 179 | 196 |
| 180 snippet->set_title(proto.title()); | 197 snippet->set_title(proto.title()); |
| 181 snippet->set_snippet(proto.snippet()); | 198 snippet->set_snippet(proto.snippet()); |
| 182 snippet->set_salient_image_url(GURL(proto.salient_image_url())); | 199 snippet->set_salient_image_url(GURL(proto.salient_image_url())); |
| 183 snippet->set_publish_date( | 200 snippet->set_publish_date( |
| 184 base::Time::FromInternalValue(proto.publish_date())); | 201 base::Time::FromInternalValue(proto.publish_date())); |
| 185 snippet->set_expiry_date(base::Time::FromInternalValue(proto.expiry_date())); | 202 snippet->set_expiry_date(base::Time::FromInternalValue(proto.expiry_date())); |
| 186 snippet->set_score(proto.score()); | 203 snippet->set_score(proto.score()); |
| 187 snippet->set_dismissed(proto.dismissed()); | 204 snippet->set_dismissed(proto.dismissed()); |
| 188 | 205 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 if (!snippet_.empty()) | 241 if (!snippet_.empty()) |
| 225 result.set_snippet(snippet_); | 242 result.set_snippet(snippet_); |
| 226 if (salient_image_url_.is_valid()) | 243 if (salient_image_url_.is_valid()) |
| 227 result.set_salient_image_url(salient_image_url_.spec()); | 244 result.set_salient_image_url(salient_image_url_.spec()); |
| 228 if (!publish_date_.is_null()) | 245 if (!publish_date_.is_null()) |
| 229 result.set_publish_date(publish_date_.ToInternalValue()); | 246 result.set_publish_date(publish_date_.ToInternalValue()); |
| 230 if (!expiry_date_.is_null()) | 247 if (!expiry_date_.is_null()) |
| 231 result.set_expiry_date(expiry_date_.ToInternalValue()); | 248 result.set_expiry_date(expiry_date_.ToInternalValue()); |
| 232 result.set_score(score_); | 249 result.set_score(score_); |
| 233 result.set_dismissed(is_dismissed_); | 250 result.set_dismissed(is_dismissed_); |
| 251 result.set_remote_category_id(remote_category_id_); |
| 234 | 252 |
| 235 for (const SnippetSource& source : sources_) { | 253 for (const SnippetSource& source : sources_) { |
| 236 SnippetSourceProto* source_proto = result.add_sources(); | 254 SnippetSourceProto* source_proto = result.add_sources(); |
| 237 source_proto->set_url(source.url.spec()); | 255 source_proto->set_url(source.url.spec()); |
| 238 if (!source.publisher_name.empty()) | 256 if (!source.publisher_name.empty()) |
| 239 source_proto->set_publisher_name(source.publisher_name); | 257 source_proto->set_publisher_name(source.publisher_name); |
| 240 if (source.amp_url.is_valid()) | 258 if (source.amp_url.is_valid()) |
| 241 source_proto->set_amp_url(source.amp_url.spec()); | 259 source_proto->set_amp_url(source.amp_url.spec()); |
| 242 } | 260 } |
| 243 | 261 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 best_source_index_ = i; | 294 best_source_index_ = i; |
| 277 if (!source.amp_url.is_empty()) { | 295 if (!source.amp_url.is_empty()) { |
| 278 // This is the best possible source, stop looking. | 296 // This is the best possible source, stop looking. |
| 279 break; | 297 break; |
| 280 } | 298 } |
| 281 } | 299 } |
| 282 } | 300 } |
| 283 } | 301 } |
| 284 | 302 |
| 285 } // namespace ntp_snippets | 303 } // namespace ntp_snippets |
| OLD | NEW |