cli_application 0.1.4 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42d3b23f523ec6e2a71aec78781c946599743010
4
- data.tar.gz: 278b38b045459d7b3bd2ebda1490e48ad2546004
3
+ metadata.gz: 3ba78168735c942c873ef29654d0e1c9c8d73a81
4
+ data.tar.gz: 76dbb97ca5ca031783e2fa207b2c3d0f49b92ba9
5
5
  SHA512:
6
- metadata.gz: abedb19ca01a4c4eda33948a2028dbb706d4912d7e4607d2bd2221938e4e1be9292c5315cea15de4ca64567bbf3e89983cd3f096fa94c740462c8b42cbe5e181
7
- data.tar.gz: 56c5b38a063b9b2b777b24ce957b68af7c12810d5ba0baf366eb117f1e2819c8f18dac44b33924f9737767705bc2034df1ab32845a1148d1f50192eab797acc9
6
+ metadata.gz: 143517fb5880d225cdc28ae474e3e4543ff8a6708a4f48b90fb352c363ba80c37c33af67d35a8957ee3bea57946e3eaed1a7e233dc3cc17431ea403249755943
7
+ data.tar.gz: 481c7078e467fd2dccd06d0a742c491084b05e147273346a83b022ce590eaee0ad7d01985e3976d7bd35816ca15a43c73017b5ddb6ebc0af530f648ef104f4a9
data/README.md CHANGED
@@ -467,7 +467,7 @@ end
467
467
  Запустим приложение, посомтрим на результат
468
468
 
469
469
  ```text
470
- #<Offer id: 10, category: 1, name: "Игрушка десткая", description: "Эта игрушка непременно понравится...", ...
470
+ #<Offer id: 10, category: 1, name: "Игрушка детская", description: "Эта игрушка непременно понравится...", ...
471
471
  ```
472
472
 
473
473
  Таким образом, буквально в несколько строк мы можем работать с базами данных в CLI-приложении, так же, как в привычном
@@ -478,52 +478,5 @@ Rails-окружении.
478
478
  _См. /test/examples/7_
479
479
 
480
480
  Иногда нужно отправлять различные нотификации из скрипта. Для этого классе CliApplication есть почтовый дивжок mail.
481
- Попробуем использовать его
481
+ Детальное описание его работы с примерами приведено [здесь](/examples/admin_mailer/README.md).
482
482
 
