st_tools 0.3.2
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 +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
|