narou 1.7.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of narou might be problematic. Click here for more details.

Files changed (100) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +1 -0
  3. data/ChangeLog.md +35 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +100 -0
  6. data/README.md +28 -39
  7. data/lib/color.rb +0 -2
  8. data/lib/command.rb +1 -0
  9. data/lib/command/convert.rb +33 -4
  10. data/lib/command/diff.rb +5 -4
  11. data/lib/command/download.rb +9 -1
  12. data/lib/command/flag.rb +2 -2
  13. data/lib/command/list.rb +1 -1
  14. data/lib/command/mail.rb +3 -3
  15. data/lib/command/remove.rb +2 -1
  16. data/lib/command/send.rb +7 -6
  17. data/lib/command/setting.rb +39 -95
  18. data/lib/command/tag.rb +25 -13
  19. data/lib/command/update.rb +6 -1
  20. data/lib/command/version.rb +5 -1
  21. data/lib/command/web.rb +111 -0
  22. data/lib/commandbase.rb +5 -2
  23. data/lib/commandline.rb +16 -0
  24. data/lib/converterbase.rb +20 -14
  25. data/lib/device.rb +5 -4
  26. data/lib/downloader.rb +68 -39
  27. data/lib/eventable.rb +72 -0
  28. data/lib/helper.rb +105 -37
  29. data/lib/ini.rb +2 -1
  30. data/lib/input.rb +68 -0
  31. data/lib/inventory.rb +4 -0
  32. data/lib/kindlestrip.rb +2 -2
  33. data/lib/logger.rb +41 -19
  34. data/lib/narou.rb +10 -0
  35. data/lib/narou/api.rb +1 -1
  36. data/lib/novelconverter.rb +8 -21
  37. data/lib/novelsetting.rb +79 -4
  38. data/lib/version.rb +1 -1
  39. data/lib/web/all.rb +12 -0
  40. data/lib/web/appserver.rb +612 -0
  41. data/lib/web/helper4web.rb +15 -0
  42. data/lib/web/progressbar4web.rb +32 -0
  43. data/lib/web/public/favicon.ico +0 -0
  44. data/lib/web/public/resources/bootbox.min.js +6 -0
  45. data/lib/web/public/resources/common.ui.js +143 -0
  46. data/lib/web/public/resources/dataTables.colVis.js +1113 -0
  47. data/lib/web/public/resources/help/rect_select.png +0 -0
  48. data/lib/web/public/resources/help/ssmain.png +0 -0
  49. data/lib/web/public/resources/help/tag.png +0 -0
  50. data/lib/web/public/resources/jquery.moveto.js +44 -0
  51. data/lib/web/public/resources/jquery.outerclick.js +60 -0
  52. data/lib/web/public/resources/jquery.slidenavbar.js +89 -0
  53. data/lib/web/public/resources/narou.library.js +815 -0
  54. data/lib/web/public/resources/narou.ui.js +993 -0
  55. data/lib/web/public/resources/perfect-scrollbar.min.css +5 -0
  56. data/lib/web/public/resources/perfect-scrollbar.min.js +4 -0
  57. data/lib/web/public/resources/shortcut.js +223 -0
  58. data/lib/web/public/resources/sort_asc.png +0 -0
  59. data/lib/web/public/resources/sort_desc.png +0 -0
  60. data/lib/web/public/resources/toggle-switch.css +322 -0
  61. data/lib/web/public/robots.txt +3 -0
  62. data/lib/web/public/test/jquery.outerclick.html +72 -0
  63. data/lib/web/pushserver.rb +110 -0
  64. data/lib/web/settingmessages.rb +14 -0
  65. data/lib/web/streaminginput.rb +103 -0
  66. data/lib/web/streaminglogger.rb +52 -0
  67. data/lib/web/views/about.haml +11 -0
  68. data/lib/web/views/help.haml +105 -0
  69. data/lib/web/views/index.haml +245 -0
  70. data/lib/web/views/js/widget.erb +74 -0
  71. data/lib/web/views/layout.haml +49 -0
  72. data/lib/web/views/novels/setting.haml +177 -0
  73. data/lib/web/views/settings.haml +115 -0
  74. data/lib/web/views/style.scss +737 -0
  75. data/lib/web/views/widget.haml +39 -0
  76. data/lib/web/web-socket-ruby/.gitignore +1 -0
  77. data/lib/web/web-socket-ruby/README.txt +75 -0
  78. data/lib/web/web-socket-ruby/lib/web_socket.rb +601 -0
  79. data/lib/web/web-socket-ruby/samples/chat_server.rb +58 -0
  80. data/lib/web/web-socket-ruby/samples/echo_server.rb +33 -0
  81. data/lib/web/web-socket-ruby/samples/stdio_client.rb +25 -0
  82. data/lib/web/worker.rb +87 -0
  83. data/narou.gemspec +36 -3
  84. data/narou.rb +8 -6
  85. data/preset/ncode.syosetu.com/n8725k/converter.rb +2 -1
  86. data/spec/data/convert_test/replace/correct_test_replace.txt +1 -1
  87. data/spec/data/convert_test/replace/test_replace.txt +1 -1
  88. data/spec/data/convert_test/ruby/correct_test_ruby.txt +18 -1
  89. data/spec/data/convert_test/ruby/test_ruby.txt +18 -0
  90. data/spec/downloader_spec.rb +37 -0
  91. data/spec/eventable_spec.rb +172 -0
  92. data/spec/exit_code_spec.rb +67 -0
  93. data/spec/helper_spec.rb +72 -0
  94. data/spec/input_spec.rb +76 -0
  95. data/spec/logger_spec.rb +53 -0
  96. data/spec/novelsetting_spec.rb +35 -0
  97. data/spec/worker_spec.rb +56 -0
  98. data/template/ibunko_novel.txt.erb +2 -2
  99. data/template/novel.txt.erb +2 -2
  100. metadata +213 -29
