narou 3.5.1 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/helper.rb CHANGED
@@ -350,10 +350,10 @@ module Helper
350
350
  # 長過ぎるファイルパスを詰める
351
351
  # ファイル名部分のみを詰める。拡張子は維持する
352
352
  #
353
- def truncate_path(path, limit = Inventory.load["filename-length-limit"])
353
+ def truncate_path(path, limit = Inventory.load["filename-length-limit"], extname: nil)
354
354
  limit ||= FILENAME_LENGTH_LIMIT
355
355
  dirname = File.dirname(path)
356
- extname = File.extname(path)
356
+ extname ||= File.extname(path)
357
357
  basename = File.basename(path, extname)
358
358
  if basename.length > limit
359
359
  basename = basename[0...limit]
@@ -375,7 +375,7 @@ module Helper
375
375
  #
376
376
  def erb_copy(src, dst, _binding)
377
377
  data = File.read(src, mode: "r:BOM|UTF-8")
378
- result = ERB.new(data, nil, "-").result(_binding)
378
+ result = ERB.new(data, trim_mode: "-").result(_binding)
379
379
  File.write(dst, result)
380
380
  end
381
381
 
data/lib/inventory.rb CHANGED
@@ -44,13 +44,13 @@ module Inventory
44
44
  return unless File.exist?(@inventory_file_path)
45
45
  self.merge!(Helper::CacheLoader.memo(@inventory_file_path) { |yaml|
46
46
  begin
47
- YAML.load(yaml)
47
+ YAML.unsafe_load(yaml)
48
48
  rescue Psych::SyntaxError
49
49
  unless restore(@inventory_file_path)
50
50
  error "#{@inventory_file_path} が壊れてるっぽい"
51
51
  raise
52
52
  end
53
- YAML.load_file(@inventory_file_path)
53
+ YAML.unsafe_load_file(@inventory_file_path)
54
54
  end
55
55
  })
56
56
  end
data/lib/loadconverter.rb CHANGED
@@ -10,7 +10,7 @@ BlankConverter = Class.new(ConverterBase) {}
10
10
 
11
11
  $latest_converter = nil
12
12
 
13
- def converter(title, &block)
13
+ def converter(_title = nil, &block)
14
14
  $latest_converter = Class.new(ConverterBase, &block)
15
15
  end
16
16
 
@@ -58,7 +58,7 @@ end
58
58
  # buffer
59
59
  # end
60
60
  # end
61
- def load_converter(title, archive_path)
61
+ def load_converter(archive_path)
62
62
  converter_path = File.join(archive_path, "converter.rb")
63
63
  if File.exist?(converter_path)
64
64
  $latest_converter = nil
@@ -71,9 +71,8 @@ def load_converter(title, archive_path)
71
71
  if conv
72
72
  return conv
73
73
  else
74
- title_for_converter = (title =~ /.txt\z/ ? title : File.basename(archive_path))
75
74
  error "converter.rbは見つかりましたが、`converter'で登録されていないようです。" +
76
- "変換処理は converter \"#{title_for_converter.gsub('"', '\\"')}\" として登録する必要があります"
75
+ "変換処理は converter do ... end として登録する必要があります"
77
76
  return BlankConverter
78
77
  end
79
78
  end
data/lib/mailer.rb CHANGED
@@ -23,7 +23,7 @@ class Mailer
23
23
  this.clear
24
24
  setting_file_path = File.join(Narou.root_dir, SETTING_FILE)
25
25
  if File.exist?(setting_file_path)
26
- options = YAML.load_file(setting_file_path)
26
+ options = YAML.unsafe_load_file(setting_file_path)
27
27
  unless options.delete(:complete)
28
28
  raise SettingUncompleteError, "設定ファイルの書き換えが終了していないようです。\n" +
29
29
  "設定ファイルは #{setting_file_path} にあります"
data/lib/narou.rb CHANGED
@@ -38,330 +38,336 @@ module Narou
38
38
 
