Module: SearchEngines

Extended by:
Enumerable
Defined in:
lib/dsl.rb

Overview

This module contains the DSL for the search engine configuration.

It also serves as the front object for DRb connectors. It’s a big module because it has a lot of responsibilities.

Author:

  • Shreyan Jain

Defined Under Namespace

Classes: ResultMapper, SearchEngineBuilder

Constant Summary collapse

ISO3166 =

A hash of all the standard ISO 3166-1 Market Codes. Includes their human-readable names, mapped to their ISO 3166-1 alpha-2 codes.

{
"Argentina (Spanish)" => "es-AR",
"Australia (English)" => "en-AU",
"Austria (German)" => "de-AT",
"Belgium (Dutch)" => "nl-BE",
"Belgium (French)" => "fr-BE",
"Brazil (Portuguese)" => "pt-BR",
"Canada (English)" => "en-CA",
"Canada (French)" => "fr-CA",
"Chile (Spanish)" => "es-CL",
"Denmark (Danish)" => "da-DK",
"Finland (Finnish)" => "fi-FI",
"France (French)" => "fr-FR",
"Germany (German)" => "de-DE",
"Hong Kong (Traditional Chinese)" => "zh-HK",
"India (English)" => "en-IN",
"Indonesia (English)" => "en-ID",
"Italy (Italian)" => "it-IT",
"Japan (Japanese)" => "ja-JP",
"Korea (Korean)" => "ko-KR",
"Malaysia (English)" => "en-MY",
"Mexico (Spanish)" => "es-MX",
"Netherlands (Dutch)" => "nl-NL",
"New Zealand (English)" => "en-NZ",
"Norway (Norwegian)" => "no-NO",
"People's Republic of China (Chinese)" => "zh-CN",
"Poland (Polish)" => "pl-PL",
"Portugal (Portuguese)" => "pt-PT",
"Philippines (English)" => "en-PH",
"Russia (Russian)" => "ru-RU",
"Saudi Arabia (Arabic)" => "ar-SA",
"South Africa (English)" => "en-ZA",
"Spain (Spanish)" => "es-ES",
"Sweden (Swedish)" => "sv-SE",
"Switzerland (French)" => "fr-CH",
"Switzerland (German)" => "de-CH",
"Taiwan (Traditional Chinese)" => "zh-TW",
"Turkey (Turkish)" => "tr-TR",
"United Kingdom (English)" => "en-GB",
"United States (English)" => "en-US",
"United States (Spanish)" => "es-US",
  }
.freeze

Class Method Summary collapse

Class Method Details

.[](engine_name) ⇒ Array<Symbol, Proc>

Returns An array. The first element is the human-friendly name of the engine. The second element is a proc that takes a query builder and returns an array of search results.

Returns:

  • (Array<Symbol, Proc>)

    An array. The first element is the human-friendly name of the engine. The second element is a proc that takes a query builder and returns an array of search results.



67
68
69
# File 'lib/dsl.rb', line 67

def self.[](engine_name)
  @engines[engine_name.downcase.to_sym]
end

.add(engine_name, &block) ⇒ Object

Adds a search engine to the list of available engines.

Examples:

Adding the Brave Search Engine’s API

SearchEngines.add :Brave do
  config :api_key
  base_uri 'https://api.search.brave.com/'
  endpoint '/res/v1/web/search'
  format :json
  headers "X-Subscription-Token": config.api_key
  query do |builder|
    {
      q: CGI.escape(builder.query),
      ui_lang: builder.market,
      safesearch: builder.safesearch ? 'strict' : 'moderate',
      offset: builder.offset,
      count: builder.count
    }
  end
  results 'web', 'results' do |i|
    url i['url']
    title i['title']
    snippet i['description']
  end
end

Adding the Bing Search Engine’s API

SearchEngines.add :Bing do
  config :api_key
  base_uri 'https://api.bing.microsoft.com/'
  endpoint '/v7.0/search'
  format :json
  headers "Ocp-Apim-Subscription-Key": config.api_key
  query do |builder|
    {
      q: CGI.escape(builder.query),
      mkt: builder.market,
      SafeSearch: builder.safesearch ? 'strict' : 'moderate',
      offset: builder.offset,
      count: builder.count
      }
  end
  results 'webPages', 'value' do |i|
    url i['url']
    title i['name']
    snippet i['snippet']
  end
end

Parameters:

  • engine_name (Symbol)

    The name of the engine.

  • block (Proc)

    A block of code representing the search engine configuration.

See Also:



60
61
62
63
64
# File 'lib/dsl.rb', line 60

def self.add(engine_name, &block)
  engine = Class.new(SearchEngineBuilder)
  engine.tap { _1.engine_name = engine_name }.module_exec(&block)
  @engines[engine_name.downcase.to_sym] = [engine_name, engine.new.method(:search).to_proc]
end

.each(&block) ⇒ Object



84
85
86
# File 'lib/dsl.rb', line 84

def self.each(&block)
  @engines.each(&block)
end

.enginesHash<Symbol, Array<Symbol, Proc>>

Returns the engines hash.

Returns:



95
96
97
# File 'lib/dsl.rb', line 95

def self.engines
  @engines
end

.LanguagesHash<String, String>

A hash of all the standard ISO 3166-1 Market Codes. Includes their human-readable names, mapped to their ISO 3166-1 alpha-2 codes.

Returns:

See Also:



51
52
53
# File 'lib/langhash.rb', line 51

def SearchEngines.Languages
  return SearchEngines::ISO3166
end

.load_engines(engine_name_list) ⇒ Object

Loads the search engines specified in the configuration, relying on file naming conventions.



15
16
17
18
19
# File 'lib/engines.rb', line 15

def SearchEngines.load_engines(engine_name_list)
  engine_name_list.each do |engine_name|
    require_relative "search_engines/#{engine_name.downcase}"
  end
end

.search_with(name, query) ⇒ Array<Result>

Searches for a specific query using the specified search engine. The query should be a QueryBuilder object. This is in order to store all the different parameters of the search in one place. That way, the query the search API recieves should be fit exactly to its specifications, to enable easy SafeSearch, choice of language/market, pagination, etc.

Parameters:

  • name (String, #to_sym)

    The name of the search engine.

  • query (QueryBuilder)

    The search query.

Returns:

  • (Array<Result>)

    An array of search results (depends on the search engine).



80
81
82
# File 'lib/dsl.rb', line 80

def self.search_with(name, query)
  engines[name.to_sym][1].call(query)
end