data/lib/command/flag.rb CHANGED
@@ -77,11 +77,11 @@ module Command
77
77
  attribute = (argv.shift || "").downcase
78
78
  unless ATTRIBUTES.include?(attribute)
79
79
  error "有効なフラグを指定して下さい\n指定可能なフラグ:#{ATTRIBUTES.join(', ')}"
80
- exit 1
80
+ exit Narou::EXIT_ERROR_CODE
81
81
  end
82
82
  if argv.length < 1
83
83
  error "対象小説を指定して下さい"
84
- exit 1
84
+ exit Narou::EXIT_ERROR_CODE
85
85
  end
86
86
  database = Database.instance
87
87
  argv.each do |target|
data/lib/command/list.rb CHANGED
@@ -126,7 +126,7 @@ module Command
126
126
  else
127
127
  error "不明なフィルターです(#{item})"
128
128
  warn "filters = #{filter_type_help}"
129
- exit 1
129
+ exit Narou::EXIT_ERROR_CODE
130
130
  end
131
131
  sum + (apply ? 1 : 0)
132
132
  end
data/lib/command/mail.rb CHANGED
@@ -50,7 +50,7 @@ module Command
50
50
  return
51
51
  rescue Mailer::SettingUncompleteError => e
52
52
  error e.message
53
- exit 1
53
+ exit Narou::EXIT_ERROR_CODE
54
54
  end
55
55
  if argv.empty?
56
56
  send_all = true
@@ -97,12 +97,12 @@ module Command
97
97
  database[id]["last_mail_date"] = Time.now
98
98
  else
99
99
  error "#{mailer.error_message}"
100
- exit 1 # next しても次も失敗する可能性が高いのでここで終了
100
+ exit Narou::EXIT_ERROR_CODE # next しても次も失敗する可能性が高いのでここで終了
101
101
  end
102
102
  end
103
103
  rescue Interrupt
104
104
  puts "メール送信を中断しました"
105
- exit 1
105
+ exit Narou::EXIT_ERROR_CODE
106
106
  ensure
107
107
  database.save_database if database
108
108
  end
@@ -5,6 +5,7 @@
5
5
 
6
6
  require_relative "../narou"
7
7
  require_relative "../helper"
8
+ require_relative "../input"
8
9
 
9
10
  module Command
10
11
  class Remove < CommandBase
@@ -77,7 +78,7 @@ module Command
77
78
  next
78
79
  end
79
80
  unless @options["yes"]
80
- next unless Helper.confirm("#{title} を#{(@options["with-file"] ? "“完全に”" : "")}削除しますか")
81
+ next unless Narou::Input.confirm("#{title} を#{(@options["with-file"] ? "“完全に”" : "")}削除しますか")
81
82
  end
