bizside 2.0.1
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/app/assets/images/jquery-treeTable/images/toggle-collapse-dark.png +0 -0
- data/app/assets/images/jquery-treeTable/images/toggle-collapse-light.png +0 -0
- data/app/assets/images/jquery-treeTable/images/toggle-expand-dark.png +0 -0
- data/app/assets/images/jquery-treeTable/images/toggle-expand-light.png +0 -0
- data/app/assets/javascripts/bizside.js +1 -0
- data/app/assets/javascripts/jquery-treeTable/jquery.treeTable.js +400 -0
- data/app/assets/stylesheets/bizside.css +3 -0
- data/app/assets/stylesheets/jquery-treeTable/jquery.treeTable.css.erb +55 -0
- data/lib/bizside/acl/access_control_utils.rb +36 -0
- data/lib/bizside/acl/available_helper.rb +65 -0
- data/lib/bizside/acl/controller_helper.rb +15 -0
- data/lib/bizside/acl.rb +6 -0
- data/lib/bizside/active_record_logger.rb +3 -0
- data/lib/bizside/audit/job_logger.rb +14 -0
- data/lib/bizside/audit/logger.rb +35 -0
- data/lib/bizside/audit_log.rb +158 -0
- data/lib/bizside/cache/entry.rb +112 -0
- data/lib/bizside/cache/file_store.rb +167 -0
- data/lib/bizside/cache/store.rb +237 -0
- data/lib/bizside/cache_util.rb +47 -0
- data/lib/bizside/cache_utils.rb +10 -0
- data/lib/bizside/carrierwave.rb +48 -0
- data/lib/bizside/config.rb +63 -0
- data/lib/bizside/configurations/mail.rb +37 -0
- data/lib/bizside/configurations/prefix.rb +25 -0
- data/lib/bizside/configurations/storage.rb +28 -0
- data/lib/bizside/coverage/launch.rb +25 -0
- data/lib/bizside/coverage/rcov_formatter.rb +13 -0
- data/lib/bizside/cron_validator.rb +62 -0
- data/lib/bizside/cucumber.rb +1 -0
- data/lib/bizside/engine.rb +4 -0
- data/lib/bizside/file_converter.rb +56 -0
- data/lib/bizside/file_uploader.rb +71 -0
- data/lib/bizside/gengou.rb +46 -0
- data/lib/bizside/gengou.yml +5 -0
- data/lib/bizside/hanaita_conf.rb +88 -0
- data/lib/bizside/implicit_ftps.rb +29 -0
- data/lib/bizside/itamae_conf.rb +186 -0
- data/lib/bizside/job_utils.rb +285 -0
- data/lib/bizside/log_analyzer.rb +122 -0
- data/lib/bizside/mailer.rb +56 -0
- data/lib/bizside/query_builder.rb +78 -0
- data/lib/bizside/railtie.rb +80 -0
- data/lib/bizside/record_has_warnings.rb +4 -0
- data/lib/bizside/resque.rb +141 -0
- data/lib/bizside/rsync.rb +40 -0
- data/lib/bizside/safe_pty.rb +17 -0
- data/lib/bizside/shib_utils.rb +18 -0
- data/lib/bizside/show_exceptions.rb +18 -0
- data/lib/bizside/sql_utils.rb +45 -0
- data/lib/bizside/string_io.rb +39 -0
- data/lib/bizside/string_utils.rb +157 -0
- data/lib/bizside/task_helper.rb +263 -0
- data/lib/bizside/tasks.rb +6 -0
- data/lib/bizside/test_help.rb +17 -0
- data/lib/bizside/uploader/content_type_validator.rb +39 -0
- data/lib/bizside/uploader/default_extensions.yml +15 -0
- data/lib/bizside/uploader/exif.rb +43 -0
- data/lib/bizside/uploader/extension_whitelist.rb +26 -0
- data/lib/bizside/uploader/filename_validator.rb +31 -0
- data/lib/bizside/user_agent/action_view/action_view_4.rb +56 -0
- data/lib/bizside/user_agent/action_view/use_variant.rb +4 -0
- data/lib/bizside/user_agent/action_view.rb +10 -0
- data/lib/bizside/user_agent/controller_helper.rb +51 -0
- data/lib/bizside/user_agent.rb +108 -0
- data/lib/bizside/validations.rb +8 -0
- data/lib/bizside/version.rb +3 -0
- data/lib/bizside/view_helper.rb +10 -0
- data/lib/bizside/warning.rb +24 -0
- data/lib/bizside/yes.rb +16 -0
- data/lib/bizside.rb +96 -0
- data/lib/cron_validator.rb +3 -0
- data/lib/gengou.rb +3 -0
- data/lib/job_utils.rb +3 -0
- data/lib/query_builder.rb +3 -0
- data/lib/record_has_warnings.rb +3 -0
- data/lib/sql_utils.rb +3 -0
- data/lib/string_utils.rb +3 -0
- data/lib/user_agent.rb +3 -0
- data/lib/yes.rb +3 -0
- data/rails/locales/ja.yml +12 -0
- data/validations/collection_presence_validator.rb +15 -0
- data/validations/email_validator.rb +1 -0
- data/validations/ip_address_validator.rb +22 -0
- data/validations/tel_validator.rb +28 -0
- data/validations/url_validator.rb +30 -0
- data/validations/zip_validator.rb +35 -0
- metadata +467 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
module Bizside
|
|
5
|
+
# itamae_conf をテストするため、 singleton 以前のクラスを定義
|
|
6
|
+
#
|
|
7
|
+
# TODO: HanaitaConf と類似していますが HanaitaConf は obsolete 予定なので
|
|
8
|
+
# 敢えて refactoring はやっていません。
|
|
9
|
+
class ItamaeConfSub
|
|
10
|
+
class << self
|
|
11
|
+
# base..derived の順
|
|
12
|
+
def conf_files
|
|
13
|
+
if ENV['ITAMAE_CONFS']
|
|
14
|
+
ENV['ITAMAE_CONFS'].split
|
|
15
|
+
else
|
|
16
|
+
result = ['/etc/bizside/hanaita.yml']
|
|
17
|
+
add_yml(result, 'itamae.yml')
|
|
18
|
+
add_yml(result, 'database.yml')
|
|
19
|
+
result
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# shared/*.yml を優先して指定。存在しない時にのみ config/*.yml を指定。
|
|
26
|
+
def add_yml(paths, basename)
|
|
27
|
+
candidates = []
|
|
28
|
+
candidates << File.join(ENV['DEPLOY_TO'], 'shared', basename).to_s unless ENV['DEPLOY_TO'].to_s.empty?
|
|
29
|
+
candidates << File.join('config', basename).to_s
|
|
30
|
+
|
|
31
|
+
candidates.each do |path|
|
|
32
|
+
if File.exist?(path)
|
|
33
|
+
paths << path
|
|
34
|
+
break
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def initialize
|
|
41
|
+
for conf_file in self.class.conf_files do
|
|
42
|
+
if File.exist?(conf_file)
|
|
43
|
+
@_conf ||= {}
|
|
44
|
+
hash = YAML.load(ERB.new(File.read(conf_file)).result)
|
|
45
|
+
|
|
46
|
+
case conf_file
|
|
47
|
+
# itamae.yml スペシャルロジック。ROLE必須。
|
|
48
|
+
when /itamae.yml$/
|
|
49
|
+
role = ENV['ROLE']
|
|
50
|
+
next if role.nil? || role.empty?
|
|
51
|
+
hash = hash[role]
|
|
52
|
+
|
|
53
|
+
# database.yml スペシャルロジック。例:
|
|
54
|
+
#
|
|
55
|
+
# database.yml:: RAILS_ENV.adapter
|
|
56
|
+
# ↓:: ↓
|
|
57
|
+
# itamae_conf:: db.adapter
|
|
58
|
+
when /database.yml$/
|
|
59
|
+
partial = hash[Bizside.env]
|
|
60
|
+
hash = {'db' => partial.dup} if partial
|
|
61
|
+
end
|
|
62
|
+
deep_merge!(@_conf, hash) if hash
|
|
63
|
+
else
|
|
64
|
+
$stderr.printf("WARN: %s does NOT exist.\n", conf_file)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def conf
|
|
70
|
+
@_conf
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# (c)Rails
|
|
76
|
+
def deep_merge(h1, h2, &block)
|
|
77
|
+
deep_merge!(h1.dup, h2, &block)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# (c)Rails
|
|
81
|
+
def deep_merge!(h1, h2, &block)
|
|
82
|
+
h2.each_pair do |current_key, other_value|
|
|
83
|
+
this_value = h1[current_key]
|
|
84
|
+
h1[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
|
|
85
|
+
deep_merge(this_value, other_value, &block)
|
|
86
|
+
else
|
|
87
|
+
if block_given? && key?(current_key)
|
|
88
|
+
block.call(current_key, this_value, other_value)
|
|
89
|
+
else
|
|
90
|
+
other_value
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
h1
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# 各種 yml を1つの hash にマージした on-memory モデル:
|
|
99
|
+
#
|
|
100
|
+
# == SYNOPSIS
|
|
101
|
+
# require 'itamae_plugin_recipe_bizside'
|
|
102
|
+
# itamae_conf(:a, :b, ...) # Or
|
|
103
|
+
# itamae_conf('a.b...')
|
|
104
|
+
#
|
|
105
|
+
# == DESCRIPTION
|
|
106
|
+
# yaml設定ファイル(後述。FILES節参照) の hash に対するキー検索を行います。
|
|
107
|
+
#
|
|
108
|
+
# ファイルが存在しない場合は nil を返します。
|
|
109
|
+
#
|
|
110
|
+
# itamae_conf(:a, :b) は意味的に itamae.yml のハッシュに対する
|
|
111
|
+
# アクセスitamae_conf['a']['b'] と同等です。
|
|
112
|
+
#
|
|
113
|
+
# itamae_conf(:a) が ハッシュでない場合(未定義または文字列や数値など)、
|
|
114
|
+
# itamae_conf(:a, :b) は単に nil を返します('undefined method `[]'
|
|
115
|
+
# for nil:NilClass' とはなりません)。
|
|
116
|
+
#
|
|
117
|
+
# I18n#t と同様、'a.b' と言った文字列指定も可能です。
|
|
118
|
+
#
|
|
119
|
+
# == FILES
|
|
120
|
+
# config/database.yml:: 設定ファイル-1(*1)
|
|
121
|
+
# config/itamae.yml:: 設定ファイル-2(*2)
|
|
122
|
+
# /etc/bizside/hanaita.yml:: 設定ファイル-3
|
|
123
|
+
#
|
|
124
|
+
# (*1) RAISL_ENV に該当する部分のみ 'db' エントリの下に読み込みます。
|
|
125
|
+
# (*2) 指定された ROLE のみ読み込みます。
|
|
126
|
+
class ItamaeConf < ItamaeConfSub
|
|
127
|
+
class OverWriteError < StandardError; end
|
|
128
|
+
|
|
129
|
+
include Singleton
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 各フェーズで itamae_conf メソッド経由でアクセスできるようにするための
|
|
133
|
+
# ユーティリティ。node メソッドと同様。
|
|
134
|
+
module ItamaeConfAccessorMixin
|
|
135
|
+
# 必要に応じて上書き
|
|
136
|
+
def itamae_conf_factory
|
|
137
|
+
Bizside::ItamaeConf.instance
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def itamae_conf(*args)
|
|
141
|
+
if args.nil? || (args.is_a?(Array) && args[0].is_a?(Symbol) || args[0].nil?)
|
|
142
|
+
itamae_conf_sub(itamae_conf_factory.conf, args)
|
|
143
|
+
elsif args.is_a?(Array) && args[0].is_a?(String)
|
|
144
|
+
itamae_conf_sub(itamae_conf_factory.conf, args[0].split('.').map{|s| s.to_sym})
|
|
145
|
+
else
|
|
146
|
+
raise 'unsupported argument type'
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# itamae_conf に値をセットします。
|
|
151
|
+
#
|
|
152
|
+
# 安易な上書きを避けるため、既存値が存在する場合は OverWriteError としています。
|
|
153
|
+
#
|
|
154
|
+
# 簡単化のため、シンボル指定(set_itamae_conf(:a, :b, ..., value))はサポートしていません
|
|
155
|
+
# (itamae_conf と違って)。
|
|
156
|
+
def set_itamae_conf(key, value)
|
|
157
|
+
raise 'まだ用途が定まっていないので、使用不可です。' unless Bizside.env == 'test'
|
|
158
|
+
set_itamae_conf_sub(itamae_conf_factory.conf, key.split('.'), key, value)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
private
|
|
162
|
+
|
|
163
|
+
def itamae_conf_sub(data, args)
|
|
164
|
+
if args.size == 0
|
|
165
|
+
data
|
|
166
|
+
elsif data.is_a?(Hash)
|
|
167
|
+
itamae_conf_sub(data[args[0].to_s], args.drop(1))
|
|
168
|
+
else
|
|
169
|
+
nil
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# ここで key は単にエラーメッセージ用途
|
|
174
|
+
def set_itamae_conf_sub(hash, args, key, value)
|
|
175
|
+
arg0 = args[0]
|
|
176
|
+
if args.size == 1
|
|
177
|
+
raise ItamaeConf::OverWriteError.new("duplicate on #{key}") if hash[arg0]
|
|
178
|
+
|
|
179
|
+
hash[arg0] = value
|
|
180
|
+
else
|
|
181
|
+
hash[arg0] = {} if hash[arg0].nil?
|
|
182
|
+
set_itamae_conf_sub(hash[arg0], args.drop(1), key, value)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
require 'bizside/cron_validator'
|
|
2
|
+
|
|
3
|
+
module Bizside
|
|
4
|
+
class JobUtils
|
|
5
|
+
|
|
6
|
+
def self.add_job(klass, *args, &block)
|
|
7
|
+
add_job_to(nil, klass, *args, &block)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.add_job_to(queue, klass, *args)
|
|
11
|
+
if Bizside.rails_env&.test?
|
|
12
|
+
if klass.respond_to?(:before_enqueue)
|
|
13
|
+
return unless klass.before_enqueue(*args)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Bizside.logger.info "テスト時にはジョブの登録を行わず、即時実行します。"
|
|
17
|
+
klass.perform(*args)
|
|
18
|
+
return
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if block_given?
|
|
22
|
+
yield
|
|
23
|
+
else
|
|
24
|
+
if queue
|
|
25
|
+
Bizside.logger.info "ジョブ #{klass} を #{queue} に登録します。"
|
|
26
|
+
else
|
|
27
|
+
Bizside.logger.info "ジョブ #{klass} を登録します。"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if queue.present?
|
|
32
|
+
::Resque.enqueue_to(queue, klass, *args)
|
|
33
|
+
else
|
|
34
|
+
::Resque.enqueue(klass, *args)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.add_job_silently(klass, *args)
|
|
39
|
+
add_job(klass, *args) do
|
|
40
|
+
# 何も出力しない
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.add_job_silently_to(queue, klass, *args)
|
|
45
|
+
add_job_to(queue, klass, *args) do
|
|
46
|
+
# 何も出力しない
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.set_job_at(time, klass, *args)
|
|
51
|
+
if Bizside.rails_env&.test?
|
|
52
|
+
if klass.respond_to?(:before_enqueue)
|
|
53
|
+
return unless klass.before_enqueue(*args)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Bizside.logger.info "テスト時には遅延ジョブの登録を行わず、即時実行します。"
|
|
57
|
+
klass.perform(*args)
|
|
58
|
+
return
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if block_given?
|
|
62
|
+
yield
|
|
63
|
+
else
|
|
64
|
+
Bizside.logger.info "遅延ジョブ #{klass} を登録します。"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
::Resque.enqueue_at(time, klass, *args)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.set_job_silently_at(time, klass, *args)
|
|
71
|
+
set_job_at(time, klass, *args) do
|
|
72
|
+
# 何も出力しない
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.cancel_job_at(klass, *args)
|
|
77
|
+
if Bizside.rails_env&.test?
|
|
78
|
+
Bizside.logger.info "テスト時には遅延ジョブのキャンセルを行いません。"
|
|
79
|
+
return
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
::Resque.remove_delayed(klass, *args)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.add_cron(name, job_type, cron, *args)
|
|
86
|
+
add_cron_to(nil, name, job_type, cron, *args)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.add_cron_to(queue, name, job_type, cron, *args)
|
|
90
|
+
if Bizside.rails_env&.test?
|
|
91
|
+
Bizside.logger.info 'テスト時にはCronの設定を行いません。'
|
|
92
|
+
return
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
::Resque.remove_schedule(name)
|
|
96
|
+
|
|
97
|
+
cronline = Array(cron).first
|
|
98
|
+
|
|
99
|
+
if cronline.to_s.strip.empty?
|
|
100
|
+
return
|
|
101
|
+
elsif CronValidator.new(cronline).valid?
|
|
102
|
+
config = {
|
|
103
|
+
:class => job_type,
|
|
104
|
+
:cron => cron,
|
|
105
|
+
:args => args,
|
|
106
|
+
:persist => true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
config[:queue] = queue if queue.present?
|
|
110
|
+
|
|
111
|
+
::Resque.set_schedule(name, config)
|
|
112
|
+
else
|
|
113
|
+
raise ArgumentError, "Cronの書式が正しくないのでスケジューリングしません。name=#{name}"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def self.remove_cron(name)
|
|
118
|
+
remove_scheduler(name)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.add_scheduler(name, job_type, interval_args, *args)
|
|
122
|
+
if Bizside.rails_env&.test?
|
|
123
|
+
Bizside.logger.info 'テスト時にはCronの設定を行いません。'
|
|
124
|
+
return
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
::Resque.remove_schedule(name)
|
|
128
|
+
|
|
129
|
+
if interval_args[:cron].present?
|
|
130
|
+
add_cron(name, job_type, interval_args[:cron], args)
|
|
131
|
+
elsif interval_args[:every].present?
|
|
132
|
+
config = {
|
|
133
|
+
:class => job_type,
|
|
134
|
+
:every => interval_args[:every],
|
|
135
|
+
:args => args,
|
|
136
|
+
:persist => true
|
|
137
|
+
}
|
|
138
|
+
::Resque.set_schedule(name, config)
|
|
139
|
+
else
|
|
140
|
+
raise ArgumentError, "cronもしくはeveryが指定されていないのでスケジューリングしません。name=#{name}"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def self.remove_scheduler(name)
|
|
145
|
+
if Bizside.rails_env&.test?
|
|
146
|
+
Bizside.logger.info 'テスト時にはCronの設定を行いません。'
|
|
147
|
+
return
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
::Resque.remove_schedule(name)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def self.peek(queue, start = 0, count = 1)
|
|
154
|
+
if Bizside.rails_env&.test?
|
|
155
|
+
Bizside.logger.info 'テスト時は、ジョブ 0 件とします。'
|
|
156
|
+
return []
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
::Resque.peek(queue, start, count)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def self.enqueue_in(time_to_delay, klass, *args)
|
|
163
|
+
if Bizside.rails_env&.test?
|
|
164
|
+
Bizside.logger.info 'テスト時にジョブの遅延実行は行いません。'
|
|
165
|
+
return
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
::Resque.enqueue_in(time_to_delay, klass, *args)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def self.enqueue_in_with_queue(queue, time_to_delay, klass, *args)
|
|
172
|
+
if Bizside.rails_env&.test?
|
|
173
|
+
Bizside.logger.info 'テスト時にジョブの遅延実行は行いません。'
|
|
174
|
+
return
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
::Resque.enqueue_in_with_queue(queue, time_to_delay, klass, *args)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def self.dequeue(klass, *args)
|
|
181
|
+
if Bizside.rails_env&.test?
|
|
182
|
+
Bizside.logger.info 'テスト時にジョブの削除は行いません。'
|
|
183
|
+
return
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
::Resque.dequeue(klass, *args)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def self.any_jobs_for?(queue)
|
|
190
|
+
ret = ::Resque.size(queue)
|
|
191
|
+
ret += ::Resque.working.reduce(0){|sum, worker| sum += worker.queues.include?(queue) ? 1 : 0 }
|
|
192
|
+
ret > 0
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def self.remove_queue(queue)
|
|
196
|
+
if Bizside.rails_env&.test?
|
|
197
|
+
Bizside.logger.info 'テスト時にキューの削除は行いません。'
|
|
198
|
+
return
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
::Resque.remove_queue(queue)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def self.queue_from_class(klass)
|
|
205
|
+
::Resque.queue_from_class(klass)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def self.queue_size(queue)
|
|
209
|
+
return 0 if Bizside.rails_env&.test?
|
|
210
|
+
|
|
211
|
+
::Resque.size(queue)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def self.unique_in_queue?(klass, args = {}, queue, count: 100, except: [])
|
|
215
|
+
if Bizside.rails_env&.test?
|
|
216
|
+
Bizside.logger.info "テスト時は常にキューに同一ジョブが存在しない前提とします。"
|
|
217
|
+
return true
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
jobs = self.peek(queue, 0, count) # 先頭からcount件のジョブ
|
|
221
|
+
|
|
222
|
+
if already_in_jobs?(klass, args, jobs, except: except)
|
|
223
|
+
false
|
|
224
|
+
else
|
|
225
|
+
count = rest_count(self.queue_size(queue), count)
|
|
226
|
+
if count == 0
|
|
227
|
+
true
|
|
228
|
+
else
|
|
229
|
+
count += 1 if count == 1 # Resque.peek()が1件だと戻り値の型が違うのを回避
|
|
230
|
+
jobs = self.peek(queue, count * -1, count) # 後ろからcount件のジョブ
|
|
231
|
+
! already_in_jobs?(klass, args, jobs, except: except)
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def self.already_in_jobs?(klass, args = {}, jobs, except: [])
|
|
237
|
+
args_to_check = args.with_indifferent_access.except(*Array(except))
|
|
238
|
+
|
|
239
|
+
jobs.each do |hash|
|
|
240
|
+
hash = hash.with_indifferent_access
|
|
241
|
+
next unless hash['class'] == klass.to_s
|
|
242
|
+
|
|
243
|
+
args = Hash(hash['args'].present? ? hash['args'][0] : {}).with_indifferent_access.except(*Array(except))
|
|
244
|
+
next unless args.size == args_to_check.size
|
|
245
|
+
|
|
246
|
+
found = true
|
|
247
|
+
args_to_check.each do |key, value|
|
|
248
|
+
if args[key] != value
|
|
249
|
+
found = false
|
|
250
|
+
break
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
if found
|
|
255
|
+
Bizside.logger.info "キューに #{hash} がすでに登録されています。"
|
|
256
|
+
return true
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
false
|
|
261
|
+
end
|
|
262
|
+
private_class_method :already_in_jobs?
|
|
263
|
+
|
|
264
|
+
def self.rest_count(size, limit)
|
|
265
|
+
[[size - limit, 0].max, limit].min
|
|
266
|
+
end
|
|
267
|
+
private_class_method :rest_count
|
|
268
|
+
|
|
269
|
+
def self.failure_jobs(start = 0, count = 1, queue = nil)
|
|
270
|
+
if Bizside.rails_env&.test?
|
|
271
|
+
Bizside.logger.info 'テスト時は、ジョブ 0 件とします。'
|
|
272
|
+
return []
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
::Resque::Failure.all(start, count, queue)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def self.failure_count(queue = nil, class_name = nil)
|
|
279
|
+
return 0 if Bizside.rails_env&.test?
|
|
280
|
+
|
|
281
|
+
::Resque::Failure.count(queue, class_name)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end
|
|
285
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Bizside
|
|
2
|
+
class LogAnalyzer
|
|
3
|
+
attr_reader :add_on_name
|
|
4
|
+
attr_reader :error_contents
|
|
5
|
+
|
|
6
|
+
def initialize(add_on_name, files)
|
|
7
|
+
@add_on_name = add_on_name
|
|
8
|
+
@files = files
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def analyze(output_file_name)
|
|
12
|
+
@success = system("request-log-analyzer --format rails3 --parse-strategy cautious --file #{output_file_name}.html --output HTML #{@files.join(' ')}")
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def success?
|
|
16
|
+
@success
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def scrape_errors
|
|
20
|
+
@error_content = String.new
|
|
21
|
+
@error_contents = {}
|
|
22
|
+
|
|
23
|
+
# TODO Okozeを解析できるようにする
|
|
24
|
+
return if add_on_name == 'okoze'
|
|
25
|
+
|
|
26
|
+
# TODO ログ内で重複したエラーメッセージを除外する
|
|
27
|
+
return if ['amadai', 'webcam_api', 'seri', 'sushioke'].include?(add_on_name)
|
|
28
|
+
|
|
29
|
+
@files.each do |file|
|
|
30
|
+
content = File.read(file, encoding: 'utf-8')
|
|
31
|
+
content = content.encode('UTF-16BE', 'UTF-8', :invalid => :replace, :undef => :replace, :replace => '?').encode('UTF-8')
|
|
32
|
+
next unless content.include?('Completed 500') or content.include?('FATAL')
|
|
33
|
+
|
|
34
|
+
# ログをプロセス単位に分割
|
|
35
|
+
partition_contents = divide_into_pid(content)
|
|
36
|
+
# プロセス単位に分割したログからエラーを抽出
|
|
37
|
+
partition_content_errors = extract_error_log(partition_contents)
|
|
38
|
+
# 抽出したエラーを出力用にまとめる
|
|
39
|
+
partition_content_errors.each do |pid, pc|
|
|
40
|
+
@error_contents[pid] = "#{file}のエラー抽出結果\n\n\n" if @error_contents[pid].nil? or @error_contents[pid].empty?
|
|
41
|
+
@error_contents[pid] << pc
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
@error_contents
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def divide_into_pid(content)
|
|
49
|
+
pid = nil
|
|
50
|
+
ret = {}
|
|
51
|
+
content.each_line do |c|
|
|
52
|
+
s = c.scan(/#[0-9]+\]/)
|
|
53
|
+
pid = s.first.scan(/[0-9]+/).first unless s.empty?
|
|
54
|
+
ret[pid] = "" unless ret[pid]
|
|
55
|
+
ret[pid] << c
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
ret
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def extract_error_log(partition_contents)
|
|
62
|
+
ret = {}
|
|
63
|
+
partition_contents.each do |pid, pc|
|
|
64
|
+
tmp = ""
|
|
65
|
+
pc.each_line do |line|
|
|
66
|
+
unless line.scan(/: Started /).empty?
|
|
67
|
+
if !tmp.scan(/Completed 500/).empty? or !tmp.scan(/\] FATAL/).empty? or !tmp.scan(/\[FATAL\]/).empty?
|
|
68
|
+
ret[pid] = "" if ret[pid].nil? or ret[pid].empty?
|
|
69
|
+
ret[pid] << tmp
|
|
70
|
+
end
|
|
71
|
+
tmp.clear
|
|
72
|
+
end
|
|
73
|
+
tmp << exclude_error_log_line(line)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Startedの前にログが終了した場合、その時点までにエラーが含まれていれば抽出に含める
|
|
77
|
+
if !tmp.empty? and !tmp.scan(/Completed 500/).empty? or !tmp.scan(/\] FATAL/).empty? or !tmp.scan(/\[FATAL\]/).empty?
|
|
78
|
+
ret[pid] = "" if ret[pid].nil? or ret[pid].empty?
|
|
79
|
+
ret[pid] << tmp
|
|
80
|
+
end
|
|
81
|
+
tmp.clear
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
ret
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def exclude_error_log_line(line)
|
|
88
|
+
ret = nil
|
|
89
|
+
ret = line.match("INFO -- : ジョブ.*登録します。")
|
|
90
|
+
|
|
91
|
+
if ret.nil?
|
|
92
|
+
line
|
|
93
|
+
else
|
|
94
|
+
""
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# TODO 重複したエラーログを除外する
|
|
99
|
+
def get_duplicate_check_line(line)
|
|
100
|
+
ret = line.scan(/(INFO -- :.*|ERROR -- :.*|WARN -- :.*|FATAL -- :.*)/).first
|
|
101
|
+
ret = ret.gsub(/\" for .*/, "\"") unless ret.nil or ret.empty?
|
|
102
|
+
|
|
103
|
+
ret
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# TODO 重複したエラーログを除外する
|
|
107
|
+
def duplicate_error_log?(extract_error_logs, duplicate_check_lines)
|
|
108
|
+
res = false
|
|
109
|
+
extract_error_logs.each do |eer|
|
|
110
|
+
tmp = false
|
|
111
|
+
duplicate_check_lines.each do |dcl|
|
|
112
|
+
tmp = eer.include?(dcl)
|
|
113
|
+
break unless tmp
|
|
114
|
+
end
|
|
115
|
+
res = tmp
|
|
116
|
+
break if res
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
res
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Bizside
|
|
2
|
+
module Mailer
|
|
3
|
+
|
|
4
|
+
def mail(headers={ })
|
|
5
|
+
headers = headers.merge(:delivery_method_options => Bizside.config.smtp_settings)
|
|
6
|
+
m = super
|
|
7
|
+
m.transport_encoding = '8bit'
|
|
8
|
+
m.from ||= Bizside.config.mail.from
|
|
9
|
+
m
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def set_priority_headers(priority)
|
|
15
|
+
get_priority_headers(priority).each do |key, value|
|
|
16
|
+
headers[key] = value
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def get_priority_headers(priority)
|
|
23
|
+
ret = {}
|
|
24
|
+
|
|
25
|
+
# Outlook、ThunderBird
|
|
26
|
+
ret['X-Priority'] = priority
|
|
27
|
+
|
|
28
|
+
# Notes
|
|
29
|
+
notes_priority = convert_priority_for_notes(priority)
|
|
30
|
+
if notes_priority
|
|
31
|
+
ret['Importance'] = notes_priority
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
ret
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def convert_priority_for_notes(priority)
|
|
38
|
+
case priority.to_i
|
|
39
|
+
when 1
|
|
40
|
+
return 'High'
|
|
41
|
+
when 2
|
|
42
|
+
return 'High'
|
|
43
|
+
when 3
|
|
44
|
+
return 'Normal'
|
|
45
|
+
when 4
|
|
46
|
+
return 'Low'
|
|
47
|
+
when 5
|
|
48
|
+
return 'Low'
|
|
49
|
+
else
|
|
50
|
+
return nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|