diff --git a/Gemfile.lock b/Gemfile.lock index fd9777c..0da190e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -517,7 +517,7 @@ GEM redis (~> 3.0, >= 3.0.4) responders (2.1.0) railties (>= 4.2.0, < 5) - riddle (2.1.0) + riddle (2.4.0) role_block_haml (0.2.4) haml (~> 4.0) route_downcaser (1.1.4) @@ -674,4 +674,4 @@ DEPENDENCIES whenever BUNDLED WITH - 1.16.1 + 1.16.6 diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index d647751..4a590a7 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,10 +1,8 @@ +# frozen_string_literal: true + class SearchController < ApplicationController before_action :define_hub_ids - def pub_types - [ Recipe, Post, Blog, Page, Interview ] - end - def autocomplete @squery = params[:term].to_s.strip to_search = Riddle::Query.escape @squery @@ -12,7 +10,7 @@ def autocomplete res = ThinkingSphinx.search( to_search, star: true, - classes: pub_types, + classes: SearchService::PUBLICATION_TYPES, field_weights: { title: 10, content: 5 @@ -24,14 +22,10 @@ def autocomplete end def search - @squery = params[:squery].to_s.strip - to_search = Riddle::Query.escape @squery + search_service = SearchService.call(params[:squery], @hub_ids, params) - @pubs = if @hub_ids.blank? - ThinkingSphinx.search(to_search, star: true, classes: pub_types, sql: { include: :hub }).pagination(params) - else - ThinkingSphinx.search(to_search, star: true, classes: pub_types, sql: { include: :hub }, with: { hub_id: @hub_ids }).pagination(params) - end + @pubs = search_service.search_result + @multiple_keyboard_layouts = search_service.multiple_keyboard_layouts @search_results_size = @pubs.size @search_results_count = @pubs.count @@ -39,6 +33,12 @@ def search render layout: 'ok2/layouts/application', template: 'ok2/search/index' end + def multiple_keyboard_layouts? + @multiple_keyboard_layouts + end + + helper_method :multiple_keyboard_layouts? + private def define_hub_ids @@ -54,5 +54,4 @@ def define_hub_ids @hub_ids << post_hub.self_and_descendants.select(:id).map(&:id).uniq end end - end diff --git a/app/services/search_service.rb b/app/services/search_service.rb new file mode 100644 index 0000000..da55a1c --- /dev/null +++ b/app/services/search_service.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module SearchService + PUBLICATION_TYPES = [ + Recipe, Post, Blog, Page, Interview + ].freeze + + LOWERCASE_DICTIONARY = { + 'q' => 'й', 'w' => 'ц', 'e' => 'у', 'r' => 'к', + 't' => 'е', 'y' => 'н', 'u' => 'г', 'i' => 'ш', + 'o' => 'щ', 'p' => 'з', 'a' => 'ф', 's' => 'ы', + 'd' => 'в', 'f' => 'а', 'g' => 'п', 'h' => 'р', + 'j' => 'о', 'k' => 'л', 'l' => 'д', ';' => 'ж', + "'" => 'э', 'z' => 'я', 'x' => 'ч', 'c' => 'с', + 'v' => 'м', 'b' => 'и', 'n' => 'т', 'm' => 'ь', + ',' => 'б', '.' => 'ю' + }.freeze + + UPPERCASE_DICTIONARY = { + 'Q' => 'Й', 'W' => 'Ц', 'E' => 'У', 'R' => 'К', + 'T' => 'Е', 'Y' => 'Н', 'U' => 'Г', 'I' => 'Ш', + 'O' => 'Щ', 'P' => 'З', 'A' => 'Ф', 'S' => 'Ы', + 'D' => 'В', 'F' => 'А', 'G' => 'П', 'H' => 'Р', + 'J' => 'О', 'K' => 'Л', 'L' => 'Д', ':' => 'Ж', + '"' => 'Э', 'Z' => 'Я', 'X' => 'Ч', 'С' => 'С', + 'V' => 'М', 'B' => 'И', 'N' => 'Т', 'M' => 'Ь', + '<' => 'Б', '>' => 'Ю' + }.freeze + + def call(query, hub_ids, params) + query = query.to_s.strip + riddle_query = Riddle::Query.escape(query) + + search_result = if hub_ids.blank? + ThinkingSphinx.search(riddle_query, star: true, classes: PUBLICATION_TYPES, sql: { include: :hub }).pagination(params) + else + ThinkingSphinx.search(riddle_query, star: true, classes: PUBLICATION_TYPES, sql: { include: :hub }, with: { hub_id: hub_ids }).pagination(params) + end + + if search_result.blank? + OpenStruct.new(search_result: search_by_multiple_keyboard_layouts(query, params), multiple_keyboard_layouts: true) + else + OpenStruct.new(search_result: search_result, multiple_keyboard_layouts: false) + end + end + + module_function :call + + def convert_to_another_keyboard_layout(query) + search_query = [] + + query.each_char do |char| + search_query.push(dictionary[char]) + end + + search_query.join + end + + module_function :convert_to_another_keyboard_layout + + private + + def search_by_multiple_keyboard_layouts(query, params) + ThinkingSphinx.search(Riddle::Query.escape(convert_to_another_keyboard_layout(query)), star: true, classes: PUBLICATION_TYPES, sql: { include: :hub }).pagination(params) + end + + module_function :search_by_multiple_keyboard_layouts + + def dictionary + LOWERCASE_DICTIONARY.merge(UPPERCASE_DICTIONARY) + end + + module_function :dictionary +end diff --git a/app/views/ok2/search/index.html.slim b/app/views/ok2/search/index.html.slim index 76fb6f9..96cf834 100644 --- a/app/views/ok2/search/index.html.slim +++ b/app/views/ok2/search/index.html.slim @@ -8,7 +8,10 @@ h1.tac.fs30.fwn.i.pt20.pb15.ffg(style='color:#024e9f') | Поиск: ' - = @squery + - if multiple_keyboard_layouts? && @pubs.present? + = SearchService.convert_to_another_keyboard_layout(params[:squery].to_s.strip) + - else + = params[:squery] -# MAIN CONTENT - if @pubs.blank?