class GoogleWebTranslate::API
interface to the google web translation api
Constants
- DEFAULT_DT
- DEFAULT_RATE_LIMIT
- DEFAULT_TOKEN_TTL
- TRANSLATE_PATH
- URL_MAIN
Public Class Methods
new(options = {})
click to toggle source
# File lib/google_web_translate/api.rb, line 7 def initialize(options = {}) @dt = options[:dt] || DEFAULT_DT @token_ttl = options[:token_ttl] || DEFAULT_TOKEN_TTL @debug = options[:debug] @http_client = options[:http_client] || HTTPClient.new(options) @rate_limit = options[:rate_limit] || DEFAULT_RATE_LIMIT end
Public Instance Methods
languages()
click to toggle source
# File lib/google_web_translate/api.rb, line 20 def languages @languages ||= begin html = fetch_main html.scan(/\['(\w{2})','(\w{2})'\]/).flatten.uniq.sort end end
translate(string, from, to)
click to toggle source
# File lib/google_web_translate/api.rb, line 15 def translate(string, from, to) data = fetch_translation(string, from, to) Result.new(data) end
Private Instance Methods
compile_js(html)
click to toggle source
# File lib/google_web_translate/api.rb, line 79 def compile_js(html) desktop_module_js = munge_module(fetch_desktop_module(html)) window_js = File.read(File.join(__dir__, '..', 'js', 'window.js')) js = window_js + desktop_module_js # File.write('generated.js', js) if debug? @tk_function = detect_tk_function(desktop_module_js) debug("detected tk function: #{@tk_function}") ExecJS.compile(js) end
debug(msg)
click to toggle source
# File lib/google_web_translate/api.rb, line 141 def debug(msg) puts msg if debug? end
debug?()
click to toggle source
# File lib/google_web_translate/api.rb, line 145 def debug? @debug end
detect_tk_function(js)
click to toggle source
# File lib/google_web_translate/api.rb, line 89 def detect_tk_function(js) js =~ /translate_tts.*,\s*(\w+)\(.*\)/ Regexp.last_match(1) || 'vq' end
extract_tkk(html)
click to toggle source
# File lib/google_web_translate/api.rb, line 114 def extract_tkk(html) raise 'TKK not found' unless html =~ /TKK=eval\('(.*?)'\);/ tkk_code = Regexp.last_match(1) # tkk_code = Translatomatic::StringEscaping.unescape(tkk_code) tkk_code = StringEscaping.unescape(tkk_code) debug("tkk code unescaped: #{tkk_code}") tkk = ExecJS.eval(tkk_code) # tkk = context.call(nil) debug("evaluated tkk: #{tkk}") tkk end
fetch_desktop_module(html)
click to toggle source
# File lib/google_web_translate/api.rb, line 66 def fetch_desktop_module(html) html =~ /([^="]*desktop_module_main.js)/ url = Regexp.last_match(1) raise 'unable to find desktop module' unless url fetch_url_body(url) end
fetch_main(options = {})
click to toggle source
# File lib/google_web_translate/api.rb, line 61 def fetch_main(options = {}) @html = nil if options[:no_cache] @html ||= fetch_url_body(URL_MAIN) end
fetch_translation(string, from, to)
click to toggle source
# File lib/google_web_translate/api.rb, line 35 def fetch_translation(string, from, to) debug('getting next server') server = ServerList.next_server(@rate_limit) debug("using server #{server}") json = fetch_url_body(translate_url(server, string, from, to)) # File.write("response.json", json) if debug? debug("response: #{json}") JSON.parse(json) end
fetch_url_body(url)
click to toggle source
# File lib/google_web_translate/api.rb, line 49 def fetch_url_body(url) uri = URI.parse(url) uri = URI.join(URL_MAIN, url) if uri.relative? debug("fetch #{uri}") response = fetch_url_response(uri) response.body end
fetch_url_response(url)
click to toggle source
# File lib/google_web_translate/api.rb, line 45 def fetch_url_response(url) @http_client.get(url.to_s) end
munge_module(js)
click to toggle source
# File lib/google_web_translate/api.rb, line 73 def munge_module(js) js.gsub(/((?:var\s+)?\w+\s*=\s*\w+\.createElement.*?;)/) do |_i| 'return "";' end end
tk(string)
click to toggle source
# File lib/google_web_translate/api.rb, line 104 def tk(string) update_token unless valid_token? tk = @js_context.call('generateToken', @tk_function, @tkk, string) (tk.split('=') || [])[1] end
tk_js()
click to toggle source
# File lib/google_web_translate/api.rb, line 110 def tk_js File.read(File.join(__dir__, 'google_web.js')) end
translate_url(server, string, from, to)
click to toggle source
# File lib/google_web_translate/api.rb, line 126 def translate_url(server, string, from, to) tk = tk(string) debug("tk: #{tk}") query = { sl: from, tl: to, ie: 'UTF-8', oe: 'UTF-8', q: string, dt: @dt, tk: tk, # not sure what these are for client: 't', hl: 'en', otf: 1, ssel: 4, tsel: 6, kc: 5 } url = "https://#{server.host}" + TRANSLATE_PATH uri = URI.parse(url) uri.query = URI.encode_www_form(query) uri.to_s end
update_token()
click to toggle source
# File lib/google_web_translate/api.rb, line 94 def update_token # download main page html = fetch_main(no_cache: true) # extract tkk from html @tkk = extract_tkk(html) # compile desktop module javascript @js_context = compile_js(html) @token_updated_at = Time.now end
valid_token?()
click to toggle source
# File lib/google_web_translate/api.rb, line 57 def valid_token? @token_updated_at && Time.now - @token_updated_at < @token_ttl end