82
83
  Downloader.remove_novel(target, @options["with-file"])
83
84
  puts "<bold><green>#{TermColorLight.escape(title)} を削除しました</green></bold>".termcolor
data/lib/command/send.rb CHANGED
@@ -57,15 +57,15 @@ module Command
57
57
  error "デバイス名が指定されていないか、間違っています。\n" +
58
58
  "narou setting device=デバイス名 で指定出来ます。\n" +
59
59
  "指定出来るデバイス名:" + Device::DEVICES.keys.join(", ")
60
- exit 1
60
+ exit Narou::EXIT_ERROR_CODE
61
61
  end
62
62
  unless device.physical_support?
63
63
  error "#{device.display_name} への直接送信は対応していません"
64
- exit 1
64
+ exit Narou::EXIT_ERROR_CODE
65
65
  end
66
66
  unless device.connecting?
67
67
  error "#{device.display_name} が接続されていません"
68
- exit 1
68
+ exit Narou::EXIT_ERROR_CODE
69
69
  end
70
70
  send_all = false
71
71
  titles = {}
@@ -98,6 +98,7 @@ module Command
98
98
  print "#{device.name}へ送信しています"
99
99
  exit_copy = false
100
100
  copy_to_path = nil
101
+ Thread.abort_on_exception = true
101
102
  Thread.new do
102
103
  copy_to_path = device.copy_to_documents(ebook_path)
103
104
  exit_copy = true
@@ -111,12 +112,12 @@ module Command
111
112
  puts copy_to_path + " へコピーしました"
112
113
  else
113
114
  error "#{device.name}が見つからなかったためコピー出来ませんでした"
114
- exit 1 # next しても次も失敗すると分かりきっているためここで終了する
115
+ exit Narou::EXIT_ERROR_CODE # next しても次も失敗すると分かりきっているためここで終了する
115
116
  end
116
117
  end
117
- rescue Interrupt
118
+ rescue Device::SendFailure, Interrupt
118
119
  puts "送信を中断しました"
119
- exit 1
120
+ exit Narou::EXIT_ERROR_CODE
120
121
  end
121
122
  end
122
123
  end
@@ -5,34 +5,23 @@
5
5
 
6
6
  require_relative "../inventory"
7
7
  require_relative "../novelsetting"
8
+ require_relative "../eventable"
8
9
 
9
10
  module Command
10
11
  class Setting < CommandBase
12
+ include Narou::Eventable
13
+
11
14
  def self.oneline_help
12
15
  "各コマンドの設定を変更します"
13
16
  end
14
17
 
15
- class InvalidVariableType < StandardError
16
- def initialize(type)
17
- super("値が #{Setting.variable_type_to_description(type).rstrip} ではありません")
18
- end
19
- end
20
-
21
- class UnknownVariableType < StandardError
22
- def initialize(type)
23
- super("unknwon variable type (:#{type})")
24
- end
25
- end
26
-
27
- class InvalidVariableName < StandardError; end
28
-
29
18
  def initialize
30
19
  super("[<name>=<value> ...] [options]")
31
20
  @opt.separator <<-EOS
32
21
 
33
22
  ・各コマンドの設定の変更が出来ます。
34
- ・Global な設定はユーザープロファイルに保存され、すべての narou コマンドで使われます。
35
- ・下の一覧は一部です。すべてを確認するには -a オプションを付けて確認して下さい。
23
+ ・Global な設定はユーザープロファイルに保存され、すべての narou コマンドで使われます
24
+ ・下の一覧は一部です。すべてを確認するには -a オプションを付けて確認して下さい
36
25
 
37
26
  Local Variable List:
38
27
  <name> <value> 説明
@@ -64,25 +53,6 @@ module Command
64
53
  }
65
54
  end
66
55
 
67
- def self.variable_type_to_description(type)
68
- case type
69
- when :boolean
70
- "true/false "
71
- when :integer
72
- "整数 "
73
- when :float
74
- "小数点数 "
75
- when :string
76
- "文字列 "
77
- when :directory
78
- "フォルダパス"
79
- when :file
80
- "ファイルパス"
81
- else
82
- raise UnknownVariableType, type
83
- end
84
- end
85
-
86
56
  def get_scope_of_variable_name(name)
