-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLiRuCounterRecognizer.rb
executable file
·136 lines (108 loc) · 4.05 KB
/
LiRuCounterRecognizer.rb
1
2
3
4
5
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
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env ruby
require 'json'
require 'digest/md5'
require 'chunky_png'
require 'httpclient'
require 'domain_name'
require 'mini_magick'
require 'socksify'
require 'sinatra'
require 'sinatra/config_file'
require File.dirname(__FILE__) + '/recognizer.rb'
config_file 'config.yml'
if settings.httpclient_socks_proxy[:enabled]
# Proxy debuging
if settings.httpclient_socks_proxy[:debug].equal? 'true'
Socksify.debug = true
end
# Proxy
TCPSocket.socks_server = settings.httpclient_socks_proxy[:host]
TCPSocket.socks_port = settings.httpclient_socks_proxy[:port]
puts "Proxy enabled! [#{settings.httpclient_socks_proxy[:host]}:#{settings.httpclient_socks_proxy[:port]}]"
end
recognizer = Recognizer.new
ua = HTTPClient.new
ERRORS = {
1 => 'Invalid domain name',
2 => 'Counter downloading error',
3 => 'Counter is empty'
}.freeze
get '/' do
'Main page! '
end
def write_file(path, data, option = 'wb')
gif_counter = File.new(path, option)
gif_counter.write(data)
gif_counter.close
end
# Процедура загрузки и конвертирования изображения
def download(ua, domain, empty_counter_md5, domain_md5, db_path)
# Загружаем изображение
begin
current_counter_data = ua.get_content(
URI.escape("http://counter.yadro.ru/logo;#{domain}?29.6")
)
rescue
return { error_code: 2 }
end
# Проверяем контрольную сумму пустого счётчика
if Digest::MD5.hexdigest(current_counter_data) == empty_counter_md5
return { error_code: 3 }
end
# Сохраняем счётчик
gif_file_path = db_path + '/' + domain_md5 + '.gif'
write_file(gif_file_path, current_counter_data)
# Конвертируем счётчик в PNG
png_file_path = db_path + '/' + domain_md5 + '.png'
image = MiniMagick::Image.open(gif_file_path)
image.format 'png'
image.write(png_file_path)
png_counter = ChunkyPNG::Image.from_file(png_file_path)
{ error_code: 0, image: png_counter }
end
get '/get/:domain' do
content_type :json
# Проверяем корректность домена и возвращаем ошибку если необходимо
if DomainName(params[:domain]).canonical?
target_domain = params[:domain]
else
return { error_code: 1, error_message: ERRORS[1] }.to_json
end
target_domain_hash = Digest::MD5.hexdigest(target_domain).to_s
db_file_path = settings.db[:path] + '/' + target_domain_hash + '.json'
# Если запись в кеше присутствует
if File.exist?(db_file_path)
# Получаем текущее время и время последней модификации файла
current_time = Time.now
existing_file_mtime = File.mtime(db_file_path)
# Рассчитываем время жизни файла
file_lifetime = (current_time - existing_file_mtime).to_i
# Если файл не устарел возвращаем информацию из кеша
if file_lifetime <= settings.downloader[:time_to_live]
# Читаем данные из кеша
cache_data = File.new(db_file_path, 'r').read
return cache_data
end
end
# Загружаем и конвертируем изображение
download_result = download(ua, target_domain,
settings.downloader[:empty_counter_md5],
target_domain_hash, settings.db[:path]
)
# Если загрузка неудалась возвращаем ошибку
if download_result[:error_code].zero?
counter_info = recognizer.get_info(download_result[:image])
end
# Создаём хеш описывающий результат обработки
response = {
error_code: download_result[:error_code],
error_message: ERRORS[download_result[:error_code]],
cached: true,
info: counter_info
}
# Сохраняем ответ в кеш
write_file(db_file_path, response.to_json, 'w')
# Модифицируем ответ перед выдачей
response[:cached] = false
response.to_json
end