class Gares::Search

Search Gares-en-mouvement for a station name

Constants

GARES_LIST_URL

This is the stations database from captaintrain.com

Attributes

query[R]

Public Class Methods

find(str) click to toggle source
# File lib/gares/search.rb, line 35
def self.find(str)
  trie.find_prefix(str)
end
new(query, field = :name) click to toggle source

Initialize a new Station search with the specified query

search = Gares::Search.new("Aix")

Gares::Search is lazy loaded, meaning that unless you access the stations attribute, no remote query is made.

Search can by done via the :name or :sncf_id field given in parameter. Defaults to the :name field.

# File lib/gares/search.rb, line 23
def initialize(query, field = :name)
  fail UnsupportedIndex unless %w(name sncf_id).include?(field.to_s)
  @query = query
  @by = field
end

Private Class Methods

load_data() click to toggle source

Read stations.csv file into memory into a Trie data structure

# File lib/gares/search.rb, line 64
def self.load_data
  if @@trie.nil?
    raw_data ||= SmarterCSV.process(open(GARES_LIST_URL), col_sep: ";")
    trie = Trie.new

    raw_data.each do |raw_station|
      next if raw_station[:name].nil? || raw_station[:sncf_id].nil? || raw_station[:uic].nil?
      trie.insert(simplify(raw_station[:name]), raw_station)
      trie.insert(simplify(raw_station[:sncf_id]), raw_station)
    end

    @@trie = trie
  end
end
simplify(str) click to toggle source
# File lib/gares/search.rb, line 54
def self.simplify(str)
  str.to_ascii.downcase
    .gsub(/\bgare\ssncf\b/, "")
    .gsub(/\bsaint\b/, "st")
    .gsub(/[^a-z]/, " ")
    .gsub(/\s+/, " ")
    .strip
end

Public Instance Methods

stations() click to toggle source

Returns an array of Gares::Station objects in order to easily search result yielded. If the query was an exact match, a single element array will be returned.

# File lib/gares/search.rb, line 31
def stations
  @stations ||= (exact_match? ? parse_station : parse_stations)
end

Private Instance Methods

exact_match?() click to toggle source
# File lib/gares/search.rb, line 84
def exact_match?
  result.count == 1
end
parse_station() click to toggle source
# File lib/gares/search.rb, line 80
def parse_station
  [result.first]
end
result() click to toggle source
# File lib/gares/search.rb, line 41
def result
  query = self.class.simplify(@query)
  if @raw_results.nil?
    @raw_results = self.class.find(query).values
    # try removing keywords one by one if nothing found
    while @raw_results.empty? && !query.split(" ").empty?
      query = query.split(" ")[0..-2].join(" ")
      @raw_results = @raw_results.empty? ? self.class.find(query).values : @raw_results
    end
  end
  @result ||= @raw_results.map { |raw_station| Gares::Station.new(raw_station) }
end