87
57
  [:local, :global].each do |scope|
88
58
  if SETTING_VARIABLES[scope].include?(name)
@@ -99,50 +69,12 @@ module Command
99
69
  def casting_variable(name, value)
100
70
  scope = get_scope_of_variable_name(name)
101
71
  unless scope
102
- raise InvalidVariableName, "#{name} は不明な名前です"
72
+ raise Helper::InvalidVariableName, "#{name} は不明な名前です"
103
73
  end
104
- casted_value = string_cast_to_type(value, SETTING_VARIABLES[scope][name][0])
74
+ casted_value = Helper.string_cast_to_type(value, SETTING_VARIABLES[scope][name][0])
105
75
  [scope, casted_value]
106
76
  end
107
77
 
108
- def string_cast_to_type(value, type)
109
- result = nil
110
- case type
111
- when :boolean
112
- case value
113
- when /true/i
114
- result = true
115
- when /false/i
116
- result = false
117
- else
118
- raise InvalidVariableType, type
119
- end
120
- when :integer
121
- if value =~ /^[+-]?\d+$/
122
- result = value.to_i
123
- else
124
- raise InvalidVariableType, type
125
- end
126
- when :float
127
- if value =~ /^[+-]?\d+\.?\d*$/
128
- result = value.to_f
129
- else
130
- raise InvalidVariableType, type
131
- end
132
- when :directory, :file
133
- if File.method("#{type}?").call(value)
134
- result = File.expand_path(value)
135
- else
136
- raise InvalidVariableType, type
137
- end
138
- when :string
139
- result = value
140
- else
141
- raise UnknownVariableType, type
142
- end
143
- result
144
- end
145
-
146
78
  def output_setting_list
147
79
  settings = {
148
80
  local: Inventory.load("local_setting", :local),
@@ -159,6 +91,12 @@ module Command
159
91
  end
160
92
  end
161
93
 
94
+ def output_error(msg, name = nil)
95
+ @error_count += 1
96
+ error msg
97
+ trigger(:error, msg, name)
98
+ end
99
+
162
100
  def execute(argv)
163
101
  super
164
102
  if argv.empty?
@@ -170,20 +108,21 @@ module Command
170
108
  global: Inventory.load("global_setting", :global)
171
109
  }
172
110
  device = Narou.get_device
111
+ @error_count = 0
173
112
  self.extend(device.get_hook_module) if device
174
113
  argv.each do |arg|
175
114
  name, value = arg.split("=", 2).map(&:strip)
176
115
  if name == ""
177
- error "書式が間違っています。変数名=値 のように書いて下さい"
116
+ output_error("書式が間違っています。変数名=値 のように書いて下さい")
178
117
  next
179
118
  end
180
119
  scope = get_scope_of_variable_name(name)
181
120
  unless scope
182
- error "#{name} という変数は存在しません"
121
+ output_error("#{name} という変数は存在しません", name)
183
122
  next
184
123
  end
185
124
  if value.nil?
186
- error "書式が間違っています。#{name}=値 のように書いて下さい"
125
+ output_error("書式が間違っています。#{name}=値 のように書いて下さい", name)
187
126
  next
188
127
  end
189
128
  if value == ""
@@ -192,14 +131,15 @@ module Command
192
131
  end
193
132
  begin
194
133
  scope, casted_value = casting_variable(name, value)
195
- rescue InvalidVariableName, InvalidVariableType => e
196
- error e.message
134
+ rescue Helper::InvalidVariableName, Helper::InvalidVariableType => e
135
+ output_error(e.message, name)
197
136
  next
198
137
  end
199
138
  hook_call(:modify_settings, settings[scope], name, casted_value)
200
139
  end
201
140
  settings[:local].save
202
141
  settings[:global].save
142
+ exit @error_count if @error_count > 0
203
143
  end
204
144
 
205
145
  def modify_settings(scoped_settings, name, value)
@@ -232,15 +172,14 @@ module Command
232
172
  puts message.string
233
173
  end
234
174
  rescue Device::UnknownDevice => e
235
- error e.message
236
- puts "設定できるのは #{Device::DEVICES.keys.join(", ")} です"
175
+ output_error("#{e.message}\n設定できるのは #{Device::DEVICES.keys.join(", ")} です", "device")
237
176
  end
238
177
 
