class Smartdict::Drivers::LingvoYandexDriver
The translation driver for Google Translate service.
DISCLAIMER: It’s was written when I had one hand broken. Refactoring costs a lot of movements so that I’ve left it as it was. I’m gonna refactor it soon. – Sergey Potapov
TODO:
* Refactor
Constants
- HOST
Host of Lingvo service.
- USER_AGENT
Pretend being Firefox :)
- WORD_CLASSES
Mapping for word classes. Default is “other”
Public Instance Methods
escape(str)
click to toggle source
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 134 def escape(str) CGI.escape(str) end
get_response()
click to toggle source
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 117 def get_response http = Net::HTTP.new(HOST, 80) request = Net::HTTP::Get.new(http_path, { "User-Agent" => USER_AGENT }) http.request(request).read_body end
grep_meanings(html_element)
click to toggle source
TODO: refactor
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 69 def grep_meanings(html_element) acronym = html_element.css("acronym").first return unless acronym ru_word_class = acronym["title"] word_class = WORD_CLASSES[ru_word_class] translations = [] html_element.css("ul > li").each do |tr| # a text line with translations separated by commas line = "" # use strong tag as an anchor strong = tr.css("strong").first if strong && strong.text =~ /\d+|[а-я]+\)/ node = strong while(node = node.next_sibling) if node.text? || node.name == "a" text = node.text line << text unless text =~ /\(|\)/ elsif ["em", "acronym"].include? node.name next else break end end end translations += words_from_line(line) end # sometimes there is only one meaning if translations.empty? if a_tag = html_element.css("span > a").first line = a_tag.text elsif span = html_element.css("span").first line = span.text elsif i_tag = html_element.xpath("i[2]") line = i_tag.text else return nil end translations = words_from_line(line) end self.translated[word_class] = translations.uniq end
http_path()
click to toggle source
@return [String] http path for request to translate word.
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 124 def http_path phrase = case [from_lang, to_lang] when ["en", "ru"] then "en-ru" when ["ru", "en"] then "ru-en" else raise Smartdict::TranslationNotFound end "/#{escape(word)}/#{phrase}/" end
translate()
click to toggle source
TODO: refactor
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 43 def translate doc = Nokogiri::HTML(get_response) if main = doc.css("div.b-translation__article > ul > li#I").first else main = doc.css("div.b-translation__article").first end raise Smartdict::TranslationNotFound unless main # Fetch transcription self.transcription = doc.css("span.b-translation__tr").first.try(:text) self.translated = {} if main.xpath("./i/acronym").any? grep_meanings(main) else main.xpath("./ul/li").each do |li| grep_meanings(li) end end end
Private Instance Methods
words_from_line(line)
click to toggle source
# File lib/smartdict/drivers/lingvo_yandex_driver.rb, line 141 def words_from_line(line) line.split(/,|;/).map(&:strip).reject(&:empty?) end