39
39
  extend Mixin::Locker
40
40
 
41
- class << self
42
- extend Memoist
41
+ class << self
42
+ extend Memoist
43
43
 
44
- @@is_web = false
44
+ @@is_web = false
45
45
 
46
- def last_commit_year
47
- 2020
48
- end
46
+ def last_commit_year
47
+ 2021
48
+ end
49
49
 
50
- def root_dir
51
- root = nil
52
- path = Dir.pwd
53
- drive_letter = ""
54
- if Helper.os_windows?
55
- path.encode!(Encoding::UTF_8)
56
- path.gsub!(/^[a-z]:/i, "")
57
- drive_letter = $&
58
- end
59
- while path != ""
60
- if File.directory?("#{drive_letter}#{path}/#{LOCAL_SETTING_DIR_NAME}")
61
- root = drive_letter + path
62
- break
50
+ def root_dir
51
+ root = nil
52
+ path = Dir.pwd
53
+ drive_letter = ""
54
+ if Helper.os_windows?
55
+ path.encode!(Encoding::UTF_8)
56
+ path.gsub!(/^[a-z]:/i, "")
57
+ drive_letter = $&
58
+ end
59
+ while path != ""
60
+ if File.directory?("#{drive_letter}#{path}/#{LOCAL_SETTING_DIR_NAME}")
61
+ root = drive_letter + path
62
+ break
63
+ end
64
+ path.gsub!(%r!/[^/]*$!, "")
63
65
  end
64
- path.gsub!(%r!/[^/]*$!, "")
66
+ Pathname(root) if root
65
67
  end
66
- Pathname(root) if root
67
- end
68
- memoize :root_dir
68
+ memoize :root_dir
69
69
 
70
- def local_setting_dir
71
- root_dir&.join(LOCAL_SETTING_DIR_NAME)
72
- end
73
- memoize :local_setting_dir
70
+ def local_setting_dir
71
+ root_dir&.join(LOCAL_SETTING_DIR_NAME)
72
+ end
73
+ memoize :local_setting_dir
74
74
 
75
- def global_setting_dir
76
- if root_dir
77
- dir = root_dir.join(GLOBAL_SETTING_DIR_NAME)
78
- return dir if dir.directory?
75
+ def global_setting_dir
76
+ if root_dir
77
+ dir = root_dir.join(GLOBAL_SETTING_DIR_NAME)
78
+ return dir if dir.directory?
79
+ end
80
+ dir = Pathname(GLOBAL_SETTING_DIR_NAME).expand_path("~")
81
+ dir.mkdir unless dir.exist?
82
+ dir
79
83
  end
80
- dir = Pathname(GLOBAL_SETTING_DIR_NAME).expand_path("~")
81
- dir.mkdir unless dir.exist?
82
- dir
83
- end
84
- memoize :global_setting_dir
84
+ memoize :global_setting_dir
85
85
 
86
- def script_dir
87
- Pathname(__dir__).join("..").expand_path
88
- end
89
- memoize :script_dir
86
+ def script_dir
87
+ Pathname(__dir__).join("..").expand_path
88
+ end
89
+ memoize :script_dir
90
90
 
91
- def log_dir
92
- root_dir&.join(LOG_DIR)
93
- end
91
+ def log_dir
92
+ root_dir&.join(LOG_DIR)
93
+ end
94
94
 
95
- def preset_dir
96
- script_dir&.join(PRESET_DIR)
97
- end
98
- memoize :preset_dir
95
+ def preset_dir
96
+ script_dir&.join(PRESET_DIR)
97
+ end
98
+ memoize :preset_dir
99
99
 
100
- def already_init?
101
- root_dir.present?
102
- end
100
+ def already_init?
101
+ root_dir.present?
102
+ end
103
103
 
