st_tools 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +258 -0
- data/bin/console +14 -0
- data/bin/setup +10 -0
- data/lib/i18n/en.yml +72 -0
- data/lib/i18n/ru.yml +49 -0
- data/lib/modules/fias.rb +57 -0
- data/lib/modules/integer.rb +28 -0
- data/lib/modules/string.rb +105 -0
- data/lib/modules/time.rb +23 -0
- data/lib/st_tools/common.rb +30 -0
- data/lib/st_tools/fias.rb +111 -0
- data/lib/st_tools/human.rb +140 -0
- data/lib/st_tools/progress_bar.rb +73 -0
- data/lib/st_tools/string.rb +170 -0
- data/lib/st_tools/system.rb +38 -0
- data/lib/st_tools/version.rb +3 -0
- data/lib/st_tools.rb +36 -0
- data/test/fias_lib_spec.rb +112 -0
- data/test/human_lib_spec.rb +64 -0
- data/test/progress_bar_lib_spec.rb +18 -0
- data/test/string_lib_spec.rb +99 -0
- data/test/system_lib_spec.rb +25 -0
- metadata +130 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module StTools
|
2
|
+
class Common
|
3
|
+
|
4
|
+
# Функция переводит хеши с несколькими уровнями вложения в плоский хэш, в котором
|
5
|
+
# глубина структуры заменяется ключами, разделенными точкой
|
6
|
+
# Источник: https://gist.github.com/lucabelmondo/4161211
|
7
|
+
#
|
8
|
+
# @param [Hash] hash для перевода ключей в плоский вид, разделенный точками
|
9
|
+
# @return [Hash] Hash вида "key.subkey.subsubkey" => value
|
10
|
+
def self.flatten_hash(hash)
|
11
|
+
result_iter = {}
|
12
|
+
paths = hash.keys.map { |key| [key] }
|
13
|
+
|
14
|
+
until paths.empty?
|
15
|
+
path = paths.shift
|
16
|
+
value = hash
|
17
|
+
path.each { |step| value = value[step] }
|
18
|
+
|
19
|
+
if value.respond_to?(:keys)
|
20
|
+
value.keys.each { |key| paths << path + [key] }
|
21
|
+
else
|
22
|
+
result_iter[path.join(".")] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
result_iter
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module StTools
|
2
|
+
class Fias
|
3
|
+
|
4
|
+
#-------------------------------------------------------------
|
5
|
+
#
|
6
|
+
# Функции получения aoguid адресного объекта
|
7
|
+
#
|
8
|
+
#-------------------------------------------------------------
|
9
|
+
# Функция возвращает aoguid Москвы в системе ФИАС
|
10
|
+
#
|
11
|
+
# @return [String] aoguid г. Москва
|
12
|
+
def self.moscow_aoguid
|
13
|
+
return self.federal_cities['msk']
|
14
|
+
end
|
15
|
+
|
16
|
+
# Функция возвращает aoguid Санкт-Питербурга в системе ФИАС
|
17
|
+
#
|
18
|
+
# @return [String] aoguid г. Санкт-Питербурга
|
19
|
+
def self.spb_aoguid
|
20
|
+
return self.federal_cities['spb']
|
21
|
+
end
|
22
|
+
|
23
|
+
# Функция возвращает aoguid Севастополя в системе ФИАС
|
24
|
+
#
|
25
|
+
# @return [String] aoguid г. Севастополь
|
26
|
+
def self.sevastopol_aoguid
|
27
|
+
return self.federal_cities['svs']
|
28
|
+
end
|
29
|
+
|
30
|
+
# Функция возвращает aoguid Байконура в системе ФИАС
|
31
|
+
#
|
32
|
+
# @return [String] aoguid г. Байконур
|
33
|
+
def self.baikonur_aoguid
|
34
|
+
return self.federal_cities['bai']
|
35
|
+
end
|
36
|
+
|
37
|
+
#-------------------------------------------------------------
|
38
|
+
#
|
39
|
+
# Функции валидации типа адресного объекта
|
40
|
+
#
|
41
|
+
#-------------------------------------------------------------
|
42
|
+
def self.federal?(aoguid)
|
43
|
+
return true if self.federal_cities.values.include?(aoguid)
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.moscow?(aoguid)
|
48
|
+
return true if self.federal_cities['msk'] == aoguid
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [aoguid] aoguid адресного объекта из таблицы addrobj ФИАС
|
53
|
+
# @return [bool] true, если объект - Санкт-Петербург
|
54
|
+
def self.spb?(aoguid)
|
55
|
+
return true if self.federal_cities['spb'] == aoguid
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.sevastopol?(aoguid)
|
60
|
+
return true if self.federal_cities['svs'] == aoguid
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.baikonur?(aoguid)
|
65
|
+
if self.federal_cities['bai'] == aoguid
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
return false
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
#--------------------------------------------------------------
|
73
|
+
#
|
74
|
+
# Функции определения типа переданного значения
|
75
|
+
#
|
76
|
+
#--------------------------------------------------------------
|
77
|
+
def self.uuid?(id)
|
78
|
+
if id.match(/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/i)
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.postalcode?(id)
|
85
|
+
if id.to_s.strip.match(/^\d{6}$/)
|
86
|
+
return true
|
87
|
+
end
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
|
91
|
+
#--------------------------------------------------------------
|
92
|
+
#
|
93
|
+
# Вспомогательные функции
|
94
|
+
#
|
95
|
+
#--------------------------------------------------------------
|
96
|
+
private
|
97
|
+
|
98
|
+
# noinspection RubyClassVariableUsageInspection
|
99
|
+
def self.federal_cities
|
100
|
+
self_federal_cities = Hash.new
|
101
|
+
|
102
|
+
self_federal_cities['msk'] = '0c5b2444-70a0-4932-980c-b4dc0d3f02b5' # Москва
|
103
|
+
self_federal_cities['spb'] = 'c2deb16a-0330-4f05-821f-1d09c93331e6' # Санкт-Петербург
|
104
|
+
self_federal_cities['svs'] = '63ed1a35-4be6-4564-a1ec-0c51f7383314' # Байконур
|
105
|
+
self_federal_cities['bai'] = '6fdecb78-893a-4e3f-a5ba-aa062459463b' # Севастополь
|
106
|
+
|
107
|
+
return self_federal_cities
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module StTools
|
2
|
+
class Human
|
3
|
+
|
4
|
+
|
5
|
+
# Функция возвращает форматированную строку из любого числа с суффиксом тыс., млн. и пр.
|
6
|
+
#
|
7
|
+
# @param [Integer] val значение
|
8
|
+
# @return [String] строка вида "512,4 кило"
|
9
|
+
def self.number(val)
|
10
|
+
# todo: локлаизовать через i18N
|
11
|
+
# noinspection RubyStringKeysInHashInspection
|
12
|
+
arr = {'' => 1000, 'тыс.' => 1000 * 1000, 'млн.' => 1000 * 1000 * 1000,
|
13
|
+
'млрд.' => 1000 * 1000 * 1000 * 1000, 'трлн.' => 1000 * 1000 * 1000 * 1000 * 1000}
|
14
|
+
|
15
|
+
arr.each_pair do |e, s|
|
16
|
+
if val < s
|
17
|
+
if ['', ' тыс.'].include?(e)
|
18
|
+
return "#{(val.to_f / (s / 1000)).round(0)} #{e}"
|
19
|
+
else
|
20
|
+
return "#{(val.to_f / (s / 1000)).round(1)} #{e}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Функция возвращает форматированную строку из любого числа с объемом памяти.
|
27
|
+
#
|
28
|
+
# @param [Integer] val значение в байтах
|
29
|
+
# @return [String] строка вида "512,4 Мбайт"
|
30
|
+
def self.bytes(val)
|
31
|
+
# todo: локлаизовать через i18N
|
32
|
+
# noinspection RubyStringKeysInHashInspection
|
33
|
+
arr = {'байт' => 1024, 'кбайт' => 1024 * 1024, 'Мбайт' => 1024 * 1024 * 1024,
|
34
|
+
'Гбайт' => 1024 * 1024 * 1024 * 1024, 'Тбайт' => 1024 * 1024 * 1024 * 1024 * 1024}
|
35
|
+
|
36
|
+
arr.each_pair do |e, s|
|
37
|
+
if val < s
|
38
|
+
if %w(байт кбайт).include?(e)
|
39
|
+
return "#{(val.to_f / (s / 1024)).round(0)} #{e}"
|
40
|
+
else
|
41
|
+
return "#{(val.to_f / (s / 1024)).round(1)} #{e}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Функция возвращает форматированную строку с объемом памяти, занимаемым текущим процессом (pid).
|
48
|
+
#
|
49
|
+
# @return [String] строка вида "512,4 Мбайт"
|
50
|
+
def self.memory
|
51
|
+
val = ::StTools::System.memory
|
52
|
+
return self.bytes(val)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Функция переводит DateTime в строку на русском или иных языках вида "4 дня 23 часа назад".
|
56
|
+
# Предварительно необходимо вызвать StTools.setup(:ru).
|
57
|
+
#
|
58
|
+
# @param [DateTime] time время и дата
|
59
|
+
# @param [Boolean] ago добавление слова "назад" в конец строки
|
60
|
+
# @return [String] строка вида "3 дня 12 часов" или "3 дня 12 часов назад"
|
61
|
+
def self.ago_in_words(time, ago = true)
|
62
|
+
now = self.to_time(Time.now.strftime('%Y-%m-%d %H:%M:%S UTC'))
|
63
|
+
slf = self.to_time(time.strftime('%Y-%m-%d %H:%M:%S UTC'))
|
64
|
+
secs = (now - slf).to_i
|
65
|
+
return I18n.t('common.ago.very_long') if time.year < 1800
|
66
|
+
return I18n.t('common.ago.just_now') if secs > -1 && secs < 1
|
67
|
+
return '' if secs <= -1
|
68
|
+
pair = self.ago_in_words_pair(secs)
|
69
|
+
pair << I18n.t("common.ago.ago_word") if ago == true
|
70
|
+
pair.join(' ')
|
71
|
+
end
|
72
|
+
|
73
|
+
# Функция переводит DateTime в строку на русском или иных языках. Предварительно необходимо вызвать
|
74
|
+
# StTools.setup(:ru).
|
75
|
+
#
|
76
|
+
# @param [DateTime] time время и дата
|
77
|
+
# @param [Sym] type формат возвращаемого результата
|
78
|
+
# @option :full форматирует дату и время (по умолчанию)
|
79
|
+
# @option :date форматирует только дату
|
80
|
+
# @option :time форматирует только время
|
81
|
+
# @return [String] строка с форматированными датой и временем
|
82
|
+
def self.format_time(time, what, type)
|
83
|
+
if [:full, :date, :time].include?(what) == false
|
84
|
+
warn "WARNING: what ':#{what.to_s}' must be in [:full, :date, :time]. Use ':full' now (at line #{__LINE__} of StTools::#{File.basename(__FILE__)})"
|
85
|
+
what = :full
|
86
|
+
end
|
87
|
+
return I18n.l(time, :format => "#{what.to_s}_#{type.to_s}".to_sym)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def self.ago_in_words_pair(secs)
|
93
|
+
mins = (secs / 60).to_i
|
94
|
+
hours = (mins / 60).to_i
|
95
|
+
days = (hours / 24).to_i
|
96
|
+
years = (days / 365).to_i
|
97
|
+
months = (days / (365/12)).to_i
|
98
|
+
# puts "#{secs}, #{mins}, #{hours}, #{days}, #{months}, #{years}"
|
99
|
+
|
100
|
+
return ago_in_words_one_pair(years, months - (years*12), "year", "month") if (months > 12)
|
101
|
+
return ago_in_words_one_pair(months, days - (months*(365/12)), "month", "day") if (days > 28)
|
102
|
+
return ago_in_words_one_pair(days, hours - (days*24), "day", "hour") if (hours > 24)
|
103
|
+
return ago_in_words_one_pair(hours, mins - (hours*60), "hour", "minute") if (mins > 60)
|
104
|
+
return ago_in_words_one_pair(mins, secs - (mins*60), "minute", "second") if (secs > 60)
|
105
|
+
return [ago_in_words_one_value(secs, "second")]
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.ago_in_words_one_pair(val1, val2, tag1, tag2)
|
109
|
+
return [ago_in_words_one_value(val1, tag1), ago_in_words_one_value(val2, tag2)]
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.ago_in_words_one_value(val, tag)
|
113
|
+
num100 = val % 100
|
114
|
+
num10 = val % 10
|
115
|
+
return val.to_s + " " + I18n.t("common.ago.#{tag}.other") if (num100 >=5 && num100 <= 20)
|
116
|
+
return val.to_s + " " + I18n.t("common.ago.#{tag}.one") if (num10 == 1)
|
117
|
+
return val.to_s + " " + I18n.t("common.ago.#{tag}.two") if ([2, 3, 4].include?(num10))
|
118
|
+
return val.to_s + " " + I18n.t("common.ago.#{tag}.other")
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.to_time(time, form = :local)
|
122
|
+
parts = Date._parse(time, false)
|
123
|
+
return if parts.empty?
|
124
|
+
|
125
|
+
now = Time.now
|
126
|
+
time = Time.new(
|
127
|
+
parts.fetch(:year, now.year),
|
128
|
+
parts.fetch(:mon, now.month),
|
129
|
+
parts.fetch(:mday, now.day),
|
130
|
+
parts.fetch(:hour, 0),
|
131
|
+
parts.fetch(:min, 0),
|
132
|
+
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
|
133
|
+
parts.fetch(:offset, form == :utc ? 0 : nil)
|
134
|
+
)
|
135
|
+
|
136
|
+
form == :utc ? time.utc : time.getlocal
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module StTools
|
2
|
+
class ProgressBar
|
3
|
+
attr_reader :usage, :progress, :executed_at
|
4
|
+
|
5
|
+
# Инициализация прогресс-бара
|
6
|
+
#
|
7
|
+
# @param [Hash] opts параметры настройки прогресс-бара
|
8
|
+
# @option opts [String] :title заголовок прогресс-бара
|
9
|
+
# @option opts [Integer] :max максимальное значение
|
10
|
+
# @option opts [Integer] :progress текущее значение (по умолчанию 0)
|
11
|
+
# @option opts [String] :footer резюмирующая строка. Допускает два шаблона: [memory] и [executed_at]
|
12
|
+
# @option opts [Integer] :step шаг кратно которому реально перерисовывается прогресс-бар
|
13
|
+
# @return [Object] нет
|
14
|
+
def initialize(opts = {})
|
15
|
+
@title = opts[:title] || ''
|
16
|
+
@max = opts[:max] || 100
|
17
|
+
@progress = opts[:progress] || 0
|
18
|
+
@footer = opts[:footer] || ''
|
19
|
+
@step = opts[:step] || 100
|
20
|
+
|
21
|
+
@usage = 1
|
22
|
+
@executed_at = 0
|
23
|
+
@start_at = ::Time.now
|
24
|
+
|
25
|
+
init_progress_bar
|
26
|
+
end
|
27
|
+
|
28
|
+
# Функция устанавливает новое значение прогресс-бара
|
29
|
+
#
|
30
|
+
# @param [Integer] val новое значение прогресс-бара. Если равно max - то вызывается функция вывода футера
|
31
|
+
# @return [Object] нет
|
32
|
+
def progress=(val)
|
33
|
+
return if val > @max
|
34
|
+
return if val == @value
|
35
|
+
return if val % @step != 0 && (@max - val) >= @step
|
36
|
+
|
37
|
+
@progress = val
|
38
|
+
@pbar.progress = val
|
39
|
+
@usage += 1
|
40
|
+
|
41
|
+
if val > @max - 1
|
42
|
+
puts_footer
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
|
49
|
+
def init_progress_bar
|
50
|
+
puts @title if @title != ''
|
51
|
+
|
52
|
+
@pbar = ::ProgressBar.create(:starting_at => 0, :total => @max, :progress_mark => '=',
|
53
|
+
:format => "%a |%B| %E", :throttle_rate => 1, :remainder_mark => '.')
|
54
|
+
end
|
55
|
+
|
56
|
+
def puts_footer
|
57
|
+
@executed_at = (::Time.now - @start_at).to_f
|
58
|
+
|
59
|
+
return if @footer == ''
|
60
|
+
|
61
|
+
@executed_at_txt = @executed_at.to_i
|
62
|
+
@executed_at_txt = @executed_at.round(1).to_s if @executed_at < 60
|
63
|
+
@executed_at_txt = @executed_at.round(5).to_s if @executed_at < 1
|
64
|
+
|
65
|
+
@footer.gsub!(/\[memory\]/i, ::StTools::Human.memory) if @footer.match(/\[memory\]/i)
|
66
|
+
@footer.gsub!(/\[executed_at\]/i, @executed_at_txt) if @footer.match(/\[executed_at\]/i)
|
67
|
+
|
68
|
+
puts @footer
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module StTools
|
2
|
+
class String
|
3
|
+
|
4
|
+
# Функция преобразует текст в транслит
|
5
|
+
#
|
6
|
+
# @param [String] text исходная строка с русскими буквами
|
7
|
+
# @return [String] строка в транслите
|
8
|
+
def self.translit(text)
|
9
|
+
return nil if text.nil?
|
10
|
+
translited = text.tr('абвгдеёзийклмнопрстуфхэыь', 'abvgdeezijklmnoprstufhey\'\'')
|
11
|
+
translited = translited.tr('АБВГДЕЁЗИЙКЛМНОПРСТУФХЭЫЬ', 'ABVGDEEZIJKLMNOPRSTUFHEY\'\'')
|
12
|
+
|
13
|
+
translited = translited.gsub(/[жцчшщъюяЖЦЧШЩЪЮЯ]/, 'ж' => 'zh', 'ц' => 'ts', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch',
|
14
|
+
'ъ' => '', 'ю' => 'ju', 'я' => 'ja',
|
15
|
+
'Ж' => 'Zh', 'Ц' => 'Ts', 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sch',
|
16
|
+
'Ъ' => '', 'Ю' => 'Ju', 'Я' => 'Ja')
|
17
|
+
translited.gsub!('\'', '')
|
18
|
+
return translited
|
19
|
+
end
|
20
|
+
|
21
|
+
# Функция с хорошей производительностью преобразует строку в нижний регистр.
|
22
|
+
# Одновременно буква 'ё' замещается на 'е'
|
23
|
+
#
|
24
|
+
# @param [String] text строка в произвольном регистре
|
25
|
+
# @return [String] строка в нижнем регистре
|
26
|
+
def self.downcase(text)
|
27
|
+
return nil if text.nil?
|
28
|
+
return text.tr('QWERTYUIOPASDFGHJKLZXCVBNMАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ',
|
29
|
+
'qwertyuiopasdfghjklzxcvbnmабвгдеёжзийклмнопрстуфхцчшщъыьэюя').gsub('ё', 'е')
|
30
|
+
end
|
31
|
+
|
32
|
+
# Функция с хорошей производительностью преобразует строку в верхний регистр.
|
33
|
+
# Одновременно буква 'Ё' замещается на 'Е'
|
34
|
+
#
|
35
|
+
# @param [String] text строка в произвольном регистре
|
36
|
+
# @return [String] строка в нижнем регистре
|
37
|
+
def self.upcase(text)
|
38
|
+
return nil if text.nil?
|
39
|
+
return text.tr('qwertyuiopasdfghjklzxcvbnmабвгдеёжзийклмнопрстуфхцчшщъыьэюя',
|
40
|
+
'QWERTYUIOPASDFGHJKLZXCVBNMАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ').gsub('Ё', 'Е')
|
41
|
+
end
|
42
|
+
|
43
|
+
# Функция заменяет в исходной строке символы английские, но похожие
|
44
|
+
# на русские на соответстующие русские. То есть это похоже на ситуацию,
|
45
|
+
# когда Google меняет случайно написанное английскими буквами на русское
|
46
|
+
#
|
47
|
+
# @param [String] text текст со смесью английских и русских букв
|
48
|
+
# @return [String] текст только с русскими буквами
|
49
|
+
def self.delat(text)
|
50
|
+
return nil if text.nil?
|
51
|
+
return text.tr('ёЁEeHCcTOoPpAHKXxBM', 'еЕЕеНСсТОоРрАНКХхВМ')
|
52
|
+
end
|
53
|
+
|
54
|
+
# Данную функцию рекомендуется вызывать каждый раз, как юзер вводит текст,
|
55
|
+
# для того, чтобы:
|
56
|
+
# - убрать букву 'ё'
|
57
|
+
# - перевести строку в нижний регистр
|
58
|
+
# - заменить случайно введенные английские буквы на русские
|
59
|
+
# - убрать лидирующие и завершающие пробелы
|
60
|
+
# - оставить в строке только один пробел между слов
|
61
|
+
#
|
62
|
+
# @param [String] text строка, введенная пользователям
|
63
|
+
# @return [String] строка без 'ё', в нижнем регистре, без английских букв
|
64
|
+
def self.normalize(text)
|
65
|
+
return nil if text.nil?
|
66
|
+
return self.downcase(self.delat(text)).strip.gsub(/\s{1,100}/, ' ')
|
67
|
+
end
|
68
|
+
|
69
|
+
# Для целей выдачи информации клиенту в неполном объеме, данная функция позволяет
|
70
|
+
# закрыть часть строки звездочками. При этом число звездочек в строке определеяется
|
71
|
+
# ее длиной. Чем строка дилинее - тем больше в ней звездочек
|
72
|
+
#
|
73
|
+
# @param [String] text строка, которую необходимо закрыть звездочками
|
74
|
+
# @return [String] строка, часть символов которой заменена звездочками
|
75
|
+
def self.hide_text(text)
|
76
|
+
return nil if text.nil?
|
77
|
+
len = text.length - 3
|
78
|
+
0.upto((len/4).to_i) do
|
79
|
+
pos = rand(len)
|
80
|
+
text[pos,1] = '*'
|
81
|
+
end
|
82
|
+
return text
|
83
|
+
end
|
84
|
+
|
85
|
+
# Функция аналогична обычной функции split, однако дополнительно может выполнять следующие действия
|
86
|
+
# - strip каждого элемента
|
87
|
+
# - normalize соответсвующей функцией (#normalize)
|
88
|
+
# - сортировка в прямом порядке
|
89
|
+
# - удаление дубликотов
|
90
|
+
#
|
91
|
+
# @param [String] text исходная строка
|
92
|
+
# @param [String] separator сепаратор (по умолчанию нет - необходимо явное указание)
|
93
|
+
# @param [Hash] opts опции преобразования
|
94
|
+
# @option opts [Boolean] :normalize - применить к каждому элементу массива функцию #normalize
|
95
|
+
# @option opts [Boolean] :sort - сортировать выходной массив
|
96
|
+
# @option opts [Boolean] :uniq - удалить из массива дубликаты
|
97
|
+
# @return [Array] массив элементов из строки
|
98
|
+
def self.split(text, separator, opts = {})
|
99
|
+
return nil if text.nil?
|
100
|
+
out = text.split(separator)
|
101
|
+
out.map! { |x| x.strip }
|
102
|
+
out.map! { |x| self.normalize(x) } if opts[:normalize]
|
103
|
+
out.uniq! if opts[:uniq]
|
104
|
+
out.sort! if opts[:sort]
|
105
|
+
|
106
|
+
return out
|
107
|
+
rescue
|
108
|
+
return []
|
109
|
+
end
|
110
|
+
|
111
|
+
# Функция возвращает полный массив Array [1, 4, 5, 6, 7, 456] для строк вида '1, 4, 5-7, 456'.
|
112
|
+
# Дополнительно осуществляется:
|
113
|
+
# - сортировка в прямом порядке
|
114
|
+
# - удаление дубликотов
|
115
|
+
#
|
116
|
+
# @param [String] text исходная строка
|
117
|
+
# @param [Hash] opts
|
118
|
+
# @option opts [Boolean] :sort - сортировать выходной массив
|
119
|
+
# @option opts [Boolean] :uniq - удалить из массива дубликаты
|
120
|
+
# @return [Array] массив чисел
|
121
|
+
def self.to_range(text, opts = {})
|
122
|
+
return nil if text.nil?
|
123
|
+
out = Array.new
|
124
|
+
|
125
|
+
tmp = self.split(text, ',')
|
126
|
+
tmp.each do |one|
|
127
|
+
if one.match(/\-/)
|
128
|
+
d = one.split(/\-/)
|
129
|
+
out += Range.new(d.first.to_i, d.last.to_i).to_a
|
130
|
+
else
|
131
|
+
out << one.to_i
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
out.uniq! if opts[:uniq]
|
136
|
+
out.sort! if opts[:sort]
|
137
|
+
|
138
|
+
return out
|
139
|
+
end
|
140
|
+
|
141
|
+
# Функция делает заглавной первую букву в словах, разделенных пробелами или тире.
|
142
|
+
# Подключеие ActiveSupport не требуется
|
143
|
+
#
|
144
|
+
# @param [String] text исходная строка
|
145
|
+
# @return [String] строка с первыми заглавными буквами
|
146
|
+
def self.caps(text)
|
147
|
+
return nil if text.nil?
|
148
|
+
str = self.downcase(text).split(/[\-\s]/).map { |x| self.upcase(x[0]) + x[1,x.length] }
|
149
|
+
str = str.join(' ')
|
150
|
+
for i in 0..str.length
|
151
|
+
str[i] = '-' if (text.to_s[i,1] == '-')
|
152
|
+
end
|
153
|
+
|
154
|
+
return str
|
155
|
+
rescue
|
156
|
+
return text
|
157
|
+
end
|
158
|
+
|
159
|
+
# Функция формирует boolean значение из строки
|
160
|
+
#
|
161
|
+
# @param [String] text исходная строка, содержащая 'true/false', 'on/off', '1/0'
|
162
|
+
# @return [Boolean] true или false
|
163
|
+
def self.to_bool(text)
|
164
|
+
return false if text.nil?
|
165
|
+
return true if ['true', 'on', '1'].include?(self.downcase(text.to_s))
|
166
|
+
false
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module StTools
|
2
|
+
class System
|
3
|
+
|
4
|
+
def self.memory
|
5
|
+
return `ps -o rss -p #{Process::pid}`.chomp.split("\n").last.strip.to_i
|
6
|
+
end
|
7
|
+
|
8
|
+
# Возвращает размер терминала - число строк в терминале или число символов в строке
|
9
|
+
#
|
10
|
+
# @param [Sym] size возвращаемый параметр
|
11
|
+
# @option size [Sym] :width вернуть число символов в строке терминала
|
12
|
+
# @option size [Sym] :height верунть число строк в терминале
|
13
|
+
# @return [Integer] число символов в строке терминала или число строк в терминале
|
14
|
+
def self.screen(size)
|
15
|
+
sizes = `stty size 2>/dev/null`.chomp.split(' ')
|
16
|
+
raise if sizes.count == 0
|
17
|
+
raise if sizes.first.match(/\d/).nil?
|
18
|
+
return sizes.last.to_i if size == :width
|
19
|
+
return sizes.first.to_i if size == :height
|
20
|
+
rescue
|
21
|
+
return (size == :width) ? 100 : 25
|
22
|
+
end
|
23
|
+
|
24
|
+
# Метод возвращает имя запускаемого скрипта (без пути), независимо от того, откуда данный метод вызывается.
|
25
|
+
#
|
26
|
+
# @return [String] имя скрипта или nil в случае ошибки
|
27
|
+
def self.exename
|
28
|
+
res = `ps -ef | grep #{Process.pid}`
|
29
|
+
lines = res.split(/[\r\n]/)
|
30
|
+
lines.each do |one|
|
31
|
+
res = one unless one.match(/grep/)
|
32
|
+
end
|
33
|
+
res = res.split(' ').last
|
34
|
+
File.basename(res)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
data/lib/st_tools.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(__dir__, *%w[.. lib])
|
2
|
+
|
3
|
+
require "st_tools/version"
|
4
|
+
|
5
|
+
require 'ruby-progressbar'
|
6
|
+
|
7
|
+
module StTools
|
8
|
+
require 'st_tools/common'
|
9
|
+
require 'st_tools/system'
|
10
|
+
require 'st_tools/human'
|
11
|
+
require 'st_tools/fias'
|
12
|
+
require 'st_tools/string'
|
13
|
+
require 'st_tools/progress_bar'
|
14
|
+
|
15
|
+
require 'modules/string'
|
16
|
+
require 'modules/integer'
|
17
|
+
require 'modules/time'
|
18
|
+
require 'modules/fias'
|
19
|
+
|
20
|
+
class Setup
|
21
|
+
|
22
|
+
def self.setup(locale)
|
23
|
+
self.setup_locale(locale)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.setup_locale(locale)
|
27
|
+
require 'i18n'
|
28
|
+
::I18n.load_path += Dir[File.dirname(File.expand_path(__FILE__)) + '/i18n/**/*.yml']
|
29
|
+
::I18n.backend.load_translations
|
30
|
+
::I18n.available_locales = [:ru, :en]
|
31
|
+
::I18n.locale = locale
|
32
|
+
::I18n.default_locale = locale
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|