| 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" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 is_dismissed_(false), | 51 is_dismissed_(false), |
| 52 remote_category_id_(remote_category_id), | 52 remote_category_id_(remote_category_id), |
| 53 best_source_index_(0) {} | 53 best_source_index_(0) {} |
| 54 | 54 |
| 55 NTPSnippet::~NTPSnippet() = default; | 55 NTPSnippet::~NTPSnippet() = default; |
| 56 | 56 |
| 57 // static | 57 // static |
| 58 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromChromeReaderDictionary( | 58 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromChromeReaderDictionary( |
| 59 const base::DictionaryValue& dict) { | 59 const base::DictionaryValue& dict) { |
| 60 const base::DictionaryValue* content = nullptr; | 60 const base::DictionaryValue* content = nullptr; |
| 61 if (!dict.GetDictionary("contentInfo", &content)) | 61 if (!dict.GetDictionary("contentInfo", &content)) { |
| 62 return nullptr; | 62 return nullptr; |
| 63 } |
| 63 | 64 |
| 64 // Need at least the id. | 65 // Need at least the id. |
| 65 std::string id; | 66 std::string id; |
| 66 if (!content->GetString("url", &id) || id.empty()) | 67 if (!content->GetString("url", &id) || id.empty()) { |
| 67 return nullptr; | 68 return nullptr; |
| 69 } |
| 68 | 70 |
| 69 std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(id, kArticlesRemoteId)); | 71 std::unique_ptr<NTPSnippet> snippet(new NTPSnippet(id, kArticlesRemoteId)); |
| 70 | 72 |
| 71 std::string title; | 73 std::string title; |
| 72 if (content->GetString("title", &title)) | 74 if (content->GetString("title", &title)) { |
| 73 snippet->set_title(title); | 75 snippet->set_title(title); |
| 76 } |
| 74 std::string salient_image_url; | 77 std::string salient_image_url; |
| 75 if (content->GetString("thumbnailUrl", &salient_image_url)) | 78 if (content->GetString("thumbnailUrl", &salient_image_url)) { |
| 76 snippet->set_salient_image_url(GURL(salient_image_url)); | 79 snippet->set_salient_image_url(GURL(salient_image_url)); |
| 80 } |
| 77 std::string snippet_str; | 81 std::string snippet_str; |
| 78 if (content->GetString("snippet", &snippet_str)) | 82 if (content->GetString("snippet", &snippet_str)) { |
| 79 snippet->set_snippet(snippet_str); | 83 snippet->set_snippet(snippet_str); |
| 84 } |
| 80 // The creation and expiry timestamps are uint64s which are stored as strings. | 85 // The creation and expiry timestamps are uint64s which are stored as strings. |
| 81 std::string creation_timestamp_str; | 86 std::string creation_timestamp_str; |
| 82 if (content->GetString("creationTimestampSec", &creation_timestamp_str)) | 87 if (content->GetString("creationTimestampSec", &creation_timestamp_str)) { |
| 83 snippet->set_publish_date(TimeFromJsonString(creation_timestamp_str)); | 88 snippet->set_publish_date(TimeFromJsonString(creation_timestamp_str)); |
| 89 } |
| 84 std::string expiry_timestamp_str; | 90 std::string expiry_timestamp_str; |
| 85 if (content->GetString("expiryTimestampSec", &expiry_timestamp_str)) | 91 if (content->GetString("expiryTimestampSec", &expiry_timestamp_str)) { |
| 86 snippet->set_expiry_date(TimeFromJsonString(expiry_timestamp_str)); | 92 snippet->set_expiry_date(TimeFromJsonString(expiry_timestamp_str)); |
| 93 } |
| 87 | 94 |
| 88 const base::ListValue* corpus_infos_list = nullptr; | 95 const base::ListValue* corpus_infos_list = nullptr; |
| 89 if (!content->GetList("sourceCorpusInfo", &corpus_infos_list)) { | 96 if (!content->GetList("sourceCorpusInfo", &corpus_infos_list)) { |
| 90 DLOG(WARNING) << "No sources found for article " << title; | 97 DLOG(WARNING) << "No sources found for article " << title; |
| 91 return nullptr; | 98 return nullptr; |
| 92 } | 99 } |
| 93 | 100 |
| 94 std::vector<std::string> additional_ids; | 101 std::vector<std::string> additional_ids; |
| 95 for (const auto& value : *corpus_infos_list) { | 102 for (const auto& value : *corpus_infos_list) { |
| 96 const base::DictionaryValue* dict_value = nullptr; | 103 const base::DictionaryValue* dict_value = nullptr; |
| 97 if (!value->GetAsDictionary(&dict_value)) { | 104 if (!value->GetAsDictionary(&dict_value)) { |
| 98 DLOG(WARNING) << "Invalid source info for article " << id; | 105 DLOG(WARNING) << "Invalid source info for article " << id; |
| 99 continue; | 106 continue; |
| 100 } | 107 } |
| 101 | 108 |
| 102 std::string corpus_id_str; | 109 std::string corpus_id_str; |
| 103 GURL corpus_id; | 110 GURL corpus_id; |
| 104 if (dict_value->GetString("corpusId", &corpus_id_str)) | 111 if (dict_value->GetString("corpusId", &corpus_id_str)) { |
| 105 corpus_id = GURL(corpus_id_str); | 112 corpus_id = GURL(corpus_id_str); |
| 113 } |
| 106 | 114 |
| 107 if (!corpus_id.is_valid()) { | 115 if (!corpus_id.is_valid()) { |
| 108 // We must at least have a valid source URL. | 116 // We must at least have a valid source URL. |
| 109 DLOG(WARNING) << "Invalid article url " << corpus_id_str; | 117 DLOG(WARNING) << "Invalid article url " << corpus_id_str; |
| 110 continue; | 118 continue; |
| 111 } | 119 } |
| 112 const base::DictionaryValue* publisher_data = nullptr; | 120 const base::DictionaryValue* publisher_data = nullptr; |
| 113 std::string site_title; | 121 std::string site_title; |
| 114 if (dict_value->GetDictionary("publisherData", &publisher_data)) { | 122 if (dict_value->GetDictionary("publisherData", &publisher_data)) { |
| 115 if (!publisher_data->GetString("sourceName", &site_title)) { | 123 if (!publisher_data->GetString("sourceName", &site_title)) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 139 snippet->AddIDs(additional_ids); | 147 snippet->AddIDs(additional_ids); |
| 140 | 148 |
| 141 if (snippet->sources_.empty()) { | 149 if (snippet->sources_.empty()) { |
| 142 DLOG(WARNING) << "No sources found for article " << id; | 150 DLOG(WARNING) << "No sources found for article " << id; |
| 143 return nullptr; | 151 return nullptr; |
| 144 } | 152 } |
| 145 | 153 |
| 146 snippet->InitBestSource(); | 154 snippet->InitBestSource(); |
| 147 | 155 |
| 148 double score; | 156 double score; |
| 149 if (dict.GetDouble("score", &score)) | 157 if (dict.GetDouble("score", &score)) { |
| 150 snippet->set_score(score); | 158 snippet->set_score(score); |
| 159 } |
| 151 | 160 |
| 152 return snippet; | 161 return snippet; |
| 153 } | 162 } |
| 154 | 163 |
| 155 // static | 164 // static |
| 156 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromContentSuggestionsDictionary( | 165 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromContentSuggestionsDictionary( |
| 157 const base::DictionaryValue& dict, | 166 const base::DictionaryValue& dict, |
| 158 int remote_category_id) { | 167 int remote_category_id) { |
| 159 const base::ListValue* ids; | 168 const base::ListValue* ids; |
| 160 if (!dict.GetList("ids", &ids)) return nullptr; | 169 if (!dict.GetList("ids", &ids)) { |
| 170 return nullptr; |
| 171 } |
| 161 std::vector<std::string> parsed_ids; | 172 std::vector<std::string> parsed_ids; |
| 162 for (const auto& value : *ids) { | 173 for (const auto& value : *ids) { |
| 163 std::string id; | 174 std::string id; |
| 164 if (!value->GetAsString(&id)) return nullptr; | 175 if (!value->GetAsString(&id)) { |
| 176 return nullptr; |
| 177 } |
| 165 parsed_ids.push_back(id); | 178 parsed_ids.push_back(id); |
| 166 } | 179 } |
| 167 | 180 |
| 168 if (parsed_ids.empty()) return nullptr; | 181 if (parsed_ids.empty()) { |
| 182 return nullptr; |
| 183 } |
| 169 auto snippet = | 184 auto snippet = |
| 170 base::MakeUnique<NTPSnippet>(parsed_ids.front(), remote_category_id); | 185 base::MakeUnique<NTPSnippet>(parsed_ids.front(), remote_category_id); |
| 171 parsed_ids.erase(parsed_ids.begin(), parsed_ids.begin() + 1); | 186 parsed_ids.erase(parsed_ids.begin(), parsed_ids.begin() + 1); |
| 172 snippet->AddIDs(parsed_ids); | 187 snippet->AddIDs(parsed_ids); |
| 173 | 188 |
| 174 snippet->sources_.emplace_back(GURL(), std::string(), GURL()); | 189 snippet->sources_.emplace_back(GURL(), std::string(), GURL()); |
| 175 auto* source = &snippet->sources_.back(); | 190 auto* source = &snippet->sources_.back(); |
| 176 snippet->best_source_index_ = 0; | 191 snippet->best_source_index_ = 0; |
| 177 | 192 |
| 178 if (!(dict.GetString("title", &snippet->title_) && | 193 if (!(dict.GetString("title", &snippet->title_) && |
| 179 dict.GetString("snippet", &snippet->snippet_) && | 194 dict.GetString("snippet", &snippet->snippet_) && |
| 180 GetTimeValue(dict, "creationTime", &snippet->publish_date_) && | 195 GetTimeValue(dict, "creationTime", &snippet->publish_date_) && |
| 181 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) && | 196 GetTimeValue(dict, "expirationTime", &snippet->expiry_date_) && |
| 182 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) && | 197 GetURLValue(dict, "imageUrl", &snippet->salient_image_url_) && |
| 183 dict.GetString("attribution", &source->publisher_name) && | 198 dict.GetString("attribution", &source->publisher_name) && |
| 184 GetURLValue(dict, "fullPageUrl", &source->url))) { | 199 GetURLValue(dict, "fullPageUrl", &source->url))) { |
| 185 return nullptr; | 200 return nullptr; |
| 186 } | 201 } |
| 187 GetURLValue(dict, "ampUrl", &source->amp_url); // May fail; OK. | 202 GetURLValue(dict, "ampUrl", &source->amp_url); // May fail; OK. |
| 188 // TODO(sfiera): also favicon URL. | 203 // TODO(sfiera): also favicon URL. |
| 189 | 204 |
| 190 double score; | 205 double score; |
| 191 if (dict.GetDouble("score", &score)) | 206 if (dict.GetDouble("score", &score)) { |
| 192 snippet->set_score(score); | 207 snippet->set_score(score); |
| 208 } |
| 193 | 209 |
| 194 return snippet; | 210 return snippet; |
| 195 } | 211 } |
| 196 | 212 |
| 197 // static | 213 // static |
| 198 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromProto( | 214 std::unique_ptr<NTPSnippet> NTPSnippet::CreateFromProto( |
| 199 const SnippetProto& proto) { | 215 const SnippetProto& proto) { |
| 200 // Need at least the id. | 216 // Need at least the id. |
| 201 if (proto.ids_size() == 0 || proto.ids(0).empty()) | 217 if (proto.ids_size() == 0 || proto.ids(0).empty()) { |
| 202 return nullptr; | 218 return nullptr; |
| 219 } |
| 203 | 220 |
| 204 int remote_category_id = proto.has_remote_category_id() | 221 int remote_category_id = proto.has_remote_category_id() |
| 205 ? proto.remote_category_id() | 222 ? proto.remote_category_id() |
| 206 : kArticlesRemoteId; | 223 : kArticlesRemoteId; |
| 207 | 224 |
| 208 auto snippet = base::MakeUnique<NTPSnippet>(proto.ids(0), remote_category_id); | 225 auto snippet = base::MakeUnique<NTPSnippet>(proto.ids(0), remote_category_id); |
| 209 snippet->AddIDs( | 226 snippet->AddIDs( |
| 210 std::vector<std::string>(proto.ids().begin() + 1, proto.ids().end())); | 227 std::vector<std::string>(proto.ids().begin() + 1, proto.ids().end())); |
| 211 | 228 |
| 212 snippet->set_title(proto.title()); | 229 snippet->set_title(proto.title()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 snippet->InitBestSource(); | 262 snippet->InitBestSource(); |
| 246 | 263 |
| 247 return snippet; | 264 return snippet; |
| 248 } | 265 } |
| 249 | 266 |
| 250 SnippetProto NTPSnippet::ToProto() const { | 267 SnippetProto NTPSnippet::ToProto() const { |
| 251 SnippetProto result; | 268 SnippetProto result; |
| 252 for (const std::string& id : ids_) { | 269 for (const std::string& id : ids_) { |
| 253 result.add_ids(id); | 270 result.add_ids(id); |
| 254 } | 271 } |
| 255 if (!title_.empty()) | 272 if (!title_.empty()) { |
| 256 result.set_title(title_); | 273 result.set_title(title_); |
| 257 if (!snippet_.empty()) | 274 } |
| 275 if (!snippet_.empty()) { |
| 258 result.set_snippet(snippet_); | 276 result.set_snippet(snippet_); |
| 259 if (salient_image_url_.is_valid()) | 277 } |
| 278 if (salient_image_url_.is_valid()) { |
| 260 result.set_salient_image_url(salient_image_url_.spec()); | 279 result.set_salient_image_url(salient_image_url_.spec()); |
| 261 if (!publish_date_.is_null()) | 280 } |
| 281 if (!publish_date_.is_null()) { |
| 262 result.set_publish_date(publish_date_.ToInternalValue()); | 282 result.set_publish_date(publish_date_.ToInternalValue()); |
| 263 if (!expiry_date_.is_null()) | 283 } |
| 284 if (!expiry_date_.is_null()) { |
| 264 result.set_expiry_date(expiry_date_.ToInternalValue()); | 285 result.set_expiry_date(expiry_date_.ToInternalValue()); |
| 286 } |
| 265 result.set_score(score_); | 287 result.set_score(score_); |
| 266 result.set_dismissed(is_dismissed_); | 288 result.set_dismissed(is_dismissed_); |
| 267 result.set_remote_category_id(remote_category_id_); | 289 result.set_remote_category_id(remote_category_id_); |
| 268 | 290 |
| 269 for (const SnippetSource& source : sources_) { | 291 for (const SnippetSource& source : sources_) { |
| 270 SnippetSourceProto* source_proto = result.add_sources(); | 292 SnippetSourceProto* source_proto = result.add_sources(); |
| 271 source_proto->set_url(source.url.spec()); | 293 source_proto->set_url(source.url.spec()); |
| 272 if (!source.publisher_name.empty()) | 294 if (!source.publisher_name.empty()) { |
| 273 source_proto->set_publisher_name(source.publisher_name); | 295 source_proto->set_publisher_name(source.publisher_name); |
| 274 if (source.amp_url.is_valid()) | 296 } |
| 297 if (source.amp_url.is_valid()) { |
| 275 source_proto->set_amp_url(source.amp_url.spec()); | 298 source_proto->set_amp_url(source.amp_url.spec()); |
| 299 } |
| 276 } | 300 } |
| 277 | 301 |
| 278 return result; | 302 return result; |
| 279 } | 303 } |
| 280 | 304 |
| 281 void NTPSnippet::AddIDs(const std::vector<std::string>& ids) { | 305 void NTPSnippet::AddIDs(const std::vector<std::string>& ids) { |
| 282 ids_.insert(ids_.end(), ids.begin(), ids.end()); | 306 ids_.insert(ids_.end(), ids.begin(), ids.end()); |
| 283 } | 307 } |
| 284 | 308 |
| 285 // static | 309 // static |
| (...skipping 28 matching lines...) Expand all Loading... |
| 314 best_source_index_ = i; | 338 best_source_index_ = i; |
| 315 if (!source.amp_url.is_empty()) { | 339 if (!source.amp_url.is_empty()) { |
| 316 // This is the best possible source, stop looking. | 340 // This is the best possible source, stop looking. |
| 317 break; | 341 break; |
| 318 } | 342 } |
| 319 } | 343 } |
| 320 } | 344 } |
| 321 } | 345 } |
| 322 | 346 |
| 323 } // namespace ntp_snippets | 347 } // namespace ntp_snippets |
| OLD | NEW |