239
178
  def get_variable_list_strings(scope)
240
179
  result = ""
241
180
  SETTING_VARIABLES[scope].each do |name, info|
242
181
  if @options["all"] || info[2] != INVISIBLE
243
- type_description = self.class.variable_type_to_description(info[0])
182
+ type_description = Helper.variable_type_to_description(info[0])
244
183
  result << " <bold><green>#{name.ljust(18)}</green></bold> #{type_description} #{info[1]}\n".termcolor
245
184
  end
246
185
  end
@@ -255,10 +194,9 @@ module Command
255
194
  puts get_variable_list_strings(:global).gsub(/^ {4}/, "")
256
195
  end
257
196
 
258
- TYPE_OF_VALUE = {
259
- TrueClass => :boolean, FalseClass => :boolean, Fixnum => :integer,
260
- Float => :float, String => :string
261
- }
197
+ def self.get_setting_variables
198
+ SETTING_VARIABLES
199
+ end
262
200
 
263
201
  INVISIBLE = true
264
202
 
@@ -269,16 +207,18 @@ module Command
269
207
  "convert.no-mobi" => [:boolean, "MOBI変換を無効にするか"],
270
208
  "convert.no-strip" => [:boolean, "MOBIのstripを無効にするか\n" +
271
209
  " " * 6 + "※注意:KDP用のMOBIはstripしないでください"],
272
- "convert.no-zip" => [:boolean, "i文庫用のzipファイルを作らない"],
273
- "convert.no-open" => [:boolean, "変換終了時に保存フォルダを開かない"],
210
+ "convert.no-zip" => [:boolean, "i文庫用のzipファイル作成を無効にするか"],
211
+ "convert.no-open" => [:boolean, "変換時に保存フォルダを開かないようにするか"],
274
212
  "convert.copy_to" => [:directory, "変換したらこのフォルダにコピーする\n" +
275
213
  " " * 6 + "※注意:存在しないフォルダだとエラーになる"],
276
214
  "convert.inspect" => [:boolean, "常に変換時に調査結果を表示するか"],
277
215
  "download.interval" => [:float, "各話DL時に指定した秒数待機する。デフォルト0"],
278
216
  "download.wait-steps" => [:integer, "この値で指定した話数ごとにウェイトを入れる\n" +
279
217
  " " * 6 + "※注意:11以上を設定してもなろうの場合は10話ごとにウェイトが入ります"],
218
+ "download.use-subdirectory" => [:boolean, "小説を一定数ごとにサブフォルダへ分けて保存するか\n" +
219
+ " " * 6 + "※注意:小説を大量に同一フォルダに保存するとパフォーマンスが劣化する回避策"],
280
220
  "send.without-freeze" => [:boolean, "`全話'送信時に凍結された小説は対象外に"],
281
- "update.strong" => [:boolean, "更新漏れが無いように改稿日の分は必ずDLする"],
221
+ "update.strong" => [:boolean, "更新漏れが無い様に改稿日の分は必ずDLするか"],
282
222
  "device" => [:string, "変換、送信対象の端末(sendの--help参照)"],
283
223
  "multiple-delimiter" => [:string, "--multiple指定時の区切り文字"],
284
224
  },
@@ -286,21 +226,25 @@ module Command
286
226
  "aozoraepub3dir" => [:directory, "AozoraEpub3のあるフォルダを指定", INVISIBLE],
287
227
  "difftool" => [:string, "Diffで使うツールのパスを指定する"],
288
228
  "difftool.arg" => [:string, "difftoolで使う引数を設定(オプション)"],
289
- "no-color" => [:boolean, "カラー表示を無効にする"],
290
- "over18" => [:boolean, "", INVISIBLE],
229
+ "no-color" => [:boolean, "カラー表示を無効にするか"],
230
+ "server-port" => [:integer, "WEBサーバ起動時のポート"],
231
+ "server-bind" => [:string, "WEBサーバのホスト制限(未設定時:起動PCのIP)", INVISIBLE],
232
+ "over18" => [:boolean, "18歳以上かどうか", INVISIBLE],
291
233
  }
292
234
  }
293
235
 
294
236
  NovelSetting::DEFAULT_SETTINGS.each do |default|