104
- def init
105
- return nil if already_init?
106
- FileUtils.mkdir(LOCAL_SETTING_DIR_NAME)
107
- puts "#{LOCAL_SETTING_DIR_NAME}/ を作成しました"
108
- Database.init
109
- end
104
+ def init
105
+ return nil if already_init?
106
+ FileUtils.mkdir(LOCAL_SETTING_DIR_NAME)
107
+ puts "#{LOCAL_SETTING_DIR_NAME}/ を作成しました"
108
+ Database.init
109
+ end
110
110
 
111
- #
112
- # target が alias だった場合はIDに変換する
113
- #
114
- # 全てのtarget照合系はこのメソッドを通過するので、ここで小文字にしてしまう
115
- #
116
- def alias_to_id(target)
117
- aliases = Inventory.load("alias")
118
- if aliases[target]
119
- return aliases[target]
120
- end
121
- target.kind_of?(Numeric) ? target : target.downcase
122
- end
111
+ #
112
+ # target が alias だった場合はIDに変換する
113
+ #
114
+ # 全てのtarget照合系はこのメソッドを通過するので、ここで小文字にしてしまう
115
+ #
116
+ def alias_to_id(target)
117
+ aliases = Inventory.load("alias")
118
+ if aliases[target]
119
+ return aliases[target]
120
+ end
121
+ target.is_a?(Numeric) ? target : target.downcase
122
+ end
123
123
 
124
- def novel_frozen?(target)
125
- id = Downloader.get_id_by_target(target) or return false
126
- Inventory.load("freeze").include?(id)
127
- end
124
+ def novel_frozen?(target)
125
+ id = Downloader.get_id_by_target(target) or return false
126
+ Inventory.load("freeze").include?(id)
127
+ end
128
128
 
129
- def create_aozoraepub3_jar_path(*paths)
130
- Pathname(File.expand_path(File.join(*paths, AOZORAEPUB3_JAR_NAME)))
131
- end
129
+ def create_aozoraepub3_jar_path(*paths)
130
+ Pathname(File.expand_path(File.join(*paths, AOZORAEPUB3_JAR_NAME)))
131
+ end
132
132
 
133
- def aozoraepub3_directory?(path)
134
- create_aozoraepub3_jar_path(path).exist?
135
- end
133
+ def aozoraepub3_directory?(path)
134
+ create_aozoraepub3_jar_path(path).exist?
135
+ end
136
136
 
137
- def parse_replace_txt(text)
138
- pattern = []
139
- text.each_line do |line|
140
- line.sub!(/[\r\n]+\z/, "")
141
- next if line[0] == ";" # コメント記号
142
- pair = line.split("\t", 2)
143
- if pair.length == 2 && pair[0]
144
- pattern << pair
137
+ def parse_replace_txt(text)
138
+ pattern = []
139
+ text.each_line do |line|
140
+ line.sub!(/[\r\n]+\z/, "")
141
+ next if line[0] == ";" # コメント記号
142
+ pair = line.split("\t", 2)
143
+ if pair.length == 2 && pair[0]
144
+ pattern << pair
145
+ end
145
146
  end
147
+ pattern
146
148
  end
147
- pattern
148
- end
149
149
 
150
- def write_replace_txt(path, pairs)
151
- buffer = pairs.each_with_object("\t").map(&:join).join("\n")
152
- File.write(path, buffer)
153
- end
150
+ def write_replace_txt(path, pairs)
151
+ buffer = pairs.each_with_object("\t").map(&:join).join("\n")
152
+ File.write(path, buffer)
153
+ end
154
154
 
155
- def load_global_replace_pattern
156
- path = root_dir.join(GLOBAL_REPLACE_NAME)
157
- pairs =
158
- if path.exist?
159
- Helper::CacheLoader.memo(path) do |text|
160
- parse_replace_txt(text)
155
+ def load_global_replace_pattern
156
+ path = root_dir.join(GLOBAL_REPLACE_NAME)
157
+ pairs =
158
+ if path.exist?
159
+ Helper::CacheLoader.memo(path) do |text|
160
+ parse_replace_txt(text)
161
+ end
162
+ else
163
+ []
161
164
  end
