narou 1.4.6 → 1.5.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +15 -1
- data/README.md +14 -17
- data/Rakefile +12 -1
- data/lib/command/browser.rb +4 -3
- data/lib/command/folder.rb +1 -0
- data/lib/converterbase.rb +44 -26
- data/lib/downloader.rb +98 -40
- data/lib/helper.rb +1 -1
- data/lib/html.rb +83 -0
- data/lib/illustration.rb +44 -40
- data/lib/narou/api.rb +2 -35
- data/lib/novelconverter.rb +20 -0
- data/lib/novelinfo.rb +48 -0
- data/lib/novelsetting.rb +2 -2
- data/lib/sitesetting.rb +5 -0
- data/lib/version.rb +1 -1
- data/narou.gemspec +11 -3
- data/narou.rb +7 -6
- data/spec/data/html_test.html +5 -0
- data/spec/data/html_test.txt +4 -0
- data/{test → spec}/data/test.ini +0 -0
- data/{test → spec}/device_spec.rb +2 -18
- data/{test → spec}/generator/num_to_kanji_test_gen.rb +0 -0
- data/spec/html_spec.rb +60 -0
- data/{test → spec}/ini_spec.rb +0 -0
- data/spec/novelinfo_spec.rb +20 -0
- data/{test/num_to_kanji.rb → spec/num_to_kanji_spec.rb} +0 -1253
- data/spec/spec_helper.rb +16 -0
- data/template/novel.txt.erb +2 -0
- data/webnovel/ncode.syosetu.com.yaml +41 -3
- data/webnovel/novel18.syosetu.com.yaml +41 -3
- data/webnovel/syosetu.org.yaml +67 -0
- data/webnovel/www.mai-net.net.yaml +39 -0
- metadata +37 -17
- data/lib/watcher.rb +0 -61
- data/preset/narou_novel_info.yaml +0 -25
data/lib/helper.rb
CHANGED
@@ -108,7 +108,7 @@ module Helper
|
|
108
108
|
# エンティティ復号
|
109
109
|
#
|
110
110
|
def restor_entity(str)
|
111
|
-
result = str.
|
111
|
+
result = str.encode("UTF-16BE", "UTF-8", :invalid => :replace, :undef => :replace, :replace => "?").encode("UTF-8")
|
112
112
|
ENTITIES.each do |key, value|
|
113
113
|
result.gsub!("&#{key};", value)
|
114
114
|
end
|
data/lib/html.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright 2013 whiteleaf. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
class HTML
|
7
|
+
attr_accessor :string
|
8
|
+
|
9
|
+
def initialize(string = "")
|
10
|
+
@string = string
|
11
|
+
@illust_current_url = nil
|
12
|
+
@illust_grep_pattern = /<img.+?src=\"(?<src>.+?)\".*?>/i
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# 挿絵を置換するための設定を変更する
|
17
|
+
#
|
18
|
+
def set_illust_setting(options)
|
19
|
+
unless options.kind_of?(Hash)
|
20
|
+
raise ArgumentError, "invalid parameter(s), need Hash"
|
21
|
+
end
|
22
|
+
@illust_current_url = options[:current_url] if options[:current_url]
|
23
|
+
if grep_pattern = options[:grep_pattern]
|
24
|
+
@illust_grep_pattern = grep_pattern.kind_of?(Regexp) ? grep_pattern : /#{grep_pattern}/m
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# 青空文庫形式に変換
|
30
|
+
#
|
31
|
+
def to_aozora
|
32
|
+
@string = br_to_aozora
|
33
|
+
@string = ruby_to_aozora
|
34
|
+
@string = b_to_aozora
|
35
|
+
@string = i_to_aozora
|
36
|
+
@string = s_to_aozora
|
37
|
+
@string = img_to_aozora
|
38
|
+
@string = delete_tag
|
39
|
+
@string
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_tag(text = @string)
|
43
|
+
text.gsub(/<.+?>/, "")
|
44
|
+
end
|
45
|
+
|
46
|
+
def br_to_aozora(text = @string)
|
47
|
+
text.gsub(/[\r\n]+/, "").gsub(/<br.*?>/i, "\n")
|
48
|
+
end
|
49
|
+
|
50
|
+
def ruby_to_aozora(text = @string)
|
51
|
+
text.tr("《》", "≪≫")
|
52
|
+
.gsub(/<ruby>(.+?)<\/ruby>/i) do
|
53
|
+
splited_ruby = $1.split(/<rt>/i)
|
54
|
+
next delete_tag(splited_ruby[0]) unless splited_ruby[1]
|
55
|
+
ruby_base = delete_tag(splited_ruby[0].split(/<rp>/i)[0])
|
56
|
+
ruby_text = delete_tag(splited_ruby[1].split(/<rp>/i)[0])
|
57
|
+
"|#{ruby_base}《#{ruby_text}》"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def b_to_aozora(text = @string)
|
62
|
+
text.gsub(/<b>/i, "[#太字]").gsub(/<\/b>/i, "[#太字終わり]")
|
63
|
+
end
|
64
|
+
|
65
|
+
def i_to_aozora(text = @string)
|
66
|
+
text.gsub(/<i>/i, "[#斜体]").gsub(/<\/i>/i, "[#斜体終わり]")
|
67
|
+
end
|
68
|
+
|
69
|
+
def s_to_aozora(text = @string)
|
70
|
+
text.gsub(/<s>/i, "[#取消線]").gsub(/<\/s>/i, "[#取消線終わり]")
|
71
|
+
end
|
72
|
+
|
73
|
+
def img_to_aozora(text = @string)
|
74
|
+
if @illust_grep_pattern
|
75
|
+
text.gsub(@illust_grep_pattern) do
|
76
|
+
url = @illust_current_url ? URI.join(@illust_current_url, $~[:src]) : $~[:src]
|
77
|
+
"[#挿絵(#{url})入る]"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
text
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/illustration.rb
CHANGED
@@ -10,7 +10,8 @@ require "open-uri"
|
|
10
10
|
#
|
11
11
|
class Illustration
|
12
12
|
ILLUST_DIR = "挿絵/"
|
13
|
-
|
13
|
+
NAROU_ILLUST_URL = "http://%s.mitemin.net/userpageimage/viewimage/icode/%s/"
|
14
|
+
NAROU_ILLUST_TAG_PATTERN = /^<(i[0-9]+)\|([0-9]+)>\n?/m
|
14
15
|
|
15
16
|
MIME = { "image/jpeg" => "jpg", "image/png" => "png", "image/gif" => "gif", "image/bmp" => "bmp" }
|
16
17
|
|
@@ -21,60 +22,63 @@ class Illustration
|
|
21
22
|
@inspector = inspector
|
22
23
|
end
|
23
24
|
|
25
|
+
def scanner(source, &block)
|
26
|
+
source.gsub!(/[#挿絵((.+?))入る]/) do
|
27
|
+
url = $1
|
28
|
+
path = url =~ URI.regexp ? download_image(url) : url
|
29
|
+
path ? block.call(make_illust_chuki(path)) : ""
|
30
|
+
end
|
31
|
+
source.gsub!(NAROU_ILLUST_TAG_PATTERN) do
|
32
|
+
id1, id2 = $1, $2
|
33
|
+
basename = "#{id1},#{id2}.*"
|
34
|
+
url = NAROU_ILLUST_URL % [id2, id1]
|
35
|
+
path = download_image(url, basename)
|
36
|
+
path ? block.call(make_illust_chuki(path)) : ""
|
37
|
+
end
|
38
|
+
source
|
39
|
+
end
|
40
|
+
|
24
41
|
#
|
25
|
-
#
|
42
|
+
# 画像のURLからデータを保存して、保存したファイルの絶対パスを返す
|
26
43
|
#
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
illust_dir = File.dirname(illust_path)
|
39
|
-
Dir.mkdir(illust_dir) unless File.exists?(illust_dir)
|
40
|
-
open(illust_path, "wb") do |write_fp|
|
41
|
-
write_fp.write(read_fp.read)
|
42
|
-
end
|
43
|
-
@inspector.info("挿絵「#{File.basename(illust_path)}」を保存しました。")
|
44
|
-
end
|
44
|
+
def download_image(url, basename = nil)
|
45
|
+
basename = File.basename(basename ? basename : url, ".*")
|
46
|
+
if path = search_image(basename)
|
47
|
+
return path
|
48
|
+
end
|
49
|
+
open(url) do |fp|
|
50
|
+
content_type = fp.meta["content-type"]
|
51
|
+
ext = MIME[content_type] or raise UnknownMIMEType, content_type
|
52
|
+
illust_abs_path = create_illust_path(basename) + "." + ext
|
53
|
+
open(illust_abs_path, "wb") do |write_fp|
|
54
|
+
write_fp.write(fp.read)
|
45
55
|
end
|
46
|
-
|
47
|
-
|
48
|
-
else
|
49
|
-
# 有効なイラストタグではなかった
|
50
|
-
@inspector.error("Illustration#get: #{illust_tag} は有効なイラストタグではありません。")
|
51
|
-
nil
|
56
|
+
@inspector.info("挿絵「#{File.basename(illust_abs_path)}」を保存しました。")
|
57
|
+
return illust_abs_path
|
52
58
|
end
|
53
59
|
rescue UnknownMIMEType => e
|
54
|
-
@inspector.error("Illustration#
|
60
|
+
@inspector.error("Illustration#download_image: #{url} は未対応の画像フォーマットです" +
|
55
61
|
"(content-type: #{e.message})")
|
56
62
|
nil
|
57
63
|
rescue StandardError => e
|
58
|
-
@inspector.error("Illustration#
|
64
|
+
@inspector.error("Illustration#download_image: #{url} を処理中に例外が発生しました(#{e})")
|
59
65
|
nil
|
60
66
|
end
|
61
67
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
68
|
+
def search_image(basename)
|
69
|
+
path = create_illust_path(basename) + ".*"
|
70
|
+
Dir.glob(path)[0]
|
65
71
|
end
|
66
72
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
else
|
72
|
-
path
|
73
|
-
end
|
73
|
+
def create_illust_path(basename)
|
74
|
+
illust_abs_dir = File.join(@setting.archive_path, ILLUST_DIR)
|
75
|
+
Dir.mkdir(illust_abs_dir) unless File.exists?(illust_abs_dir)
|
76
|
+
File.join(illust_abs_dir, basename)
|
74
77
|
end
|
75
78
|
|
76
|
-
def
|
77
|
-
|
79
|
+
def make_illust_chuki(illust_path)
|
80
|
+
rel_illust_path = to_rel(@setting.archive_path, illust_path)
|
81
|
+
"[#挿絵(#{rel_illust_path})入る]"
|
78
82
|
end
|
79
83
|
|
80
84
|
#
|
data/lib/narou/api.rb
CHANGED
@@ -5,19 +5,13 @@
|
|
5
5
|
|
6
6
|
require "open-uri"
|
7
7
|
require "yaml"
|
8
|
-
|
9
|
-
require_relative "../sitesetting"
|
8
|
+
require_relative "../novelinfo"
|
10
9
|
|
11
10
|
module Narou
|
12
11
|
#
|
13
12
|
# 小説家になろうデベロッパーAPI操作クラス
|
14
13
|
#
|
15
14
|
class API
|
16
|
-
INFO_SETTING_FILE = "narou_novel_info.yaml"
|
17
|
-
NOVEL_TYPE = { "連載中" => 1, "完結済" => 1, "短編" => 2 }
|
18
|
-
|
19
|
-
@@novel_info_parameters = {}
|
20
|
-
|
21
15
|
#
|
22
16
|
# なろうデベロッパーAPIから情報を取得
|
23
17
|
#
|
@@ -49,7 +43,7 @@ module Narou
|
|
49
43
|
else
|
50
44
|
# なろうAPIからデータを取得出来なかった
|
51
45
|
# 開示設定が検索から除外に設定されるとAPIからはアクセスできなくなる
|
52
|
-
result =
|
46
|
+
result = NovelInfo.load(@setting)
|
53
47
|
unless result
|
54
48
|
error "小説家になろうからデータを取得出来ませんでした"
|
55
49
|
exit
|
@@ -58,32 +52,5 @@ module Narou
|
|
58
52
|
end
|
59
53
|
end
|
60
54
|
end
|
61
|
-
|
62
|
-
#
|
63
|
-
# 小説情報ページをパースして必要な情報を取り出す
|
64
|
-
#
|
65
|
-
def parse_novel_info
|
66
|
-
return @@novel_info_parameters[@ncode] if @@novel_info_parameters[@ncode]
|
67
|
-
result = {}
|
68
|
-
of = "nt-s-gf-nu-gl"
|
69
|
-
request_output_parameters = of.split("-")
|
70
|
-
info_source = ""
|
71
|
-
open(@setting["narou_info_url"]) do |fp|
|
72
|
-
info_source = Helper.pretreatment_source(fp.read)
|
73
|
-
end
|
74
|
-
info_setting = SiteSetting.load_file(File.join(Narou.get_preset_dir, INFO_SETTING_FILE))
|
75
|
-
info_setting.multi_match(info_source, *request_output_parameters)
|
76
|
-
result["novel_type"] = NOVEL_TYPE[info_setting["novel_type"]]
|
77
|
-
result["story"] = info_setting["story"].gsub("<br />", "")
|
78
|
-
%w(general_firstup novelupdated_at general_lastup).each do |elm|
|
79
|
-
result[elm] = date_string_to_time(info_setting[elm])
|
80
|
-
end
|
81
|
-
@@novel_info_parameters[@ncode] = result
|
82
|
-
result
|
83
|
-
end
|
84
|
-
|
85
|
-
def date_string_to_time(date)
|
86
|
-
date ? Time.parse(date.tr("年月日時分秒", "///:::")) : nil
|
87
|
-
end
|
88
55
|
end
|
89
56
|
end
|
data/lib/novelconverter.rb
CHANGED
@@ -14,6 +14,7 @@ require_relative "template"
|
|
14
14
|
require_relative "progressbar"
|
15
15
|
require_relative "helper"
|
16
16
|
require_relative "localsetting"
|
17
|
+
require_relative "html"
|
17
18
|
|
18
19
|
class NovelConverter
|
19
20
|
NOVEL_TEXT_TEMPLATE_NAME = "novel.txt"
|
@@ -21,6 +22,10 @@ class NovelConverter
|
|
21
22
|
|
22
23
|
attr_reader :use_dakuten_font
|
23
24
|
|
25
|
+
if Narou.already_init?
|
26
|
+
@@site_settings = Downloader.load_settings
|
27
|
+
end
|
28
|
+
|
24
29
|
#
|
25
30
|
# 指定の小説を整形・変換する
|
26
31
|
#
|
@@ -234,6 +239,8 @@ class NovelConverter
|
|
234
239
|
toc = @toc
|
235
240
|
cover_chuki = @cover_chuki
|
236
241
|
device = Narou.get_device
|
242
|
+
# タイトルがルビ化されてしまうのを抑制
|
243
|
+
toc["title"] = toc["title"].gsub("《", "※[#始め二重山括弧]").gsub("》", "※[#終わり二重山括弧]")
|
237
244
|
tempalte_name = (device && device.ibunko? ? NOVEL_TEXT_TEMPLATE_NAME_FOR_IBUNKO : NOVEL_TEXT_TEMPLATE_NAME)
|
238
245
|
Template.get(tempalte_name, binding)
|
239
246
|
end
|
@@ -264,6 +271,10 @@ class NovelConverter
|
|
264
271
|
end
|
265
272
|
end
|
266
273
|
|
274
|
+
def find_site_setting
|
275
|
+
@@site_settings.find { |s| s.multi_match(@toc["toc_url"], "url") }
|
276
|
+
end
|
277
|
+
|
267
278
|
#
|
268
279
|
# 変換処理メイン
|
269
280
|
#
|
@@ -286,6 +297,10 @@ class NovelConverter
|
|
286
297
|
@section_save_dir = Downloader.get_novel_section_save_dir(@setting.archive_path)
|
287
298
|
@toc = Downloader.get_toc_data(@setting.archive_path)
|
288
299
|
@toc["story"] = conv.convert(@toc["story"], "story")
|
300
|
+
html = HTML.new
|
301
|
+
site_setting = find_site_setting
|
302
|
+
html.set_illust_setting(current_url: site_setting["illust_current_url"],
|
303
|
+
grep_pattern: site_setting["illust_grep_pattern"])
|
289
304
|
progressbar = ProgressBar.new(@toc["subtitles"].count)
|
290
305
|
@toc["subtitles"].each_with_index do |subinfo, i|
|
291
306
|
progressbar.output(i)
|
@@ -295,7 +310,12 @@ class NovelConverter
|
|
295
310
|
end
|
296
311
|
@inspector.subtitle = section["subtitle"]
|
297
312
|
element = section["element"]
|
313
|
+
data_type = element.delete("data_type") || "text"
|
298
314
|
element.each do |text_type, elm_text|
|
315
|
+
if data_type == "html"
|
316
|
+
html.string = elm_text
|
317
|
+
elm_text = html.to_aozora
|
318
|
+
end
|
299
319
|
element[text_type] = conv.convert(elm_text, text_type)
|
300
320
|
end
|
301
321
|
section["subtitle"] = conv.convert(section["subtitle"], "subtitle")
|
data/lib/novelinfo.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright 2013 whiteleaf. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "open-uri"
|
7
|
+
require "time"
|
8
|
+
require_relative "sitesetting"
|
9
|
+
require_relative "html"
|
10
|
+
|
11
|
+
class NovelInfo
|
12
|
+
@@novel_info_parameters = {}
|
13
|
+
|
14
|
+
def self.load(setting)
|
15
|
+
info = new(setting)
|
16
|
+
info.parse_novel_info
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(setting)
|
20
|
+
@setting = setting
|
21
|
+
@ncode = @setting["ncode"]
|
22
|
+
@@novel_info_parameters[@setting["name"]] ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_novel_info
|
26
|
+
info_url = @setting["novel_info_url"] or return nil
|
27
|
+
result = @@novel_info_parameters[@setting["name"]][@ncode] ||= {}
|
28
|
+
return result unless result.empty?
|
29
|
+
of = "nt-s-gf-nu-gl-w"
|
30
|
+
request_output_parameters = of.split("-")
|
31
|
+
info_source = ""
|
32
|
+
open(info_url) do |fp|
|
33
|
+
info_source = Helper.pretreatment_source(fp.read, @setting["encoding"])
|
34
|
+
end
|
35
|
+
@setting.multi_match(info_source, *request_output_parameters)
|
36
|
+
result["novel_type"] = @setting["novel_type_string"][@setting["novel_type"]] || 1
|
37
|
+
result["story"] = @setting["story"]
|
38
|
+
result["writer"] = @setting["writer"]
|
39
|
+
%w(general_firstup novelupdated_at general_lastup).each do |elm|
|
40
|
+
result[elm] = date_string_to_time(@setting[elm])
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def date_string_to_time(date)
|
46
|
+
date ? Time.parse(date.sub(/[\((].+?[\))]/, "").tr("年月日時分秒", "///:::")) : nil
|
47
|
+
end
|
48
|
+
end
|
data/lib/novelsetting.rb
CHANGED
@@ -182,9 +182,9 @@ class NovelSetting
|
|
182
182
|
help: "ルビ処理を有効に"
|
183
183
|
},
|
184
184
|
{
|
185
|
-
name: "
|
185
|
+
name: "enable_illust",
|
186
186
|
value: true,
|
187
|
-
help: "
|
187
|
+
help: "挿絵タグを有効にする(false なら削除)"
|
188
188
|
},
|
189
189
|
{
|
190
190
|
name: "enable_transform_fraction",
|
data/lib/sitesetting.rb
CHANGED
@@ -51,8 +51,13 @@ class SiteSetting
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def is_container?(value)
|
55
|
+
value.kind_of?(Hash) || value.kind_of?(Array)
|
56
|
+
end
|
57
|
+
|
54
58
|
def replace_group_values(key, option_values = {})
|
55
59
|
dest = option_values[key] || @match_values[key] || @yaml_setting[key]
|
60
|
+
return dest if is_container?(dest)
|
56
61
|
begin
|
57
62
|
result = dest.dup
|
58
63
|
rescue TypeError
|
data/lib/version.rb
CHANGED
data/narou.gemspec
CHANGED
@@ -46,11 +46,19 @@ narou コマンドのインストール or アップデートが完了しまし
|
|
46
46
|
初めてこのアプリケーションを使う場合、小説管理用のフォルダを初期化する必要があります。
|
47
47
|
任意のフォルダで `narou init' を実行して下さい。
|
48
48
|
|
49
|
-
2014/
|
49
|
+
2014/03/06 : **1.5.0**
|
50
50
|
* 追加機能もしくは仕様変更
|
51
|
-
-
|
51
|
+
- 小説投稿サイト ハーメルン (http://syosetu.org/) に対応しました
|
52
|
+
- 小説投稿サイト Arcadia (http://www.mai-net.net/) に対応しました
|
53
|
+
+ Arcadiaは `narou d "http://www.mai-net.net/bbs/sst/sst.php?~略~&n=0&count=1"` のように
|
54
|
+
URLを " で囲まないとコマンドがきちんと通りませんのでご注意下さい
|
55
|
+
- このバージョン以降ダウンロードした小説の保存フォルダ名には、タイトルの前にIDが付加されるようになりました
|
56
|
+
- アラビア数字を漢数字に変換しないパターンを追加(%や単位系)
|
57
|
+
- `setting.ini` の項目、 `enable_narou_illust` が `enable_illust` に変更になりました
|
52
58
|
* Bug Fix
|
53
|
-
-
|
59
|
+
- `narou browser --vote` コマンドがなろうのレイアウト変更に対応していなかったので修正
|
60
|
+
- 半角カナを全角カナに変換するように修正 #36
|
61
|
+
- 小説のタイトルにはルビをふれないように修正 #37
|
54
62
|
|
55
63
|
#{"*" * 79}
|
56
64
|
EOS
|
data/narou.rb
CHANGED
@@ -7,11 +7,11 @@
|
|
7
7
|
#
|
8
8
|
|
9
9
|
$debug = File.exists?(File.join(File.expand_path(File.dirname($0)), "debug"))
|
10
|
-
watch = File.exists?(File.join(File.expand_path(File.dirname($0)), "watch"))
|
11
10
|
Encoding.default_external = Encoding::UTF_8
|
12
11
|
|
13
12
|
require_relative "lib/globalsetting"
|
14
13
|
|
14
|
+
display_time = ARGV.delete("--time")
|
15
15
|
display_backtrace = ARGV.delete("--backtrace")
|
16
16
|
display_backtrace ||= $debug
|
17
17
|
$disable_color = ARGV.delete("--no-color")
|
@@ -23,11 +23,11 @@ require_relative "lib/commandline"
|
|
23
23
|
|
24
24
|
rescue_level = $debug ? Exception : StandardError
|
25
25
|
|
26
|
-
if
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
if display_time
|
27
|
+
now = Time.now
|
28
|
+
at_exit do
|
29
|
+
puts "実行時間 #{Time.now - now}秒"
|
30
|
+
end
|
31
31
|
end
|
32
32
|
|
33
33
|
begin
|
@@ -44,3 +44,4 @@ rescue rescue_level => e
|
|
44
44
|
end
|
45
45
|
exit 1
|
46
46
|
end
|
47
|
+
|