295
237
  SETTING_VARIABLES[:local]["force." + default[:name]] = [
296
- #TYPE_OF_VALUE[default[:value].class], "\n " + default[:help], INVISIBLE
297
- TYPE_OF_VALUE[default[:value].class], "", INVISIBLE
238
+ Helper.type_of_value(default[:value]), "\n " + default[:help], INVISIBLE
298
239
  ]
299
240
  end
300
241
 
301
242
  Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), "*.rb"))) do |path|
302
243
  cmd_name = File.basename(path, ".rb")
303
- SETTING_VARIABLES[:local]["default_args." + cmd_name] = [:string, "", INVISIBLE]
244
+ SETTING_VARIABLES[:local]["default_args." + cmd_name] =
245
+ [:string, "#{cmd_name} コマンドのデフォルトオプション", INVISIBLE]
304
246
  end
247
+
248
+ SETTING_VARIABLES.freeze
305
249
  end
306
250
  end
data/lib/command/tag.rb CHANGED
@@ -69,6 +69,28 @@ module Command
69
69
  }
70
70
  end
71
71
 
72
+ #
73
+ # タグ一覧取得
74
+ #
75
+ # ids: 特定の小説のタグだけ取得するためのIDの配列を指定
76
+ # @return: { "タグの名前" => タグが付けられた小説の数, ... }
77
+ #
78
+ def self.get_tag_list(ids = nil)
79
+ database = Database.instance
80
+ tag_list = Hash.new(0)
81
+ database.each do |_, data|
82
+ if ids.kind_of?(Array)
83
+ next unless ids.include?(data["id"])
84
+ end
85
+ tags = data["tags"] || []
86
+ tags.each do |tag|
87
+ tag_list[tag] += 1
88
+ end
89
+ end
90
+ tag_list.default = nil
91
+ tag_list
92
+ end
93
+
72
94
  def get_color_list
73
95
  COLORS.map { |color|
74
96
  "<bold><#{color}>#{color}</#{color}></bold>"
@@ -84,7 +106,7 @@ module Command
84
106
  return
85
107
  end
86
108
  error "対象の小説を指定して下さい"
87
- exit 1
109
+ exit Narou::EXIT_ERROR_CODE
88
110
  else
89
111
  if @options["mode"] == :list
90
112
  search_novel_by_tag(argv)
@@ -96,19 +118,9 @@ module Command
96
118
 
97
119
  def display_taglist
98
120
  database = Database.instance
99
- tags_list = {}
100
- database.each do |_, data|
101
- tags = data["tags"] || []
102
- tags.each do |tag|
103
- if tags_list[tag]
104
- tags_list[tag] += 1
105
- else
106
- tags_list[tag] = 1
107
- end
108
- end
109
- end
121
+ tag_list = Tag.get_tag_list
110
122
  puts "タグ一覧"
111
- puts tags_list.map { |tag, count|
123
+ puts tag_list.map { |tag, count|
112
124
  color = Tag.get_color(tag)
113
125
  "<bold><#{color}>#{TermColorLight.escape(tag)}(#{count})</#{color}></bold>"
114
126
  }.join(" ").termcolor
@@ -42,6 +42,7 @@ module Command
42
42
 
43
43
  def execute(argv)
44
44
  super
45
+ mistook_count = 0
45
46
  update_target_list = argv.dup
46
47
  no_open = false
47
48
  if update_target_list.empty?
@@ -66,6 +67,7 @@ module Command
66
67
  Helper.print_horizontal_rule if i > 0
67
68
  if display_message
68
69
  puts display_message
70
+ mistook_count += 1
69
71
  next
70
72
  end
71
73
  result = Downloader.start(target)
@@ -79,15 +81,18 @@ module Command
79
81
  end
80
82
  when :failed
81
83
  puts "ID:#{data["id"]} #{data["title"]} の更新は失敗しました"
84
+ mistook_count += 1
82
85
  when :canceled
83
86
  puts "ID:#{data["id"]} #{data["title"]} の更新はキャンセルされました"
87
+ mistook_count += 1
84
88
  when :none
85
89
  puts "#{data["title"]} に更新はありません"
86
90
  end
87
91
  end
92
+ exit mistook_count if mistook_count > 0
88
93
  rescue Interrupt
89
94
  puts "アップデートを中断しました"
90
- exit 1
95
+ exit Narou::EXIT_ERROR_CODE
91
96
  end
92
97
  end
93
98
  end