162
- else
163
- []
164
- end
165
- @@global_replace_pattern_pairs = pairs
166
- pairs
167
- end
165
+ @@global_replace_pattern_pairs = pairs
166
+ pairs
167
+ end
168
168
 
169
- def global_replace_pattern
170
- @@global_replace_pattern_pairs ||= load_global_replace_pattern
171
- end
169
+ def global_replace_pattern
170
+ @@global_replace_pattern_pairs ||= load_global_replace_pattern
171
+ end
172
172
 
173
- def save_global_replace_pattern
174
- path = root_dir.join(GLOBAL_REPLACE_NAME)
175
- write_replace_txt(path, @@global_replace_pattern_pairs)
176
- end
173
+ def save_global_replace_pattern
174
+ path = root_dir.join(GLOBAL_REPLACE_NAME)
175
+ write_replace_txt(path, @@global_replace_pattern_pairs)
176
+ end
177
177
 
178
- #
179
- # AozoraEpub3 の実行ファイル(.jar)のフルパス取得
180
- # 検索順序
181
- # 1. グローバルセッティング (global_setting aozoraepub3dir)
182
- # 2. 小説保存ディレクトリ(Narou.root_dir) 直下の AozoraEpub3
183
- # 3. スクリプト保存ディレクトリ(Narou.script_dir) 直下の AozoraEpub3
184
- #
185
- def aozoraepub3_path
186
- global_setting_aozora_path = Inventory.load("global_setting", :global)["aozoraepub3dir"]
187
- if global_setting_aozora_path
188
- aozora_jar_path = create_aozoraepub3_jar_path(global_setting_aozora_path)
189
- if aozora_jar_path.exist?
190
- return aozora_jar_path
178
+ #
179
+ # AozoraEpub3 の実行ファイル(.jar)のフルパス取得
180
+ # 検索順序
181
+ # 1. グローバルセッティング (global_setting aozoraepub3dir)
182
+ # 2. 小説保存ディレクトリ(Narou.root_dir) 直下の AozoraEpub3
183
+ # 3. スクリプト保存ディレクトリ(Narou.script_dir) 直下の AozoraEpub3
184
+ #
185
+ def aozoraepub3_path
186
+ global_setting_aozora_path = Inventory.load("global_setting", :global)["aozoraepub3dir"]
187
+ if global_setting_aozora_path
188
+ aozora_jar_path = create_aozoraepub3_jar_path(global_setting_aozora_path)
189
+ if aozora_jar_path.exist?
190
+ return aozora_jar_path
191
+ end
191
192
  end
192
- end
193
- [Narou.root_dir, Narou.script_dir].each do |dir|
194
- aozora_jar_path = create_aozoraepub3_jar_path(dir, AOZORAEPUB3_DIR)
195
- return aozora_jar_path if aozora_jar_path.exist?
196
- end
197
- nil
198
- end
199
- memoize :aozoraepub3_path
200
-
201
- #
202
- # 書籍ファイル名を生成する
203
- # convert.filename-to-ncode を設定している場合に novel_data に ncode、domain を
204
- # 設定しない場合は id カラムが必須
205
- #
206
- def create_novel_filename(novel_data, ext = "")
207
- filename_to_ncode = Inventory.load("local_setting")["convert.filename-to-ncode"]
208
- novel_setting =
209
- if novel_data["id"]
210
- NovelSetting.load(novel_data["id"])
211
- else
212
- OpenStruct.new
193
+ [Narou.root_dir, Narou.script_dir].each do |dir|
194
+ aozora_jar_path = create_aozoraepub3_jar_path(dir, AOZORAEPUB3_DIR)
195
+ return aozora_jar_path if aozora_jar_path.exist?
213
196
  end
