| 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/ntp_snippets_service.h" | 5 #include "components/ntp_snippets/ntp_snippets_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> |
| 8 #include <utility> | 9 #include <utility> |
| 9 | 10 |
| 10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 11 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 12 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
| 13 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
| 14 #include "base/location.h" | 15 #include "base/location.h" |
| 15 #include "base/path_service.h" | 16 #include "base/path_service.h" |
| 16 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 const NTPSnippetsService::NTPSnippetStorage& snippets) { | 145 const NTPSnippetsService::NTPSnippetStorage& snippets) { |
| 145 scoped_ptr<base::ListValue> list(new base::ListValue); | 146 scoped_ptr<base::ListValue> list(new base::ListValue); |
| 146 for (const auto& snippet : snippets) { | 147 for (const auto& snippet : snippets) { |
| 147 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | 148 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); |
| 148 dict->Set(kContentInfo, snippet->ToDictionary()); | 149 dict->Set(kContentInfo, snippet->ToDictionary()); |
| 149 list->Append(std::move(dict)); | 150 list->Append(std::move(dict)); |
| 150 } | 151 } |
| 151 return list; | 152 return list; |
| 152 } | 153 } |
| 153 | 154 |
| 155 bool ContainsSnippet(const NTPSnippetsService::NTPSnippetStorage& haystack, |
| 156 const scoped_ptr<NTPSnippet>& needle) { |
| 157 const GURL& url = needle->url(); |
| 158 return std::find_if(haystack.begin(), haystack.end(), |
| 159 [&url](const scoped_ptr<NTPSnippet>& snippet) { |
| 160 return snippet->url() == url; |
| 161 }) != haystack.end(); |
| 162 } |
| 163 |
| 154 } // namespace | 164 } // namespace |
| 155 | 165 |
| 156 NTPSnippetsService::NTPSnippetsService( | 166 NTPSnippetsService::NTPSnippetsService( |
| 157 PrefService* pref_service, | 167 PrefService* pref_service, |
| 158 SuggestionsService* suggestions_service, | 168 SuggestionsService* suggestions_service, |
| 159 scoped_refptr<base::SequencedTaskRunner> file_task_runner, | 169 scoped_refptr<base::SequencedTaskRunner> file_task_runner, |
| 160 const std::string& application_language_code, | 170 const std::string& application_language_code, |
| 161 NTPSnippetsScheduler* scheduler, | 171 NTPSnippetsScheduler* scheduler, |
| 162 scoped_ptr<NTPSnippetsFetcher> snippets_fetcher, | 172 scoped_ptr<NTPSnippetsFetcher> snippets_fetcher, |
| 163 const ParseJSONCallback& parse_json_callback) | 173 const ParseJSONCallback& parse_json_callback) |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 if (!top_dict->GetList("recos", &list)) | 352 if (!top_dict->GetList("recos", &list)) |
| 343 return false; | 353 return false; |
| 344 | 354 |
| 345 return LoadFromListValue(*list); | 355 return LoadFromListValue(*list); |
| 346 } | 356 } |
| 347 | 357 |
| 348 bool NTPSnippetsService::LoadFromListValue(const base::ListValue& list) { | 358 bool NTPSnippetsService::LoadFromListValue(const base::ListValue& list) { |
| 349 NTPSnippetStorage new_snippets; | 359 NTPSnippetStorage new_snippets; |
| 350 if (!AddSnippetsFromListValue(list, &new_snippets)) | 360 if (!AddSnippetsFromListValue(list, &new_snippets)) |
| 351 return false; | 361 return false; |
| 362 |
| 363 // Remove new snippets that we already have, or that have been discarded. |
| 364 new_snippets.erase( |
| 365 std::remove_if(new_snippets.begin(), new_snippets.end(), |
| 366 [this](const scoped_ptr<NTPSnippet>& snippet) { |
| 367 return ContainsSnippet(discarded_snippets_, snippet) || |
| 368 ContainsSnippet(snippets_, snippet); |
| 369 }), |
| 370 new_snippets.end()); |
| 371 |
| 372 // Fill in default publish/expiry dates where required. |
| 352 for (scoped_ptr<NTPSnippet>& snippet : new_snippets) { | 373 for (scoped_ptr<NTPSnippet>& snippet : new_snippets) { |
| 353 // If this snippet has previously been discarded, don't add it again. | |
| 354 if (HasDiscardedSnippet(snippet->url())) | |
| 355 continue; | |
| 356 | |
| 357 // If the snippet has no publish/expiry dates, fill in defaults. | |
| 358 if (snippet->publish_date().is_null()) | 374 if (snippet->publish_date().is_null()) |
| 359 snippet->set_publish_date(base::Time::Now()); | 375 snippet->set_publish_date(base::Time::Now()); |
| 360 if (snippet->expiry_date().is_null()) { | 376 if (snippet->expiry_date().is_null()) { |
| 361 snippet->set_expiry_date( | 377 snippet->set_expiry_date( |
| 362 snippet->publish_date() + | 378 snippet->publish_date() + |
| 363 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins)); | 379 base::TimeDelta::FromMinutes(kDefaultExpiryTimeMins)); |
| 364 } | 380 } |
| 381 } |
| 365 | 382 |
| 366 // Check if we already have a snippet with the same URL. If so, replace it | 383 // Insert the new snippets at the front. |
| 367 // rather than adding a duplicate. | 384 snippets_.insert(snippets_.begin(), |
| 368 const GURL& url = snippet->url(); | 385 std::make_move_iterator(new_snippets.begin()), |
| 369 auto it = std::find_if(snippets_.begin(), snippets_.end(), | 386 std::make_move_iterator(new_snippets.end())); |
| 370 [&url](const scoped_ptr<NTPSnippet>& old_snippet) { | |
| 371 return old_snippet->url() == url; | |
| 372 }); | |
| 373 if (it != snippets_.end()) | |
| 374 *it = std::move(snippet); | |
| 375 else | |
| 376 snippets_.push_back(std::move(snippet)); | |
| 377 } | |
| 378 | 387 |
| 379 // Immediately remove any already-expired snippets. This will also notify our | 388 // Immediately remove any already-expired snippets. This will also notify our |
| 380 // observers and schedule the expiry timer. | 389 // observers and schedule the expiry timer. |
| 381 RemoveExpiredSnippets(); | 390 RemoveExpiredSnippets(); |
| 382 | 391 |
| 383 return true; | 392 return true; |
| 384 } | 393 } |
| 385 | 394 |
| 386 void NTPSnippetsService::LoadSnippetsFromPrefs() { | 395 void NTPSnippetsService::LoadSnippetsFromPrefs() { |
| 387 bool success = LoadFromListValue(*pref_service_->GetList(prefs::kSnippets)); | 396 bool success = LoadFromListValue(*pref_service_->GetList(prefs::kSnippets)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 418 } | 427 } |
| 419 | 428 |
| 420 void NTPSnippetsService::StoreSnippetHostsToPrefs( | 429 void NTPSnippetsService::StoreSnippetHostsToPrefs( |
| 421 const std::set<std::string>& hosts) { | 430 const std::set<std::string>& hosts) { |
| 422 base::ListValue list; | 431 base::ListValue list; |
| 423 for (const std::string& host : hosts) | 432 for (const std::string& host : hosts) |
| 424 list.AppendString(host); | 433 list.AppendString(host); |
| 425 pref_service_->Set(prefs::kSnippetHosts, list); | 434 pref_service_->Set(prefs::kSnippetHosts, list); |
| 426 } | 435 } |
| 427 | 436 |
| 428 bool NTPSnippetsService::HasDiscardedSnippet(const GURL& url) const { | |
| 429 auto it = std::find_if(discarded_snippets_.begin(), discarded_snippets_.end(), | |
| 430 [&url](const scoped_ptr<NTPSnippet>& snippet) { | |
| 431 return snippet->url() == url; | |
| 432 }); | |
| 433 return it != discarded_snippets_.end(); | |
| 434 } | |
| 435 | |
| 436 void NTPSnippetsService::RemoveExpiredSnippets() { | 437 void NTPSnippetsService::RemoveExpiredSnippets() { |
| 437 base::Time expiry = base::Time::Now(); | 438 base::Time expiry = base::Time::Now(); |
| 438 | 439 |
| 439 snippets_.erase( | 440 snippets_.erase( |
| 440 std::remove_if(snippets_.begin(), snippets_.end(), | 441 std::remove_if(snippets_.begin(), snippets_.end(), |
| 441 [&expiry](const scoped_ptr<NTPSnippet>& snippet) { | 442 [&expiry](const scoped_ptr<NTPSnippet>& snippet) { |
| 442 return snippet->expiry_date() <= expiry; | 443 return snippet->expiry_date() <= expiry; |
| 443 }), | 444 }), |
| 444 snippets_.end()); | 445 snippets_.end()); |
| 445 StoreSnippetsToPrefs(); | 446 StoreSnippetsToPrefs(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 468 if (snippet->expiry_date() < next_expiry) | 469 if (snippet->expiry_date() < next_expiry) |
| 469 next_expiry = snippet->expiry_date(); | 470 next_expiry = snippet->expiry_date(); |
| 470 } | 471 } |
| 471 DCHECK_GT(next_expiry, expiry); | 472 DCHECK_GT(next_expiry, expiry); |
| 472 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, | 473 expiry_timer_.Start(FROM_HERE, next_expiry - expiry, |
| 473 base::Bind(&NTPSnippetsService::RemoveExpiredSnippets, | 474 base::Bind(&NTPSnippetsService::RemoveExpiredSnippets, |
| 474 base::Unretained(this))); | 475 base::Unretained(this))); |
| 475 } | 476 } |
| 476 | 477 |
| 477 } // namespace ntp_snippets | 478 } // namespace ntp_snippets |
| OLD | NEW |