google_web_translate 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +24 -24
- data/google-web-translate.gemspec +31 -31
- data/lib/google_web_translate.rb +7 -6
- data/lib/google_web_translate/api.rb +151 -142
- data/lib/google_web_translate/server.rb +13 -0
- data/lib/google_web_translate/server_list.rb +135 -146
- data/lib/google_web_translate/version.rb +3 -3
- data/lib/js/window.js +0 -4
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7ffd5385d2f29f6faa1034ea2c9c0f458b063b7aa7b769789352727027e3167d
|
4
|
+
data.tar.gz: 3809d0162a684d6d452a0b0a83a07fb5fa36ecfbbf9f3967768aa457ffb6a421
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f901517261b1887923faaaa7ceaf8ea418bab7e7e71cda5b506e947d810bdd51790c44b81f15c1fc5e760f4fff954ef71a93bb5aaca273dd4e4fa0c46ffc1202
|
7
|
+
data.tar.gz: d9fd55c8cf55eede4671fda0d228bf89022a5babc418f8f9891afa1ac9844b27e460c437a1040ed46a7ce946b3165f3b657e5fa6b1b58132dde2f22dc1b90073
|
data/Gemfile
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
|
-
|
5
|
-
def gem_installed?(args)
|
6
|
-
name, *version = *args
|
7
|
-
dependency = Gem::Dependency.new(name, *version)
|
8
|
-
specs = dependency.matching_specs
|
9
|
-
specs && !specs.empty?
|
10
|
-
end
|
11
|
-
|
12
|
-
def optional_gem(*args)
|
13
|
-
gem(*args) if gem_installed?(args)
|
14
|
-
end
|
15
|
-
|
16
|
-
# database adapters
|
17
|
-
optional_gem 'therubyracer', platform: :ruby
|
18
|
-
optional_gem 'therubyrhino', platform: :jruby
|
19
|
-
|
20
|
-
# optional c extensions
|
21
|
-
optional_gem 'concurrent-ruby-ext', platform: :ruby
|
22
|
-
|
23
|
-
# Specify your gem's dependencies in google-web-translate.gemspec
|
24
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
|
+
|
5
|
+
def gem_installed?(args)
|
6
|
+
name, *version = *args
|
7
|
+
dependency = Gem::Dependency.new(name, *version)
|
8
|
+
specs = dependency.matching_specs
|
9
|
+
specs && !specs.empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def optional_gem(*args)
|
13
|
+
gem(*args) if gem_installed?(args)
|
14
|
+
end
|
15
|
+
|
16
|
+
# database adapters
|
17
|
+
optional_gem 'therubyracer', platform: :ruby
|
18
|
+
optional_gem 'therubyrhino', platform: :jruby
|
19
|
+
|
20
|
+
# optional c extensions
|
21
|
+
optional_gem 'concurrent-ruby-ext', platform: :ruby
|
22
|
+
|
23
|
+
# Specify your gem's dependencies in google-web-translate.gemspec
|
24
|
+
gemspec
|
@@ -1,31 +1,31 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'google_web_translate/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = 'google_web_translate'
|
8
|
-
spec.version = GoogleWebTranslate::VERSION
|
9
|
-
spec.authors = ['Andrew']
|
10
|
-
spec.email = ['sobakasu@gmail.com']
|
11
|
-
|
12
|
-
spec.summary = 'Text translation using the google web interface'
|
13
|
-
spec.homepage = 'https://github.com/sobakasu/google_web_translate'
|
14
|
-
spec.license = 'MIT'
|
15
|
-
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
-
f.match(%r{^(test|spec|features)/})
|
17
|
-
end
|
18
|
-
spec.bindir = 'bin'
|
19
|
-
spec.executables = %w[google_web_translate]
|
20
|
-
spec.require_paths = ['lib']
|
21
|
-
|
22
|
-
spec.add_development_dependency 'bundler', '~> 1.16'
|
23
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
|
-
spec.add_development_dependency 'simplecov'
|
26
|
-
spec.add_development_dependency 'webmock'
|
27
|
-
|
28
|
-
spec.add_dependency 'concurrent-ruby'
|
29
|
-
spec.add_dependency 'execjs'
|
30
|
-
spec.add_dependency 'thor'
|
31
|
-
end
|
1
|
+
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'google_web_translate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'google_web_translate'
|
8
|
+
spec.version = GoogleWebTranslate::VERSION
|
9
|
+
spec.authors = ['Andrew']
|
10
|
+
spec.email = ['sobakasu@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Text translation using the google web interface'
|
13
|
+
spec.homepage = 'https://github.com/sobakasu/google_web_translate'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.executables = %w[google_web_translate]
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
|
+
spec.add_development_dependency 'simplecov'
|
26
|
+
spec.add_development_dependency 'webmock'
|
27
|
+
|
28
|
+
spec.add_dependency 'concurrent-ruby'
|
29
|
+
spec.add_dependency 'execjs'
|
30
|
+
spec.add_dependency 'thor'
|
31
|
+
end
|
data/lib/google_web_translate.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
require 'google_web_translate/version.rb'
|
2
|
-
require 'google_web_translate/
|
3
|
-
require 'google_web_translate/
|
4
|
-
require 'google_web_translate/
|
5
|
-
require 'google_web_translate/
|
6
|
-
require 'google_web_translate/
|
1
|
+
require 'google_web_translate/version.rb'
|
2
|
+
require 'google_web_translate/server.rb'
|
3
|
+
require 'google_web_translate/server_list.rb'
|
4
|
+
require 'google_web_translate/string_escaping.rb'
|
5
|
+
require 'google_web_translate/http_client.rb'
|
6
|
+
require 'google_web_translate/result.rb'
|
7
|
+
require 'google_web_translate/api.rb'
|
@@ -1,142 +1,151 @@
|
|
1
|
-
require 'execjs'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module GoogleWebTranslate
|
5
|
-
# interface to the google web translation api
|
6
|
-
class API
|
7
|
-
def initialize(options = {})
|
8
|
-
@dt = options[:dt] || DEFAULT_DT
|
9
|
-
@token_ttl = options[:token_ttl] || DEFAULT_TOKEN_TTL
|
10
|
-
@debug = options[:debug]
|
11
|
-
@http_client = options[:http_client] || HTTPClient.new(options)
|
12
|
-
@rate_limit = options[:rate_limit] || DEFAULT_RATE_LIMIT
|
13
|
-
end
|
14
|
-
|
15
|
-
def translate(string, from, to)
|
16
|
-
data = fetch_translation(string, from, to)
|
17
|
-
Result.new(data)
|
18
|
-
end
|
19
|
-
|
20
|
-
def languages
|
21
|
-
@languages ||= begin
|
22
|
-
html = fetch_main
|
23
|
-
html.scan(/\['(\w{2})','(\w{2})'\]/).flatten.uniq.sort
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
URL_MAIN = 'https://translate.google.com'.freeze
|
30
|
-
TRANSLATE_PATH = '/translate_a/single'.freeze
|
31
|
-
DEFAULT_DT = %w[at bd ex ld md qca rw rm ss t].freeze
|
32
|
-
DEFAULT_TOKEN_TTL = 3600
|
33
|
-
DEFAULT_RATE_LIMIT = 5
|
34
|
-
|
35
|
-
def fetch_translation(string, from, to)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
debug("
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
1
|
+
require 'execjs'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module GoogleWebTranslate
|
5
|
+
# interface to the google web translation api
|
6
|
+
class API
|
7
|
+
def initialize(options = {})
|
8
|
+
@dt = options[:dt] || DEFAULT_DT
|
9
|
+
@token_ttl = options[:token_ttl] || DEFAULT_TOKEN_TTL
|
10
|
+
@debug = options[:debug]
|
11
|
+
@http_client = options[:http_client] || HTTPClient.new(options)
|
12
|
+
@rate_limit = options[:rate_limit] || DEFAULT_RATE_LIMIT
|
13
|
+
end
|
14
|
+
|
15
|
+
def translate(string, from, to)
|
16
|
+
data = fetch_translation(string, from, to)
|
17
|
+
Result.new(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def languages
|
21
|
+
@languages ||= begin
|
22
|
+
html = fetch_main
|
23
|
+
html.scan(/\['(\w{2})','(\w{2})'\]/).flatten.uniq.sort
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
URL_MAIN = 'https://translate.google.com'.freeze
|
30
|
+
TRANSLATE_PATH = '/translate_a/single'.freeze
|
31
|
+
DEFAULT_DT = %w[at bd ex ld md qca rw rm ss t].freeze
|
32
|
+
DEFAULT_TOKEN_TTL = 3600
|
33
|
+
DEFAULT_RATE_LIMIT = 5
|
34
|
+
|
35
|
+
def fetch_translation(string, from, to)
|
36
|
+
debug('getting next server')
|
37
|
+
server = ServerList.next_server(@rate_limit)
|
38
|
+
debug("using server #{server}")
|
39
|
+
json = fetch_url_body(translate_url(server, string, from, to))
|
40
|
+
# File.write("response.json", json) if debug?
|
41
|
+
debug("response: #{json}")
|
42
|
+
JSON.parse(json)
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_url_response(url)
|
46
|
+
@http_client.get(url.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_url_body(url)
|
50
|
+
uri = URI.parse(url)
|
51
|
+
uri = URI.join(URL_MAIN, url) if uri.relative?
|
52
|
+
debug("fetch #{uri}")
|
53
|
+
response = fetch_url_response(uri)
|
54
|
+
response.body
|
55
|
+
end
|
56
|
+
|
57
|
+
def valid_token?
|
58
|
+
@token_updated_at && Time.now - @token_updated_at < @token_ttl
|
59
|
+
end
|
60
|
+
|
61
|
+
def fetch_main(options = {})
|
62
|
+
@html = nil if options[:no_cache]
|
63
|
+
@html ||= fetch_url_body(URL_MAIN)
|
64
|
+
end
|
65
|
+
|
66
|
+
def fetch_desktop_module(html)
|
67
|
+
html =~ /([^="]*desktop_module_main.js)/
|
68
|
+
url = Regexp.last_match(1)
|
69
|
+
raise 'unable to find desktop module' unless url
|
70
|
+
fetch_url_body(url)
|
71
|
+
end
|
72
|
+
|
73
|
+
def munge_module(js)
|
74
|
+
js.gsub(/((?:var\s+)?\w+\s*=\s*\w+\.createElement.*?;)/) do |_i|
|
75
|
+
'return "";'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def compile_js(html)
|
80
|
+
desktop_module_js = munge_module(fetch_desktop_module(html))
|
81
|
+
window_js = File.read(File.join(__dir__, '..', 'js', 'window.js'))
|
82
|
+
js = window_js + desktop_module_js
|
83
|
+
# File.write('generated.js', js) if debug?
|
84
|
+
@tk_function = detect_tk_function(desktop_module_js)
|
85
|
+
debug("detected tk function: #{@tk_function}")
|
86
|
+
ExecJS.compile(js)
|
87
|
+
end
|
88
|
+
|
89
|
+
def detect_tk_function(js)
|
90
|
+
js =~ /translate_tts.*,\s*(\w+)\(.*\)/
|
91
|
+
Regexp.last_match(1) || 'vq'
|
92
|
+
end
|
93
|
+
|
94
|
+
def update_token
|
95
|
+
# download main page
|
96
|
+
html = fetch_main(no_cache: true)
|
97
|
+
# extract tkk from html
|
98
|
+
@tkk = extract_tkk(html)
|
99
|
+
# compile desktop module javascript
|
100
|
+
@js_context = compile_js(html)
|
101
|
+
@token_updated_at = Time.now
|
102
|
+
end
|
103
|
+
|
104
|
+
def tk(string)
|
105
|
+
update_token unless valid_token?
|
106
|
+
@js_context.call('setWindowProperty', 'TKK', @tkk)
|
107
|
+
# tk = @js_context.call("wq", string)
|
108
|
+
tk = @js_context.call(@tk_function, string)
|
109
|
+
(tk.split('=') || [])[1]
|
110
|
+
end
|
111
|
+
|
112
|
+
def tk_js
|
113
|
+
File.read(File.join(__dir__, 'google_web.js'))
|
114
|
+
end
|
115
|
+
|
116
|
+
def extract_tkk(html)
|
117
|
+
raise 'TKK not found' unless html =~ /TKK=eval\('(.*?)'\);/
|
118
|
+
tkk_code = Regexp.last_match(1)
|
119
|
+
# tkk_code = Translatomatic::StringEscaping.unescape(tkk_code)
|
120
|
+
tkk_code = StringEscaping.unescape(tkk_code)
|
121
|
+
debug("tkk code unescaped: #{tkk_code}")
|
122
|
+
tkk = ExecJS.eval(tkk_code)
|
123
|
+
# tkk = context.call(nil)
|
124
|
+
debug("evaluated tkk: #{tkk}")
|
125
|
+
tkk
|
126
|
+
end
|
127
|
+
|
128
|
+
def translate_url(server, string, from, to)
|
129
|
+
tk = tk(string)
|
130
|
+
debug("tk: #{tk}")
|
131
|
+
query = {
|
132
|
+
sl: from, tl: to, ie: 'UTF-8', oe: 'UTF-8',
|
133
|
+
q: string, dt: @dt, tk: tk,
|
134
|
+
# not sure what these are for
|
135
|
+
client: 't', hl: 'en', otf: 1, ssel: 4, tsel: 6, kc: 5
|
136
|
+
}
|
137
|
+
url = "https://#{server.host}" + TRANSLATE_PATH
|
138
|
+
uri = URI.parse(url)
|
139
|
+
uri.query = URI.encode_www_form(query)
|
140
|
+
uri.to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
def debug(msg)
|
144
|
+
puts msg if debug?
|
145
|
+
end
|
146
|
+
|
147
|
+
def debug?
|
148
|
+
@debug
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module GoogleWebTranslate
|
2
|
+
# @private
|
3
|
+
SERVER_ATTRIBUTES = %i[host ip resolved_at last_used_at
|
4
|
+
counter available].freeze
|
5
|
+
|
6
|
+
Server = Struct.new(*SERVER_ATTRIBUTES) do
|
7
|
+
def to_json(*args)
|
8
|
+
result = {}
|
9
|
+
each_pair { |key, value| result[key] = value }
|
10
|
+
result.to_json(args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,146 +1,135 @@
|
|
1
|
-
require 'concurrent'
|
2
|
-
require 'resolv'
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module GoogleWebTranslate
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
server_list
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
server
|
113
|
-
server
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
resolver = Resolv::DNS.new
|
137
|
-
resolver.timeouts = 5
|
138
|
-
resolver
|
139
|
-
end
|
140
|
-
|
141
|
-
def resolve_ip(host)
|
142
|
-
resolver.getaddress(host).to_s
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
1
|
+
require 'concurrent'
|
2
|
+
require 'resolv'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module GoogleWebTranslate
|
6
|
+
|
7
|
+
class ServerList
|
8
|
+
class << self
|
9
|
+
def servers
|
10
|
+
update_servers if @servers.nil?
|
11
|
+
@servers.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
def next_server(rate_limit = nil)
|
15
|
+
@mutex ||= Mutex.new
|
16
|
+
@mutex.synchronize do
|
17
|
+
@counter ||= 0
|
18
|
+
@counter += 1
|
19
|
+
|
20
|
+
list = servers.sort_by { |i| i.counter || 0 }
|
21
|
+
server = list[0]
|
22
|
+
server.counter = @counter
|
23
|
+
sleep(rate_limit_delay(server, rate_limit))
|
24
|
+
server.last_used_at = Time.now
|
25
|
+
server
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
MAX_TTL = 86_400
|
32
|
+
|
33
|
+
def rate_limit_delay(server, rate_limit)
|
34
|
+
return 0 unless rate_limit && server.last_used_at
|
35
|
+
delay = rate_limit - (Time.now - server.last_used_at)
|
36
|
+
delay < 0 || ENV['TEST'] ? 0 : delay
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_servers
|
40
|
+
server_list = read_server_data
|
41
|
+
pool = Concurrent::CachedThreadPool.new
|
42
|
+
# puts "updating #{server_list.length} servers"
|
43
|
+
server_list.each do |server|
|
44
|
+
pool.post { update_server(server) }
|
45
|
+
end
|
46
|
+
|
47
|
+
pool.shutdown
|
48
|
+
pool.wait_for_termination
|
49
|
+
@servers = unique_servers(server_list)
|
50
|
+
# puts "#{@servers.length} unique servers found"
|
51
|
+
save_server_data(server_list)
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_server(server)
|
55
|
+
now = Time.now.to_i
|
56
|
+
if server.resolved_at.nil? ||
|
57
|
+
now - server.resolved_at > MAX_TTL #|| !server.available
|
58
|
+
server.resolved_at = now
|
59
|
+
server.ip = resolve_ip(server.host)
|
60
|
+
end
|
61
|
+
server.available = true
|
62
|
+
rescue Resolv::ResolvError
|
63
|
+
# puts "server #{server.host} is unavailable: #{e}"
|
64
|
+
server.available = false
|
65
|
+
end
|
66
|
+
|
67
|
+
def data_dir
|
68
|
+
File.join(__dir__, '..', '..', 'data')
|
69
|
+
end
|
70
|
+
|
71
|
+
def server_data_path
|
72
|
+
File.join(data_dir, 'server_data.txt')
|
73
|
+
end
|
74
|
+
|
75
|
+
def url_list_path
|
76
|
+
File.join(data_dir, 'urls.txt')
|
77
|
+
end
|
78
|
+
|
79
|
+
def hostnames
|
80
|
+
names = []
|
81
|
+
lines = File.read(url_list_path).split(/[\r\n]+/)
|
82
|
+
lines.each do |host|
|
83
|
+
next unless host && !host.empty?
|
84
|
+
names << "translate.#{host}"
|
85
|
+
end
|
86
|
+
names
|
87
|
+
end
|
88
|
+
|
89
|
+
def unique_servers(list)
|
90
|
+
server_by_ip = {}
|
91
|
+
list.each do |server|
|
92
|
+
next unless server.available
|
93
|
+
server_by_ip[server.ip] = server
|
94
|
+
end
|
95
|
+
server_by_ip.values
|
96
|
+
end
|
97
|
+
|
98
|
+
def initial_data
|
99
|
+
hostnames.collect do |host|
|
100
|
+
server = Server.new
|
101
|
+
server.host = host
|
102
|
+
server
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def read_server_data
|
107
|
+
return initial_data unless File.exist?(server_data_path)
|
108
|
+
data = JSON.parse(File.read(server_data_path))
|
109
|
+
server_list = []
|
110
|
+
data.each do |entry|
|
111
|
+
attributes = SERVER_ATTRIBUTES.collect { |i| entry[i.to_s] }
|
112
|
+
server = Server.new(*attributes)
|
113
|
+
next unless server.host && !server.host.empty?
|
114
|
+
server.counter = 0
|
115
|
+
server_list << server
|
116
|
+
end
|
117
|
+
server_list
|
118
|
+
end
|
119
|
+
|
120
|
+
def save_server_data(servers)
|
121
|
+
File.write(server_data_path, servers.to_json)
|
122
|
+
end
|
123
|
+
|
124
|
+
def resolver
|
125
|
+
resolver = Resolv::DNS.new
|
126
|
+
resolver.timeouts = 5
|
127
|
+
resolver
|
128
|
+
end
|
129
|
+
|
130
|
+
def resolve_ip(host)
|
131
|
+
resolver.getaddress(host).to_s
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module GoogleWebTranslate
|
2
|
-
VERSION = '0.2.
|
3
|
-
end
|
1
|
+
module GoogleWebTranslate
|
2
|
+
VERSION = '0.2.4'.freeze
|
3
|
+
end
|
data/lib/js/window.js
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_web_translate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- lib/google_web_translate/cli.rb
|
150
150
|
- lib/google_web_translate/http_client.rb
|
151
151
|
- lib/google_web_translate/result.rb
|
152
|
+
- lib/google_web_translate/server.rb
|
152
153
|
- lib/google_web_translate/server_list.rb
|
153
154
|
- lib/google_web_translate/string_escaping.rb
|
154
155
|
- lib/google_web_translate/version.rb
|
@@ -173,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
174
|
version: '0'
|
174
175
|
requirements: []
|
175
176
|
rubyforge_project:
|
176
|
-
rubygems_version: 2.
|
177
|
+
rubygems_version: 2.7.4
|
177
178
|
signing_key:
|
178
179
|
specification_version: 4
|
179
180
|
summary: Text translation using the google web interface
|