483
- Сначала пропишем в конфиге параметры подключения к почтовой системе. Имя конфигуарции - `cli/mail`.
484
-
485
- ```yaml
486
- cli:
487
- timezone: "Moscow"
488
-
489
- mail:
490
- enable: true
491
- from: 'Admin <admin@test-mail.ru>'
492
- host: test-mail.ru
493
- port: 25
494
- footer: '<br><br>--------------<br>Your gem <b>cli_application</b>'
495
- ```
496
-
497
- Допустимые ключи:
498
- * `enable` - если true, то допускается отправка сообщений. Через эту опцию можно запретить отправку
499
- * `from` - адрес почты, с которой будет отправлено сообщение
500
- * `host` - SMPT-сервер. Пока имеется ограничение - использование должно быть без пароля
501
- * `port` - IP-порт почтового сервера
502
- * `footer` - Подпись сообщения
503
-
504
- Затем отправим письмо.
505
-
506
- ```ruby
507
- def main
508
- mail.quick_send('stan@test-mail.ru', 'Stan', 'Тестовый заголовок', 'Hellow, world')
509
- 0
510
- end
511
- ```
512
-
513
- В итоге получим.
514
-
515
- ```html
516
- Hellow, world
517
-
518
- --------------
519
- Your gem <b>cli_application</b>
520
- ```
521
-
522
-
523
- ## Contributing
524
-
525
- 1. Fork it ( https://github.com/[my-github-username]/cli_application/fork )
526
- 2. Create your feature branch (`git checkout -b my-new-feature`)
527
- 3. Commit your changes (`git commit -am 'Add some feature'`)
528
- 4. Push to the branch (`git push origin my-new-feature`)
529
- 5. Create a new Pull Request
@@ -4,6 +4,7 @@ require "cli_application/version"
4
4
  require 'st_tools'
5
5
  require 'cli_application/includes'
6
6
 
7
+ require 'rubygems'
7
8
  require 'active_support/time'
8
9
  require 'mysql2'
9
10
  require 'pg'
@@ -11,9 +12,18 @@ require 'sqlite3'
11
12
  require 'active_record'
12
13
  require 'ostruct'
13
14
  require 'net/smtp'
15
+ require 'htmlentities'
16
+ require "base64"
14
17
 
15
18
 
16
19
  module CliApplication # :nodoc:
20
+ require 'cli_application/mail_lib/message'
21
+ require 'cli_application/mail_lib/base'
22
+ require 'cli_application/mail_lib/error'
23
+ require 'cli_application/mail_lib/smtp'
24
+ require 'cli_application/mail_lib/sendmail'
25
+ require 'cli_application/mail_lib/log'
26
+
17
27
  require 'cli_application/json_struct'
18
28
  require 'cli_application/config'
19
29
  require 'cli_application/databases'
@@ -46,7 +46,7 @@ module CliApplication
46
46
  @config = ::CliApplication::Config.new(@folders)
47
47
 
48
48
  @databases = ::CliApplication::Databases.new(config.cli.databases)
49
- @mail = ::CliApplication::Mail.new(config.cli.mail)
49
+ @mail = ::CliApplication::Mail.new(config.cli.mail, @folders)
50
50
 
51
51
  @footer = nil
52
52
 
@@ -248,6 +248,12 @@ module CliApplication
248
248
  end
249
249
  end
250
250
 
251
+ def reserved_methods
252
+ out = ['argv', 'folders', 'config', 'mail', 'executed_at', 'version', 'description', 'footer', 'databases']
253
+ out += ['help', 'run']
254
+ out.sort
255
+ end
256
+
251
257
 
252
258
  private
253
259
 
@@ -84,6 +84,8 @@ module CliApplication
84
84
 
85
85
  # Метод выводит подсказку по аргументам командной строки
86
86
  def help
87
+ return if @full.empty?
88
+
87
89
  puts
88
90
  puts "Параметры приложения:"
89
91
 
@@ -2,77 +2,50 @@
2
2
  # может быть использован для отсылки критических сообщений
3
3
 
4
4
  module CliApplication
5
- class Mail
5
+ class Mail # :nodoc:
6
6
 
7
7
  # Инициализация методов, позволяющих рассылать письма адимнистраторам
8
8
  # системы
9
- def initialize(config)
10
- @config = config
11
- if !@config.nil? && @config.enable
12
- @is_valid = true
13
- else
14
- @is_valid = false
9
+ def self.new(config, folders)
10
+ res = self.check(config)
11
+
12
+ case res[:delivery_method]
13
+ when :log
14
+ ::CliApplication::MailLib::Log.new(config, folders)
15
+ when :smtp
16
+ ::CliApplication::MailLib::SMTP.new(config, folders)
17
+ when :sendmail
18
+ ::CliApplication::MailLib::Sendmail.new(config, folders)
19
+ else
20
+ ::CliApplication::MailLib::Error.new(config, folders)
15
21
  end
16
22
  end
17
23
 
18
- # Метод показывает готовность подсистемы отсылки почты администратору
19
- # @return [Boolean] true, если разрешено отправлять письма администратору
20
- def valid?
21
- @is_valid
24
+ def self.check(config)
25
+ methods = ['log', 'sendmail', 'smtp']
26
+
27
+ return self.set_valid_state(false, 'Отсутствует секция mail') if config.nil?
28
+ return self.set_valid_state(false, 'Отсутствует параметр enable в секции mail') if config.enable.nil?
29
+ return self.set_valid_state(false, 'Отсутствует параметр from в секции mail') if config.from.nil?
30
+ return self.set_valid_state(false, 'Параметр from в секции mail не должен быть пустым') if config.from.strip == ''
31
+ warn "Внимание: передача почтовых сообщений отключена" unless config.enable
32
+ return self.set_valid_state(false, "Метод доставки должен быть один из: #{methods.inspect}") unless methods.include?(config.delivery_method.to_s)
33
+
34
+ res = Hash.new
35
+ res[:valid] = true
36
+ res[:delivery_method] = config.delivery_method.to_sym
37
+ res[:error_msg] = ''
38
+ res
22
39
  end
23
40
 
24
- # Функция отправляет сообщение по электронной почте
25
- # @param [String] to электронная почта лица, которому отправляется сообщение
26
- # @param [String] name имя клиента, которому отправляется сообщение
27
- # @param [String] title заголовок письма
28
- # @param [String] body текст письма
29
- # @return [Boolean] true, если письмо отправлено
30
- def quick_send(to, name, title, body)
31
- return false unless valid?
32
-
33
- to_email = (name.nil? || name == '') ? to : "#{name} <#{to}>"
34
- body_full = (@config.footer.nil? || @config.footer == '') ? body : (body+@config.footer)
35
-
36
- begin
37
- send_message(to_email, title, body_full)
38
- true
39
- rescue Errno::ECONNREFUSED
40
- puts "Почтовый сервер не найден, выводим почтовое сообщение в консоль"
41
- puts "From: #{@config.from.inspect}"
42
- puts "To: #{to_email.inspect}"
43
- puts "Title: #{title.inspect}"
44
- puts "Body: #{(body_full[0,256] + '...').inspect}"
45
- false
46
- rescue Exception => e
47
- puts "Ошибка отправки письма: #{e.message}"
48
- false
49
- end
41
+ def self.set_valid_state(state, error_msg)
42
+ res = Hash.new
43
+ res[:valid] = false
44
+ res[:delivery_method] = :error
45
+ res[:error_msg] = error_msg
46
+ res
50
47
  end
51
48
 
52
- def send_message(to, title, body)
53
- msgstr = <<MESSAGE_END
54
- From: #{@config.from}
55
- To: #{to}
56
- Subject: #{title}
57
- Date: #{::Time.zone.now.to_formatted_s(:rfc822) }
58
- MIME-Version: 1.0
59
- Content-type: text/html
60
-
61
- #{body}
62
- MESSAGE_END
63
-
64
- Net::SMTP.start(host, port) do |smtp|
65
- smtp.send_message msgstr, @config.from, to
66
- end
67
- end
68
-
69
- def host
70
- @config.host || 'none'
71
- end
72
-
73
- def port
74
- @config.port || 0
75
- end
76
49
 
77
50
  end
78
51
  end
@@ -0,0 +1,142 @@
1
+ # CliApplication::MailLib::Base - базовый класс валидации конфига почты
2
+
3
+ module CliApplication
4
+ module MailLib
5
+ class Base # :nodoc:
6
+ attr_reader :delivery_method
7
+ attr_reader :config_fail_message
8
+
9
+ def initialize(config, folders) # :nodoc:
10
+ @config = config
11
+ @folders = folders
12
+ end
13
+
14
+ # Метод возвращает true, если подсистема отсылки почтовых сообщений настроена корректна
15
+ # и готова к рассылке сообщений
16
+ #
17
+ # @return [Boolean] true - если подсистема почта настроена корректно
18
+ def valid?
19
+ @is_valid
20
+ end
21
+
22
+ # Метод является заглушкой функции, которая должна быть переписана в дочерних классах
23
+ # ::Log, ::Error, ::Smpt, ::Sendmail
24
+ #
25
+ # @param [String] электронная почта лица, которому отправляется сообщение, или массив адресов
26
+ # @param [String] name имя клиента, которому отправляется сообщение
27
+ # @param [String] title заголовок письма
28
+ # @param [String] body текст письма
29
+ # @return [Boolean] true, если письмо отправлено
30
+ def simple_send(to, name, title, body)
31
+ warn "Необходимо переопределить функцию отправки электронной почты (simple_send)"
32
+ warn "Обратитесь к разработчику данного скрипта"
33
+ end
34
+
35
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Log
36
+ #
37
+ # @return [String] пустая строка
38
+ def log_filename
39
+ ''
40
+ end
41
+
42
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
43
+ #
44
+ # @return [String] пустая строка
45
+ def address
46
+ ''
47
+ end
48
+
49
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
50
+ #
51
+ # @return [String] пустая строка
52
+ def domain
53
+ ''
54
+ end
55
+
56
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
57
+ #
58
+ # @return [String] пустая строка
59
+ def port
60
+ ''
61
+ end
62
+
63
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
64
+ #
65
+ # @return [String] пустая строка
66
+ def user_name
67
+ ''
68
+ end
69
+
70
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
71
+ #
72
+ # @return [Boolean] необходимость использовать SSL/TLS
73
+ def tls?
74
+ false
75
+ end
76
+
77
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
78
+ #
79
+ # @return [Boolean] необходимость использовать SSL/TLS
80
+ def smpt_log?
81
+ false
82
+ end
83
+
84
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
85
+ #
86
+ # @return [String] пустая строка
87
+ def authentication
88
+ ''
89
+ end
90
+
91
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Smtp
92
+ #
93
+ # @return [String] пустая строка
94
+ def password
95
+ ''
96
+ end
97
+
98
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Sendmail
99
+ #
100
+ # @return [String] пустая строка
101
+ def sendmail_location
102
+ ''
103
+ end
104
+
105
+ # Заглушка на случай вызова данной функции из класса иного, чем CliApplication::MailLib::Sendmail
106
+ #
107
+ # @return [String] пустая строка
108
+ def sendmail_arguments
109
+ ''
110
+ end
111
+
112
+
113
+ private
114
+
115
+
116
+
117
+ def set_check_config_state(state, message) # :nodoc:
118
+ @is_valid = state
119
+ @config_fail_message = message
120
+ state
121
+ end
122
+
123
+ def build_rfc822_name(to, name) # :nodoc:
124
+ return to if name.nil? || name == ''
125
+ "#{name} <#{to}>"
126
+ end
127
+
128
+ def processing_to(to, name, message) # :nodoc:
129
+ if to.is_a?(::Array)
130
+ # Несколько адресов
131
+ to.each do |one|
132
+ message.add_to(one, '')
133
+ end
134
+ else
135
+ # Один адрес
136
+ message.add_to(to, name)
137
+ end
138
+ end
139
+
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,45 @@
1
+ # CliApplication::MailLib::Log - класс хранения почты в файлы
2
+
3
+ module CliApplication
4
+ module MailLib
5
+ class Error < ::CliApplication::MailLib::Base
6
+
7
+ def initialize(config, folders) # :nodoc:
8
+ @delivery_method = :error
9
+ super(config, folders)
10
+ @is_valid = false
11
+
12
+ check_config
13
+ end
14
+
15
+ # Функция всегда возвращает false
16
+ #
17
+ # @param [String] to электронная почта лица, которому отправляется сообщение, или массив адресов
18
+ # @param [String] name имя клиента, которому отправляется сообщение
19
+ # @param [String] title заголовок письма
20
+ # @param [String] body текст письма
21
+ # @return [Boolean] false
22
+ def simple_send(to, name, title, body)
23
+ false
24
+ end
25
+
26
+
27
+ private
28
+
29
+
30
+
31
+ def check_config # :nodoc:
32
+ methods = ['log', 'sendmail', 'smtp']
33
+
34
+ return set_check_config_state(false, "Отсутствует секция mail") if @config.nil?
35
+ return set_check_config_state(false, 'Отсутствует параметр enable в секции mail') if @config.enable.nil?
36
+ return set_check_config_state(false, 'Отсутствует параметр from в секции mail') if @config.from.nil?
37
+ return set_check_config_state(false, 'Параметр from в секции mail не должен быть пустым') if @config.from.strip == ''
38
+ return set_check_config_state(false, "Метод доставки должен быть один из: #{methods.inspect}") unless methods.include?(@config.delivery_method.to_s)
39
+
40
+ set_check_config_state(false, 'Неизвестная ошибка (почтовая подсистема)')
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,90 @@
1
+ # CliApplication::MailLib::Log - класс хранения почты в файлы
2
+
3
+ module CliApplication
4
+ module MailLib
5
+ class Log < ::CliApplication::MailLib::Base
6
+
7
+ def initialize(config, folders) # :nodoc:
8
+ @delivery_method = :log
9
+ super(config, folders)
10
+ check_config
11
+
12
+ prepare_log_filename
13
+ end
14
+
15
+ # Данный метод возвращает имя файла для записи логов. В этом методе происходит
16
+ # обработка параметра даты {date}, что позволяет разбивать логи по дням.
17
+ #
18
+ # @return [String] имя лог-файла для записи сообщений
19
+ def log_filename
20
+ @log_filename.gsub('{date}', ::Time.zone.now.to_date.to_s(:db))
21
+ end
22
+
23
+ # Функция записывает сообщение электронной почты в лог-файл, с преобразованием HTML-формата в текст
24
+ #
25
+ # @param [String] to электронная почта лица, которому отправляется сообщение, или массив адресов
26
+ # @param [String] name имя клиента, которому отправляется сообщение
27
+ # @param [String] title заголовок письма
28
+ # @param [String] body текст письма
29
+ # @return [Boolean] true, если письмо отправлено
30
+ def simple_send(to, name, title, body)
31
+ message = CliApplication::MailLib::Message.new
32
+ message.from_email = @config.from
33
+ message.subject = title
34
+ message.body = (@config.footer.nil? || @config.footer == '') ? body : (body+@config.footer)
35
+
36
+ processing_to(to, name, message)
37
+
38
+ out = Array.new
39
+ out << ''
40
+ out << "--- #{StTools::Human.format_time(::Time.zone.now, :full, :full)} -------------------"
41
+ out << message.to_log
42
+ record = out.join("\n")
43
+
44
+ open(log_filename, 'a') do |f|
45
+ f.puts record
46
+ end
47
+
48
+ true
49
+ rescue Exception => e
50
+ $stderr.puts "Ошибка записи электронного сообщения: #{e.message}"
51
+ false
52
+ end
53
+
54
+
55
+ private
56
+
57
+
58
+ def check_config # :nodoc:
59
+ return set_check_config_state(false, "Не найдена секция конфиг-файла cli/mail/log") if @config.log.nil?
60
+ return set_check_config_state(false, "Не найден параметр конфиг-файла cli/mail/log/location") if @config.log.location.nil?
61
+ return set_check_config_state(false, "Параметр конфиг-файла cli/mail/log/location не должен быть пустым") if @config.log.location == ''
62
+ set_check_config_state(true, '')
63
+ end
64
+
65
+ def prepare_log_filename # :nodoc:
66
+ return '' unless valid?
67
+
68
+ res = @config.log.location
69
+ res.gsub!('{exe}', File.basename(StTools::System.exename, '.rb').gsub(/\_/, '-'))
70
+ res.gsub!('****', @folders[:app])
71
+ res.gsub!('***', @folders[:class])
72
+ @log_filename = res
73
+
74
+ path = File.dirname(@log_filename)
75
+ begin
76
+ unless Dir.exist?(path)
77
+ FileUtils.mkdir_p(path)
78
+ FileUtils.chmod(0777, path)
79
+ end
80
+ rescue Exception => e
81
+ $stderr.puts "Ошибка создания папки для записи сообщений электронной почты (#{e.message})"
82
+ $stderr.puts " #{path}"
83
+ $stderr.puts " Обратитесь к разработчику данного скрипта"
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+ end
90
+ end