214
- if novel_setting.output_filename.present?
215
- %!#{novel_setting.output_filename}#{ext}!
216
- elsif filename_to_ncode
217
- ncode, domain = novel_data["ncode"], novel_data["domain"]
218
- if !ncode || !domain
219
- id = novel_data["id"]
220
- unless id
221
- raise ArgumentError, %!novel_data["id"] を設定して下さい!
197
+ nil
198
+ end
199
+ memoize :aozoraepub3_path
200
+
201
+ #
202
+ # 書籍ファイル名を生成する
203
+ # convert.filename-to-ncode を設定している場合に novel_data に ncode、domain を
204
+ # 設定しない場合は id カラムが必須
205
+ #
206
+ # rubocop:disable Metrics/CyclomaticComplexity
207
+ # rubocop:disable Metrics/PerceivedComplexity
208
+ def create_novel_filename(novel_data, ext = "")
209
+ filename_to_ncode = Inventory.load("local_setting")["convert.filename-to-ncode"]
210
+ novel_setting =
211
+ if novel_data["id"]
212
+ NovelSetting.load(novel_data["id"])
213
+ else
214
+ OpenStruct.new
215
+ end
216
+ if novel_setting.output_filename.present?
217
+ %!#{novel_setting.output_filename}#{ext}!
218
+ elsif filename_to_ncode
219
+ ncode = novel_data["ncode"]
220
+ domain = novel_data["domain"]
221
+ if !ncode || !domain
222
+ id = novel_data["id"]
223
+ unless id
224
+ raise ArgumentError, %!novel_data["id"] を設定して下さい!
225
+ end
226
+ site_setting = Downloader.get_sitesetting_by_target(id)
227
+ ncode = site_setting["ncode"]
228
+ domain = site_setting["domain"]
222
229
  end
223
- site_setting = Downloader.get_sitesetting_by_target(id)
224
- ncode = site_setting["ncode"]
225
- domain = site_setting["domain"]
230
+ serialized_domain = domain.to_s.gsub(".", "_")
231
+ %!#{serialized_domain}_#{ncode}#{ext}!
232
+ else
233
+ author = Helper.replace_filename_special_chars(
234
+ novel_setting.novel_author.presence || novel_data["author"],
235
+ true
236
+ )
237
+ title = Helper.replace_filename_special_chars(
238
+ novel_setting.novel_title.presence || novel_data["title"],
239
+ true
240
+ )
241
+ filename = "[#{author}] #{title}#{ext}"
242
+ length_limit = Inventory.load["ebook-filename-length-limit"]
243
+ length_limit ? Helper.truncate_path(filename, length_limit, extname: ext) : filename
226
244
  end
227
- serialized_domain = domain.to_s.gsub(".", "_")
228
- %!#{serialized_domain}_#{ncode}#{ext}!
229
- else
230
- author = Helper.replace_filename_special_chars(
231
- novel_setting.novel_author.presence || novel_data["author"],
232
- true
233
- )
234
- title = Helper.replace_filename_special_chars(
235
- novel_setting.novel_title.presence || novel_data["title"],
236
- true
237
- )
238
- filename = "[#{author}] #{title}#{ext}"
239
- length_limit = Inventory.load["ebook-filename-length-limit"]
240
- length_limit ? Helper.truncate_path(filename, length_limit) : filename
241
245
  end
242
- end
246
+ # rubocop:enable Metrics/CyclomaticComplexity
247
+ # rubocop:enable Metrics/PerceivedComplexity
243
248
 
244
- def get_mobi_paths(target)
245
- get_ebook_file_paths(target, ".mobi")
246
- end
249
+ def get_mobi_paths(target)
250
+ get_ebook_file_paths(target, ".mobi")
251
+ end
247
252
 
248
- def get_ebook_file_paths(target, ext)
249
- data = Downloader.get_data_by_target(target)
250
- return nil unless data
251
- dir = Downloader.get_novel_data_dir_by_target(target)
252
- fname = create_novel_filename(data, ext)
253
- base = File.basename(fname, ext)
254
- get_ebook_file_paths_from_components(dir, base, ext)
255
- end
253
+ def get_ebook_file_paths(target, ext)
254
+ data = Downloader.get_data_by_target(target)
255
+ return nil unless data
256
256
 
