Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/download/download_query.h" | 5 #include "chrome/browser/download/download_query.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 return false; | 62 return false; |
| 63 } | 63 } |
| 64 out->push_back(element); | 64 out->push_back(element); |
| 65 } | 65 } |
| 66 return true; | 66 return true; |
| 67 } | 67 } |
| 68 | 68 |
| 69 // The next several functions are helpers for making Callbacks that access | 69 // The next several functions are helpers for making Callbacks that access |
| 70 // DownloadItem fields. | 70 // DownloadItem fields. |
| 71 | 71 |
| 72 static int64_t GetStartTimeMsEpoch(const DownloadItem& item) { | 72 int64_t GetStartTimeMsEpoch(const DownloadItem& item) { |
| 73 return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); | 73 return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); |
| 74 } | 74 } |
| 75 | 75 |
| 76 static int64_t GetEndTimeMsEpoch(const DownloadItem& item) { | 76 int64_t GetEndTimeMsEpoch(const DownloadItem& item) { |
| 77 return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); | 77 return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 std::string TimeToISO8601(const base::Time& t) { | 80 std::string TimeToISO8601(const base::Time& t) { |
| 81 base::Time::Exploded exploded; | 81 base::Time::Exploded exploded; |
| 82 t.UTCExplode(&exploded); | 82 t.UTCExplode(&exploded); |
| 83 return base::StringPrintf( | 83 return base::StringPrintf( |
| 84 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, | 84 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, |
| 85 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, | 85 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, |
| 86 exploded.millisecond); | 86 exploded.millisecond); |
| 87 } | 87 } |
| 88 | 88 |
| 89 static std::string GetStartTime(const DownloadItem& item) { | 89 std::string GetStartTime(const DownloadItem& item) { |
| 90 return TimeToISO8601(item.GetStartTime()); | 90 return TimeToISO8601(item.GetStartTime()); |
| 91 } | 91 } |
| 92 | 92 |
| 93 static std::string GetEndTime(const DownloadItem& item) { | 93 std::string GetEndTime(const DownloadItem& item) { |
| 94 return TimeToISO8601(item.GetEndTime()); | 94 return TimeToISO8601(item.GetEndTime()); |
| 95 } | 95 } |
| 96 | 96 |
| 97 static bool GetDangerAccepted(const DownloadItem& item) { | 97 bool GetDangerAccepted(const DownloadItem& item) { |
| 98 return (item.GetDangerType() == | 98 return (item.GetDangerType() == |
| 99 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); | 99 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); |
| 100 } | 100 } |
| 101 | 101 |
| 102 static bool GetExists(const DownloadItem& item) { | 102 bool GetExists(const DownloadItem& item) { |
| 103 return !item.GetFileExternallyRemoved(); | 103 return !item.GetFileExternallyRemoved(); |
| 104 } | 104 } |
| 105 | 105 |
| 106 static base::string16 GetFilename(const DownloadItem& item) { | 106 base::string16 GetFilename(const DownloadItem& item) { |
| 107 // This filename will be compared with strings that could be passed in by the | 107 // This filename will be compared with strings that could be passed in by the |
| 108 // user, who only sees LossyDisplayNames. | 108 // user, who only sees LossyDisplayNames. |
| 109 return item.GetTargetFilePath().LossyDisplayName(); | 109 return item.GetTargetFilePath().LossyDisplayName(); |
| 110 } | 110 } |
| 111 | 111 |
| 112 static std::string GetFilenameUTF8(const DownloadItem& item) { | 112 std::string GetFilenameUTF8(const DownloadItem& item) { |
| 113 return base::UTF16ToUTF8(GetFilename(item)); | 113 return base::UTF16ToUTF8(GetFilename(item)); |
| 114 } | 114 } |
| 115 | 115 |
| 116 static std::string GetUrl(const DownloadItem& item) { | 116 std::string GetOriginalUrl(const DownloadItem& item) { |
| 117 return item.GetOriginalUrl().spec(); | 117 return item.GetOriginalUrl().spec(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 static DownloadItem::DownloadState GetState(const DownloadItem& item) { | 120 std::string GetUrl(const DownloadItem& item) { |
| 121 return item.GetURL().spec(); | |
| 122 } | |
| 123 | |
| 124 DownloadItem::DownloadState GetState(const DownloadItem& item) { | |
| 121 return item.GetState(); | 125 return item.GetState(); |
| 122 } | 126 } |
| 123 | 127 |
| 124 static DownloadDangerType GetDangerType(const DownloadItem& item) { | 128 DownloadDangerType GetDangerType(const DownloadItem& item) { |
| 125 return item.GetDangerType(); | 129 return item.GetDangerType(); |
| 126 } | 130 } |
| 127 | 131 |
| 128 static int GetReceivedBytes(const DownloadItem& item) { | 132 int GetReceivedBytes(const DownloadItem& item) { |
| 129 return item.GetReceivedBytes(); | 133 return item.GetReceivedBytes(); |
| 130 } | 134 } |
| 131 | 135 |
| 132 static int GetTotalBytes(const DownloadItem& item) { | 136 int GetTotalBytes(const DownloadItem& item) { |
| 133 return item.GetTotalBytes(); | 137 return item.GetTotalBytes(); |
| 134 } | 138 } |
| 135 | 139 |
| 136 static std::string GetMimeType(const DownloadItem& item) { | 140 std::string GetMimeType(const DownloadItem& item) { |
| 137 return item.GetMimeType(); | 141 return item.GetMimeType(); |
| 138 } | 142 } |
| 139 | 143 |
| 140 static bool IsPaused(const DownloadItem& item) { | 144 bool IsPaused(const DownloadItem& item) { |
| 141 return item.IsPaused(); | 145 return item.IsPaused(); |
| 142 } | 146 } |
| 143 | 147 |
| 144 enum ComparisonType {LT, EQ, GT}; | 148 enum ComparisonType {LT, EQ, GT}; |
| 145 | 149 |
| 146 // Returns true if |item| matches the filter specified by |value|, |cmptype|, | 150 // Returns true if |item| matches the filter specified by |value|, |cmptype|, |
| 147 // and |accessor|. |accessor| is conceptually a function that takes a | 151 // and |accessor|. |accessor| is conceptually a function that takes a |
| 148 // DownloadItem and returns one of its fields, which is then compared to | 152 // DownloadItem and returns one of its fields, which is then compared to |
| 149 // |value|. | 153 // |value|. |
| 150 template<typename ValueType> | 154 template<typename ValueType> |
| 151 static bool FieldMatches( | 155 bool FieldMatches( |
| 152 const ValueType& value, | 156 const ValueType& value, |
| 153 ComparisonType cmptype, | 157 ComparisonType cmptype, |
| 154 const base::Callback<ValueType(const DownloadItem&)>& accessor, | 158 const base::Callback<ValueType(const DownloadItem&)>& accessor, |
| 155 const DownloadItem& item) { | 159 const DownloadItem& item) { |
| 156 switch (cmptype) { | 160 switch (cmptype) { |
| 157 case LT: return accessor.Run(item) < value; | 161 case LT: return accessor.Run(item) < value; |
| 158 case EQ: return accessor.Run(item) == value; | 162 case EQ: return accessor.Run(item) == value; |
| 159 case GT: return accessor.Run(item) > value; | 163 case GT: return accessor.Run(item) > value; |
| 160 } | 164 } |
| 161 NOTREACHED(); | 165 NOTREACHED(); |
| 162 return false; | 166 return false; |
| 163 } | 167 } |
| 164 | 168 |
| 165 // Helper for building a Callback to FieldMatches<>(). | 169 // Helper for building a Callback to FieldMatches<>(). |
| 166 template <typename ValueType> DownloadQuery::FilterCallback BuildFilter( | 170 template <typename ValueType> DownloadQuery::FilterCallback BuildFilter( |
| 167 const base::Value& value, ComparisonType cmptype, | 171 const base::Value& value, ComparisonType cmptype, |
| 168 ValueType (*accessor)(const DownloadItem&)) { | 172 ValueType (*accessor)(const DownloadItem&)) { |
| 169 ValueType cpp_value; | 173 ValueType cpp_value; |
| 170 if (!GetAs(value, &cpp_value)) return DownloadQuery::FilterCallback(); | 174 if (!GetAs(value, &cpp_value)) return DownloadQuery::FilterCallback(); |
| 171 return base::Bind(&FieldMatches<ValueType>, cpp_value, cmptype, | 175 return base::Bind(&FieldMatches<ValueType>, cpp_value, cmptype, |
| 172 base::Bind(accessor)); | 176 base::Bind(accessor)); |
| 173 } | 177 } |
| 174 | 178 |
| 175 // Returns true if |accessor.Run(item)| matches |pattern|. | 179 // Returns true if |accessor.Run(item)| matches |pattern|. |
| 176 static bool FindRegex( | 180 bool FindRegex( |
| 177 RE2* pattern, | 181 RE2* pattern, |
| 178 const base::Callback<std::string(const DownloadItem&)>& accessor, | 182 const base::Callback<std::string(const DownloadItem&)>& accessor, |
| 179 const DownloadItem& item) { | 183 const DownloadItem& item) { |
| 180 return RE2::PartialMatch(accessor.Run(item), *pattern); | 184 return RE2::PartialMatch(accessor.Run(item), *pattern); |
| 181 } | 185 } |
| 182 | 186 |
| 183 // Helper for building a Callback to FindRegex(). | 187 // Helper for building a Callback to FindRegex(). |
| 184 DownloadQuery::FilterCallback BuildRegexFilter( | 188 DownloadQuery::FilterCallback BuildRegexFilter( |
| 185 const base::Value& regex_value, | 189 const base::Value& regex_value, |
| 186 std::string (*accessor)(const DownloadItem&)) { | 190 std::string (*accessor)(const DownloadItem&)) { |
| 187 std::string regex_str; | 191 std::string regex_str; |
| 188 if (!GetAs(regex_value, ®ex_str)) return DownloadQuery::FilterCallback(); | 192 if (!GetAs(regex_value, ®ex_str)) return DownloadQuery::FilterCallback(); |
| 189 std::unique_ptr<RE2> pattern(new RE2(regex_str)); | 193 std::unique_ptr<RE2> pattern(new RE2(regex_str)); |
| 190 if (!pattern->ok()) return DownloadQuery::FilterCallback(); | 194 if (!pattern->ok()) return DownloadQuery::FilterCallback(); |
| 191 return base::Bind(&FindRegex, base::Owned(pattern.release()), | 195 return base::Bind(&FindRegex, base::Owned(pattern.release()), |
| 192 base::Bind(accessor)); | 196 base::Bind(accessor)); |
| 193 } | 197 } |
| 194 | 198 |
| 195 // Returns a ComparisonType to indicate whether a field in |left| is less than, | 199 // Returns a ComparisonType to indicate whether a field in |left| is less than, |
| 196 // greater than or equal to the same field in |right|. | 200 // greater than or equal to the same field in |right|. |
| 197 template<typename ValueType> | 201 template<typename ValueType> |
| 198 static ComparisonType Compare( | 202 ComparisonType Compare( |
| 199 const base::Callback<ValueType(const DownloadItem&)>& accessor, | 203 const base::Callback<ValueType(const DownloadItem&)>& accessor, |
| 200 const DownloadItem& left, const DownloadItem& right) { | 204 const DownloadItem& left, const DownloadItem& right) { |
| 201 ValueType left_value = accessor.Run(left); | 205 ValueType left_value = accessor.Run(left); |
| 202 ValueType right_value = accessor.Run(right); | 206 ValueType right_value = accessor.Run(right); |
| 203 if (left_value > right_value) return GT; | 207 if (left_value > right_value) return GT; |
| 204 if (left_value < right_value) return LT; | 208 if (left_value < right_value) return LT; |
| 205 DCHECK_EQ(left_value, right_value); | 209 DCHECK_EQ(left_value, right_value); |
| 206 return EQ; | 210 return EQ; |
| 207 } | 211 } |
| 208 | 212 |
| 209 } // anonymous namespace | 213 } // anonymous namespace |
| 210 | 214 |
| 211 // static | 215 // static |
| 212 bool DownloadQuery::MatchesQuery(const std::vector<base::string16>& query_terms, | 216 bool DownloadQuery::MatchesQuery(const std::vector<base::string16>& query_terms, |
| 213 const DownloadItem& item) { | 217 const DownloadItem& item) { |
| 214 if (query_terms.empty()) | 218 if (query_terms.empty()) |
| 215 return true; | 219 return true; |
| 216 | 220 |
| 217 base::string16 url_raw(base::UTF8ToUTF16(item.GetOriginalUrl().spec())); | 221 base::string16 original_url_raw( |
| 218 base::string16 url_formatted = url_raw; | 222 base::UTF8ToUTF16(item.GetOriginalUrl().spec())); |
| 219 if (item.GetBrowserContext()) | 223 base::string16 url_raw(base::UTF8ToUTF16(item.GetURL().spec())); |
| 220 url_formatted = url_formatter::FormatUrl(item.GetOriginalUrl()); | 224 // Try to also match query with above URLs formatted in user display friendly |
| 225 // way. This will unescape spaces and trim all extra data (like username and | |
|
asanka
2016/06/23 15:48:12
Note that UnescapeRule::SPACE also implies Unescap
mharanczyk
2016/06/23 16:05:15
Reworded the comment.
| |
| 226 // password) from raw url so that for example raw url | |
| 227 // "http://some.server.org/example%20download/file.zip" will be matched with | |
| 228 // search term "example download". | |
| 229 base::string16 original_url_formatted( | |
| 230 url_formatter::FormatUrl(item.GetOriginalUrl())); | |
| 231 base::string16 url_formatted(url_formatter::FormatUrl(item.GetURL())); | |
| 221 base::string16 path(item.GetTargetFilePath().LossyDisplayName()); | 232 base::string16 path(item.GetTargetFilePath().LossyDisplayName()); |
| 222 | 233 |
| 223 for (std::vector<base::string16>::const_iterator it = query_terms.begin(); | 234 for (std::vector<base::string16>::const_iterator it = query_terms.begin(); |
| 224 it != query_terms.end(); ++it) { | 235 it != query_terms.end(); ++it) { |
| 225 base::string16 term = base::i18n::ToLower(*it); | 236 base::string16 term = base::i18n::ToLower(*it); |
| 226 if (!base::i18n::StringSearchIgnoringCaseAndAccents( | 237 if (!base::i18n::StringSearchIgnoringCaseAndAccents( |
| 238 term, original_url_raw, NULL, NULL) && | |
| 239 !base::i18n::StringSearchIgnoringCaseAndAccents( | |
| 240 term, original_url_formatted, NULL, NULL) && | |
| 241 !base::i18n::StringSearchIgnoringCaseAndAccents( | |
| 227 term, url_raw, NULL, NULL) && | 242 term, url_raw, NULL, NULL) && |
| 228 !base::i18n::StringSearchIgnoringCaseAndAccents( | 243 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 229 term, url_formatted, NULL, NULL) && | 244 term, url_formatted, NULL, NULL) && |
| 230 !base::i18n::StringSearchIgnoringCaseAndAccents( | 245 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 231 term, path, NULL, NULL)) { | 246 term, path, NULL, NULL)) { |
| 232 return false; | 247 return false; |
| 233 } | 248 } |
| 234 } | 249 } |
| 235 return true; | 250 return true; |
| 236 } | 251 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 case FILTER_STARTED_BEFORE: | 308 case FILTER_STARTED_BEFORE: |
| 294 return AddFilter(BuildFilter<std::string>(value, LT, &GetStartTime)); | 309 return AddFilter(BuildFilter<std::string>(value, LT, &GetStartTime)); |
| 295 case FILTER_START_TIME: | 310 case FILTER_START_TIME: |
| 296 return AddFilter(BuildFilter<std::string>(value, EQ, &GetStartTime)); | 311 return AddFilter(BuildFilter<std::string>(value, EQ, &GetStartTime)); |
| 297 case FILTER_TOTAL_BYTES: | 312 case FILTER_TOTAL_BYTES: |
| 298 return AddFilter(BuildFilter<int>(value, EQ, &GetTotalBytes)); | 313 return AddFilter(BuildFilter<int>(value, EQ, &GetTotalBytes)); |
| 299 case FILTER_TOTAL_BYTES_GREATER: | 314 case FILTER_TOTAL_BYTES_GREATER: |
| 300 return AddFilter(BuildFilter<int>(value, GT, &GetTotalBytes)); | 315 return AddFilter(BuildFilter<int>(value, GT, &GetTotalBytes)); |
| 301 case FILTER_TOTAL_BYTES_LESS: | 316 case FILTER_TOTAL_BYTES_LESS: |
| 302 return AddFilter(BuildFilter<int>(value, LT, &GetTotalBytes)); | 317 return AddFilter(BuildFilter<int>(value, LT, &GetTotalBytes)); |
| 318 case FILTER_ORIGINAL_URL: | |
| 319 return AddFilter(BuildFilter<std::string>(value, EQ, &GetOriginalUrl)); | |
| 320 case FILTER_ORIGINAL_URL_REGEX: | |
| 321 return AddFilter(BuildRegexFilter(value, &GetOriginalUrl)); | |
| 303 case FILTER_URL: | 322 case FILTER_URL: |
| 304 return AddFilter(BuildFilter<std::string>(value, EQ, &GetUrl)); | 323 return AddFilter(BuildFilter<std::string>(value, EQ, &GetUrl)); |
| 305 case FILTER_URL_REGEX: | 324 case FILTER_URL_REGEX: |
| 306 return AddFilter(BuildRegexFilter(value, &GetUrl)); | 325 return AddFilter(BuildRegexFilter(value, &GetUrl)); |
| 307 } | 326 } |
| 308 return false; | 327 return false; |
| 309 } | 328 } |
| 310 | 329 |
| 311 bool DownloadQuery::Matches(const DownloadItem& item) const { | 330 bool DownloadQuery::Matches(const DownloadItem& item) const { |
| 312 for (FilterCallbackVector::const_iterator filter = filters_.begin(); | 331 for (FilterCallbackVector::const_iterator filter = filters_.begin(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 void DownloadQuery::AddSorter(DownloadQuery::SortType type, | 402 void DownloadQuery::AddSorter(DownloadQuery::SortType type, |
| 384 DownloadQuery::SortDirection direction) { | 403 DownloadQuery::SortDirection direction) { |
| 385 switch (type) { | 404 switch (type) { |
| 386 case SORT_END_TIME: | 405 case SORT_END_TIME: |
| 387 sorters_.push_back(Sorter::Build<int64_t>(direction, &GetEndTimeMsEpoch)); | 406 sorters_.push_back(Sorter::Build<int64_t>(direction, &GetEndTimeMsEpoch)); |
| 388 break; | 407 break; |
| 389 case SORT_START_TIME: | 408 case SORT_START_TIME: |
| 390 sorters_.push_back( | 409 sorters_.push_back( |
| 391 Sorter::Build<int64_t>(direction, &GetStartTimeMsEpoch)); | 410 Sorter::Build<int64_t>(direction, &GetStartTimeMsEpoch)); |
| 392 break; | 411 break; |
| 412 case SORT_ORIGINAL_URL: | |
| 413 sorters_.push_back( | |
| 414 Sorter::Build<std::string>(direction, &GetOriginalUrl)); | |
| 415 break; | |
| 393 case SORT_URL: | 416 case SORT_URL: |
| 394 sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl)); | 417 sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl)); |
| 395 break; | 418 break; |
| 396 case SORT_FILENAME: | 419 case SORT_FILENAME: |
| 397 sorters_.push_back( | 420 sorters_.push_back( |
| 398 Sorter::Build<base::string16>(direction, &GetFilename)); | 421 Sorter::Build<base::string16>(direction, &GetFilename)); |
| 399 break; | 422 break; |
| 400 case SORT_DANGER: | 423 case SORT_DANGER: |
| 401 sorters_.push_back(Sorter::Build<DownloadDangerType>( | 424 sorters_.push_back(Sorter::Build<DownloadDangerType>( |
| 402 direction, &GetDangerType)); | 425 direction, &GetDangerType)); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 430 if (!sorters_.empty()) { | 453 if (!sorters_.empty()) { |
| 431 std::partial_sort(results->begin(), | 454 std::partial_sort(results->begin(), |
| 432 results->begin() + std::min(limit_, results->size()), | 455 results->begin() + std::min(limit_, results->size()), |
| 433 results->end(), | 456 results->end(), |
| 434 DownloadComparator(sorters_)); | 457 DownloadComparator(sorters_)); |
| 435 } | 458 } |
| 436 | 459 |
| 437 if (results->size() > limit_) | 460 if (results->size() > limit_) |
| 438 results->resize(limit_); | 461 results->resize(limit_); |
| 439 } | 462 } |
| OLD | NEW |