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 |