257
- def get_ebook_file_paths_from_components(dir, base, ext)
258
- paths = [File.join(dir, "#{base}#{ext}")]
259
- index = 2
260
- while File.exist?(path = File.join(dir, "#{base}_#{index}#{ext}"))
261
- paths.push(Pathname(path))
262
- index += 1
257
+ dir = Downloader.get_novel_data_dir_by_target(target)
258
+ fname = create_novel_filename(data, ext)
259
+ base = File.basename(fname, ext)
260
+ get_ebook_file_paths_from_components(dir, base, ext)
263
261
  end
264
- paths
265
- end
266
262
 
267
- def misc_dir
268
- root_dir.join(MISC_DIR)
269
- end
263
+ def get_ebook_file_paths_from_components(dir, base, ext)
264
+ paths = [File.join(dir, "#{base}#{ext}")]
265
+ index = 2
266
+ while File.exist?(path = File.join(dir, "#{base}_#{index}#{ext}"))
267
+ paths.push(Pathname(path))
268
+ index += 1
269
+ end
270
+ paths
271
+ end
272
+
273
+ def misc_dir
274
+ root_dir.join(MISC_DIR)
275
+ end
270
276
 
271
- require_relative "device"
277
+ require_relative "device"
272
278
 
273
- def get_device(device_name = nil)
274
- device_name = Inventory.load("local_setting")["device"] unless device_name
275
- if device_name && Device.exists?(device_name)
276
- return Device.create(device_name)
279
+ def get_device(device_name = nil)
280
+ device_name ||= Inventory.load("local_setting")["device"]
281
+ if device_name && Device.exists?(device_name)
282
+ return Device.create(device_name)
283
+ end
284
+ nil
277
285
  end
278
- nil
279
- end
280
286
 
281
- def web=(bool)
282
- @@is_web = bool
283
- end
287
+ def web=(bool)
288
+ @@is_web = bool
289
+ end
284
290
 
285
- def web?
286
- @@is_web
287
- end
291
+ def web?
292
+ @@is_web
293
+ end
288
294
 
289
- def update_sort_key_summaries(left_space = 28)
290
- summaries = { "KEY" => " 対象" }.merge(UPDATE_SORT_KEYS)
291
- key_max_width = summaries.keys.max_by(&:length).length
292
- summaries.map do |(key, summary)|
293
- "#{" " * left_space}| #{key.center(key_max_width)} | #{summary}"
294
- end.join("\n")
295
- end
295
+ def update_sort_key_summaries(left_space = 28)
296
+ summaries = { "KEY" => " 対象" }.merge(UPDATE_SORT_KEYS)
297
+ key_max_width = summaries.keys.max_by(&:length).length
298
+ summaries.map do |(key, summary)|
299
+ "#{" " * left_space}| #{key.center(key_max_width)} | #{summary}"
300
+ end.join("\n")
301
+ end
296
302
 
297
- def get_theme
298
- Inventory.load("local_setting")["webui.theme"]
299
- end
303
+ def theme
304
+ Inventory.load("local_setting")["webui.theme"]
305
+ end
300
306
 
301
- def get_theme_dir(name = nil)
302
- Pathname(File.join([script_dir, "lib/web/public/theme", name].compact))
303
- end
307
+ def get_theme_dir(name = nil)
308
+ Pathname(File.join([script_dir, "lib/web/public/theme", name].compact))
309
+ end
304
310
 
305
- def get_theme_names
306
- Dir.glob(get_theme_dir("*")).map do |path|
307
- name = File.basename(path)
308
- name == "fonts" ? nil : name
309
- end.compact
310
- end
311
- memoize :get_theme_names
311
+ def theme_names
312
+ Dir.glob(get_theme_dir("*")).map do |path|
313
+ name = File.basename(path)
314
+ name == "fonts" ? nil : name
315
+ end.compact
316
+ end
317
+ memoize :theme_names
312
318
 
