cli_application 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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