Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: components/omnibox/search_suggestion_parser.cc

Issue 669573005: Add a class to parse answer json. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tweaked API and finished unit tests Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/omnibox/search_suggestion_parser.h" 5 #include "components/omnibox/search_suggestion_parser.h"
6 6
7 #include "base/i18n/icu_string_conversions.h" 7 #include "base/i18n/icu_string_conversions.h"
8 #include "base/json/json_string_value_serializer.h" 8 #include "base/json/json_string_value_serializer.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 // SearchSuggestionParser::SuggestResult --------------------------------------- 58 // SearchSuggestionParser::SuggestResult ---------------------------------------
59 59
60 SearchSuggestionParser::SuggestResult::SuggestResult( 60 SearchSuggestionParser::SuggestResult::SuggestResult(
61 const base::string16& suggestion, 61 const base::string16& suggestion,
62 AutocompleteMatchType::Type type, 62 AutocompleteMatchType::Type type,
63 const base::string16& match_contents, 63 const base::string16& match_contents,
64 const base::string16& match_contents_prefix, 64 const base::string16& match_contents_prefix,
65 const base::string16& annotation, 65 const base::string16& annotation,
66 const base::string16& answer_contents, 66 const base::string16& answer_contents,
67 const base::string16& answer_type, 67 const base::string16& answer_type,
68 const SuggestionAnswer& answer,
68 const std::string& suggest_query_params, 69 const std::string& suggest_query_params,
69 const std::string& deletion_url, 70 const std::string& deletion_url,
70 bool from_keyword_provider, 71 bool from_keyword_provider,
71 int relevance, 72 int relevance,
72 bool relevance_from_server, 73 bool relevance_from_server,
73 bool should_prefetch, 74 bool should_prefetch,
74 const base::string16& input_text) 75 const base::string16& input_text)
75 : Result(from_keyword_provider, 76 : Result(from_keyword_provider,
76 relevance, 77 relevance,
77 relevance_from_server, 78 relevance_from_server,
78 type, 79 type,
79 deletion_url), 80 deletion_url),
80 suggestion_(suggestion), 81 suggestion_(suggestion),
81 match_contents_prefix_(match_contents_prefix), 82 match_contents_prefix_(match_contents_prefix),
82 annotation_(annotation), 83 annotation_(annotation),
83 suggest_query_params_(suggest_query_params), 84 suggest_query_params_(suggest_query_params),
84 answer_contents_(answer_contents), 85 answer_contents_(answer_contents),
85 answer_type_(answer_type), 86 answer_type_(answer_type),
87 answer_(answer),
86 should_prefetch_(should_prefetch) { 88 should_prefetch_(should_prefetch) {
87 match_contents_ = match_contents; 89 match_contents_ = match_contents;
88 DCHECK(!match_contents_.empty()); 90 DCHECK(!match_contents_.empty());
89 ClassifyMatchContents(true, input_text); 91 ClassifyMatchContents(true, input_text);
90 } 92 }
91 93
92 SearchSuggestionParser::SuggestResult::~SuggestResult() {} 94 SearchSuggestionParser::SuggestResult::~SuggestResult() {}
93 95
94 void SearchSuggestionParser::SuggestResult::ClassifyMatchContents( 96 void SearchSuggestionParser::SuggestResult::ClassifyMatchContents(
95 const bool allow_bolding_all, 97 const bool allow_bolding_all,
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 scheme_classifier, url, match_type, title, deletion_url, 435 scheme_classifier, url, match_type, title, deletion_url,
434 is_keyword_result, relevance, relevances != NULL, input.text(), 436 is_keyword_result, relevance, relevances != NULL, input.text(),
435 languages)); 437 languages));
436 } 438 }
437 } else { 439 } else {
438 base::string16 match_contents = suggestion; 440 base::string16 match_contents = suggestion;
439 base::string16 match_contents_prefix; 441 base::string16 match_contents_prefix;
440 base::string16 annotation; 442 base::string16 annotation;
441 base::string16 answer_contents; 443 base::string16 answer_contents;
442 base::string16 answer_type; 444 base::string16 answer_type;
445 SuggestionAnswer answer;
443 std::string suggest_query_params; 446 std::string suggest_query_params;
444 447
445 if (suggestion_details) { 448 if (suggestion_details) {
446 suggestion_details->GetDictionary(index, &suggestion_detail); 449 suggestion_details->GetDictionary(index, &suggestion_detail);
447 if (suggestion_detail) { 450 if (suggestion_detail) {
448 suggestion_detail->GetString("t", &match_contents); 451 suggestion_detail->GetString("t", &match_contents);
449 suggestion_detail->GetString("mp", &match_contents_prefix); 452 suggestion_detail->GetString("mp", &match_contents_prefix);
450 // Error correction for bad data from server. 453 // Error correction for bad data from server.
451 if (match_contents.empty()) 454 if (match_contents.empty())
452 match_contents = suggestion; 455 match_contents = suggestion;
453 suggestion_detail->GetString("a", &annotation); 456 suggestion_detail->GetString("a", &annotation);
454 suggestion_detail->GetString("q", &suggest_query_params); 457 suggestion_detail->GetString("q", &suggest_query_params);
455 458
456 // Extract Answers, if provided. 459 // Extract Answers, if provided.
457 const base::DictionaryValue* answer_json = NULL; 460 const base::DictionaryValue* answer_json = NULL;
458 if (suggestion_detail->GetDictionary("ansa", &answer_json)) { 461 if (suggestion_detail->GetDictionary("ansa", &answer_json)) {
459 match_type = AutocompleteMatchType::SEARCH_SUGGEST_ANSWER; 462 std::string contents, type;
460 GetAnswersImageURLs(answer_json, &results->answers_image_urls);
461 std::string contents;
462 base::JSONWriter::Write(answer_json, &contents); 463 base::JSONWriter::Write(answer_json, &contents);
463 answer_contents = base::UTF8ToUTF16(contents); 464 if (SuggestionAnswer::ParseAnswer(answer_json, &answer)) {
464 suggestion_detail->GetString("ansb", &answer_type); 465 match_type = AutocompleteMatchType::SEARCH_SUGGEST_ANSWER;
466 answer_contents = base::UTF8ToUTF16(contents);
467 suggestion_detail->GetString("ansb", &answer_type);
468 answer.SetType(answer_type);
469 GetAnswersImageURLs(answer, &results->answers_image_urls);
470 } else {
471 answer.Clear();
groby-ooo-7-16 2014/10/23 00:46:19 Question: What if ParseAnswer() returned void, and
Justin Donnelly 2014/10/23 17:59:37 I considered that, but this is such a standard C++
groby-ooo-7-16 2014/10/23 21:59:54 Since the SuggestionAnswer object already needs to
Justin Donnelly 2014/10/24 14:58:08 Done.
472 DLOG(ERROR) << "Invalid suggestion answer json: "
473 << answer_contents;
474 }
465 } 475 }
466 } 476 }
467 } 477 }
468 478
469 bool should_prefetch = static_cast<int>(index) == prefetch_index; 479 bool should_prefetch = static_cast<int>(index) == prefetch_index;
470 // TODO(kochi): Improve calculator suggestion presentation. 480 // TODO(kochi): Improve calculator suggestion presentation.
471 results->suggest_results.push_back(SuggestResult( 481 results->suggest_results.push_back(SuggestResult(
472 base::CollapseWhitespace(suggestion, false), match_type, 482 base::CollapseWhitespace(suggestion, false), match_type,
473 base::CollapseWhitespace(match_contents, false), 483 base::CollapseWhitespace(match_contents, false),
474 match_contents_prefix, annotation, answer_contents, answer_type, 484 match_contents_prefix, annotation, answer_contents, answer_type,
475 suggest_query_params, deletion_url, is_keyword_result, relevance, 485 answer, suggest_query_params, deletion_url, is_keyword_result,
476 relevances != NULL, should_prefetch, trimmed_input)); 486 relevance, relevances != NULL, should_prefetch, trimmed_input));
477 } 487 }
478 } 488 }
479 results->relevances_from_server = relevances != NULL; 489 results->relevances_from_server = relevances != NULL;
480 return true; 490 return true;
481 } 491 }
482 492
483 // static 493 // static
484 void SearchSuggestionParser::GetAnswersImageURLs( 494 void SearchSuggestionParser::GetAnswersImageURLs(
485 const base::DictionaryValue* answer_json, 495 const SuggestionAnswer& answer,
groby-ooo-7-16 2014/10/23 00:46:19 I think this function should move onto SuggestionA
Justin Donnelly 2014/10/23 17:59:37 Yeah, duh, should've thought of that. Done.
486 std::vector<GURL>* urls) { 496 std::vector<GURL>* urls) {
487 DCHECK(answer_json); 497 if(!answer.is_valid())
488
489 const base::ListValue* lines = NULL;
490 if (!answer_json->GetList("l", &lines) || !lines || lines->GetSize() == 0)
491 return; 498 return;
492 499
493 for (base::ListValue::const_iterator iter = lines->begin(); 500 if (answer.first_line().has_image_url())
494 iter != lines->end(); 501 urls->push_back(answer.first_line().image_url());
495 ++iter) { 502 if (answer.second_line().has_image_url())
496 const base::DictionaryValue* line = NULL; 503 urls->push_back(answer.second_line().image_url());
497 if (!(*iter)->GetAsDictionary(&line) || !line)
498 continue;
499
500 std::string image_host_and_path;
501 if (!line->GetString("il.i.d", &image_host_and_path) ||
502 image_host_and_path.empty())
503 continue;
504 // Concatenate scheme and host/path using only ':' as separator. This is
505 // due to the results delivering strings of the form '//host/path', which
506 // is web-speak for "use the enclosing page's scheme", but not a valid path
507 // of an URL.
508 GURL image_url(
509 GURL(std::string(url::kHttpsScheme) + ":" + image_host_and_path));
510 if (image_url.is_valid())
511 urls->push_back(image_url);
512 }
513 } 504 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698