313
- def economy?(mode)
314
- eco_modes = Inventory.load("local_setting")["economy"].to_s.split(",").map(&:strip)
315
- eco_modes.include?(mode)
316
- end
319
+ def economy?(mode)
320
+ eco_modes = Inventory.load("local_setting")["economy"].to_s.split(",").map(&:strip)
321
+ eco_modes.include?(mode)
322
+ end
317
323
 
318
- def novel_type_text(type)
319
- type == 2 ? "短編" : "連載"
320
- end
324
+ def novel_type_text(type)
325
+ type == 2 ? "短編" : "連載"
326
+ end
321
327
 
322
- #
323
- # Narou.rb gem の最新バージョン番号を取得する
324
- #
325
- # rubygems公式APIによる取得は、WindowsでのSSL証明書問題で取得出来ない
326
- # 環境があるため、gemコマンド経由で取得する
327
- #
328
- def latest_version
329
- response = `gem search ^narou$`.split("\n")
330
- if response.last =~ /\Anarou \(([0-9.]+).*?\)\z/
331
- $1
328
+ #
329
+ # Narou.rb gem の最新バージョン番号を取得する
330
+ #
331
+ # rubygems公式APIによる取得は、WindowsでのSSL証明書問題で取得出来ない
332
+ # 環境があるため、gemコマンド経由で取得する
333
+ #
334
+ def latest_version
335
+ response = `gem search ^narou$`.split("\n")
336
+ if response.last =~ /\Anarou \(([0-9.]+).*?\)\z/
337
+ $1
338
+ end
332
339
  end
333
- end
334
340
 
335
- def commit_version
336
- cv_path = File.expand_path("commitversion", script_dir)
337
- File.read(cv_path) if File.exist?(cv_path)
338
- end
339
- memoize :commit_version
341
+ def commit_version
342
+ cv_path = File.expand_path("commitversion", script_dir)
343
+ File.read(cv_path) if File.exist?(cv_path)
344
+ end
345
+ memoize :commit_version
340
346
 
341
- def kindlegen_path
342
- postfix = Helper.os_windows? ? ".exe" : ""
343
- aozoraepub3_path.dirname.join("kindlegen#{postfix}")
344
- end
345
- memoize :kindlegen_path
347
+ def kindlegen_path
348
+ postfix = Helper.os_windows? ? ".exe" : ""
349
+ aozoraepub3_path.dirname.join("kindlegen#{postfix}")
350
+ end
351
+ memoize :kindlegen_path
346
352
 
347
- def line_height(default: LINE_HEIGHT_DEFAULT)
348
- global_setting = Inventory.load("global_setting", :global)
349
- global_setting["line-height"] || default
350
- end
353
+ def line_height(default: LINE_HEIGHT_DEFAULT)
354
+ global_setting = Inventory.load("global_setting", :global)
355
+ global_setting["line-height"] || default
356
+ end
351
357
 
352
- def concurrency_enabled?
353
- $stdout != $stdout2
354
- end
355
- memoize :concurrency_enabled?
358
+ def concurrency_enabled?
359
+ $stdout != $stdout2
360
+ end
361
+ memoize :concurrency_enabled?
356
362
 
357
- # 同時実行が有効ならキューに積んで、無効なら普通に実行する
358
- def concurrency_call(&block)
359
- if concurrency_enabled?
360
- Worker.push(&block)
361
- EXIT_SUCCESS
362
- else
363
- block.call
363
+ # 同時実行が有効ならキューに積んで、無効なら普通に実行する
364
+ def concurrency_call(&block)
365
+ if concurrency_enabled?
366
+ Worker.push(&block)
367
+ EXIT_SUCCESS
368
+ else
369
+ block.call
370
+ end
364
371
  end
365
372
  end
366
- end
367
373
  end