narou 1.6.4 → 1.7.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 +13 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +419 -0
- data/ChangeLog.md +23 -0
- data/README.md +24 -123
- data/Rakefile +1 -1
- data/bin/narou +0 -0
- data/lib/color.rb +1 -8
- data/lib/command/backup.rb +1 -1
- data/lib/command/diff.rb +5 -5
- data/lib/command/download.rb +2 -2
- data/lib/command/freeze.rb +1 -9
- data/lib/command/init.rb +4 -4
- data/lib/command/list.rb +49 -20
- data/lib/command/mail.rb +4 -4
- data/lib/command/remove.rb +2 -3
- data/lib/command/send.rb +3 -3
- data/lib/command/tag.rb +6 -6
- data/lib/command/update.rb +2 -2
- data/lib/commandbase.rb +4 -4
- data/lib/commandline.rb +1 -1
- data/lib/converterbase.rb +27 -17
- data/lib/database.rb +1 -1
- data/lib/device.rb +1 -1
- data/lib/device/ibooks.rb +2 -2
- data/lib/device/ibunko.rb +2 -2
- data/lib/diffviewer.rb +7 -8
- data/lib/downloader.rb +22 -24
- data/lib/helper.rb +2 -2
- data/lib/illustration.rb +1 -1
- data/lib/ini.rb +0 -1
- data/lib/inspector.rb +2 -2
- data/lib/inventory.rb +1 -1
- data/lib/loadconverter.rb +1 -1
- data/lib/logger.rb +2 -14
- data/lib/mailer.rb +2 -2
- data/lib/narou.rb +5 -5
- data/lib/novelconverter.rb +4 -4
- data/lib/novelsetting.rb +1 -1
- data/lib/sitesetting.rb +1 -1
- data/lib/template.rb +2 -2
- data/lib/version.rb +2 -1
- data/narou.bat +0 -0
- data/narou.gemspec +15 -126
- data/narou.rb +1 -1
- data/preset/ncode.syosetu.com/n4259s/converter.rb +1 -1
- data/preset/ncode.syosetu.com/n8725k/converter.rb +1 -1
- data/spec/convert_spec.rb +6 -3
- data/spec/data/convert_test/auto_indent/correct_test_auto_indent.txt +3 -0
- data/spec/data/convert_test/auto_indent/test_auto_indent.txt +4 -0
- data/spec/data/convert_test/auto_join_bracket/correct_test_auto_join_bracket.txt +12 -1
- data/spec/data/convert_test/auto_join_bracket/test_auto_join_bracket.txt +12 -0
- data/spec/data/convert_test/auto_join_line/test_auto_join_line.txt +0 -0
- data/spec/data/convert_test/convert_page_break/test_convert_page_break.txt +0 -0
- data/spec/data/convert_test/english/correct_test_english.txt +26 -0
- data/spec/data/convert_test/english/test_english.txt +27 -0
- data/spec/data/convert_test/force_indent_special_chapter/test_force_indent_special_chapter.txt +0 -0
- data/spec/data/convert_test/horizontal_ellipsis/test_horizontal_ellipsis.txt +0 -0
- data/spec/data/convert_test/kanji_num/test_kanji_num.txt +0 -0
- data/spec/data/convert_test/nonokagi/test_nonokagi.txt +0 -0
- data/spec/data/convert_test/replace/correct_test_replace.txt +1 -1
- data/spec/data/convert_test/replace/replace.txt +0 -0
- data/spec/data/convert_test/replace/test_replace.txt +0 -0
- data/spec/data/convert_test/ruby/correct_test_ruby.txt +3 -1
- data/spec/data/convert_test/ruby/test_ruby.txt +3 -0
- data/spec/data/convert_test/ruby_youon/test_ruby_youon.txt +0 -0
- data/spec/data/convert_test/sesame/test_sesame.txt +0 -0
- data/spec/data/convert_test/to_odd_leader/test_to_odd_leader.txt +0 -0
- data/spec/generator/convert_spec_gen.rb +2 -3
- data/spec/spec_helper.rb +2 -2
- metadata +29 -162
- data/lib/ruby.rb +0 -152
data/lib/command/mail.rb
CHANGED
@@ -45,7 +45,7 @@ module Command
|
|
45
45
|
database = Database.instance
|
46
46
|
begin
|
47
47
|
mailer = Mailer.create
|
48
|
-
rescue Mailer::SettingNotFound
|
48
|
+
rescue Mailer::SettingNotFound
|
49
49
|
install_mailer_setting
|
50
50
|
return
|
51
51
|
rescue Mailer::SettingUncompleteError => e
|
@@ -73,13 +73,13 @@ module Command
|
|
73
73
|
next # すでに送信済みなので送信しない
|
74
74
|
end
|
75
75
|
end
|
76
|
-
unless File.
|
76
|
+
unless File.exist?(ebook_path)
|
77
77
|
error "まだファイル(#{File.basename(ebook_path)})が無いようです" unless send_all
|
78
78
|
next
|
79
79
|
end
|
80
80
|
id = data["id"]
|
81
81
|
title = data["title"]
|
82
|
-
puts "<bold><green>ID:#{id} #{
|
82
|
+
puts "<bold><green>ID:#{id} #{TermColorLight.escape(title)}</green></bold>".termcolor
|
83
83
|
print "メールを送信しています"
|
84
84
|
exit_mail = false
|
85
85
|
mail_result = nil
|
@@ -120,7 +120,7 @@ module Command
|
|
120
120
|
|
121
121
|
def alter_database_add_column_last_mail_date
|
122
122
|
database = Database.instance
|
123
|
-
database.each do |
|
123
|
+
database.each do |_, data|
|
124
124
|
data["last_mail_date"] ||= Time.now
|
125
125
|
end
|
126
126
|
database.save_database
|
data/lib/command/remove.rb
CHANGED
@@ -51,10 +51,9 @@ module Command
|
|
51
51
|
|
52
52
|
def execute(argv)
|
53
53
|
super
|
54
|
-
novels = []
|
55
54
|
if @options["all-ss"]
|
56
55
|
novels = get_all_short_story
|
57
|
-
if novels.
|
56
|
+
if novels.size == 0
|
58
57
|
puts "短編小説がひとつもありません"
|
59
58
|
return
|
60
59
|
end
|
@@ -81,7 +80,7 @@ module Command
|
|
81
80
|
next unless Helper.confirm("#{title} を#{(@options["with-file"] ? "“完全に”" : "")}削除しますか")
|
82
81
|
end
|
83
82
|
Downloader.remove_novel(target, @options["with-file"])
|
84
|
-
puts "<bold><green>#{
|
83
|
+
puts "<bold><green>#{TermColorLight.escape(title)} を削除しました</green></bold>".termcolor
|
85
84
|
end
|
86
85
|
end
|
87
86
|
end
|
data/lib/command/send.rb
CHANGED
@@ -84,13 +84,13 @@ module Command
|
|
84
84
|
error "#{target} は存在しません"
|
85
85
|
next
|
86
86
|
end
|
87
|
-
unless File.
|
87
|
+
unless File.exist?(ebook_path)
|
88
88
|
error "まだファイル(#{File.basename(ebook_path)})が無いようです" unless send_all
|
89
89
|
next
|
90
90
|
end
|
91
91
|
if send_all
|
92
92
|
if device.ebook_file_old?(ebook_path)
|
93
|
-
puts "<bold><green>ID:#{target} #{
|
93
|
+
puts "<bold><green>ID:#{target} #{TermColorLight.escape(titles[target])}</green></bold>".termcolor
|
94
94
|
else
|
95
95
|
next
|
96
96
|
end
|
@@ -114,7 +114,7 @@ module Command
|
|
114
114
|
exit 1 # next しても次も失敗すると分かりきっているためここで終了する
|
115
115
|
end
|
116
116
|
end
|
117
|
-
rescue Interrupt
|
117
|
+
rescue Interrupt
|
118
118
|
puts "送信を中断しました"
|
119
119
|
exit 1
|
120
120
|
end
|
data/lib/command/tag.rb
CHANGED
@@ -56,7 +56,7 @@ module Command
|
|
56
56
|
}
|
57
57
|
@opt.on("-c", "--color COL", String,
|
58
58
|
"タグの色を自分で指定する\n" \
|
59
|
-
"#{' '*25}COL=#{get_color_list}"
|
59
|
+
"#{' '*25}COL=#{get_color_list}") { |color|
|
60
60
|
color.downcase!
|
61
61
|
unless COLORS.include?(color)
|
62
62
|
error "#{color}という色は存在しません。色指定は無視されます"
|
@@ -72,7 +72,7 @@ module Command
|
|
72
72
|
def get_color_list
|
73
73
|
COLORS.map { |color|
|
74
74
|
"<bold><#{color}>#{color}</#{color}></bold>"
|
75
|
-
}.join(",")
|
75
|
+
}.join(",").termcolor
|
76
76
|
end
|
77
77
|
|
78
78
|
def execute(argv)
|
@@ -110,7 +110,7 @@ module Command
|
|
110
110
|
puts "タグ一覧"
|
111
111
|
puts tags_list.map { |tag, count|
|
112
112
|
color = Tag.get_color(tag)
|
113
|
-
"<bold><#{color}>#{
|
113
|
+
"<bold><#{color}>#{TermColorLight.escape(tag)}(#{count})</#{color}></bold>"
|
114
114
|
}.join(" ").termcolor
|
115
115
|
end
|
116
116
|
|
@@ -145,11 +145,11 @@ module Command
|
|
145
145
|
set_color(tag, @options["color"])
|
146
146
|
end
|
147
147
|
end
|
148
|
-
if tags.
|
148
|
+
if tags.size > 0
|
149
149
|
print "現在のタグは "
|
150
150
|
print tags.map { |tagname|
|
151
151
|
color = Tag.get_color(tagname)
|
152
|
-
"<bold><#{color}>#{
|
152
|
+
"<bold><#{color}>#{TermColorLight.escape(tagname)}</#{color}></bold>"
|
153
153
|
}.join(" ").termcolor
|
154
154
|
puts " です"
|
155
155
|
end
|
@@ -163,7 +163,7 @@ module Command
|
|
163
163
|
color = @@tag_colors[tagname]
|
164
164
|
return color if color
|
165
165
|
last_color = @@tag_colors.values.last || COLORS.last
|
166
|
-
index = (COLORS.index(last_color) + 1) % COLORS.
|
166
|
+
index = (COLORS.index(last_color) + 1) % COLORS.size
|
167
167
|
color = COLORS[index]
|
168
168
|
@@tag_colors[tagname] = color
|
169
169
|
@@tag_colors.save
|
data/lib/command/update.rb
CHANGED
@@ -71,8 +71,8 @@ module Command
|
|
71
71
|
result = Downloader.start(target)
|
72
72
|
case result.status
|
73
73
|
when :ok
|
74
|
-
unless @options["no-convert"]
|
75
|
-
(@options["convert-only-new-arrival"]
|
74
|
+
unless @options["no-convert"] ||
|
75
|
+
(@options["convert-only-new-arrival"] && !result.new_arrivals)
|
76
76
|
convert_argv = [target]
|
77
77
|
convert_argv << "--no-open" if no_open
|
78
78
|
Convert.execute!(convert_argv)
|
data/lib/commandbase.rb
CHANGED
@@ -14,7 +14,7 @@ module Command
|
|
14
14
|
banner = postfixies.split("\n").map.with_index { |postfix, i|
|
15
15
|
(i == 0 ? "Usage: " : " or: ") + "narou #{command_name} #{postfix}"
|
16
16
|
}.join("\n")
|
17
|
-
@opt.banner = "<bold><green>#{
|
17
|
+
@opt.banner = "<bold><green>#{TermColorLight.escape(banner)}</green></bold>".termcolor
|
18
18
|
@options = {}
|
19
19
|
# ヘルプを見やすく色付け
|
20
20
|
def @opt.help
|
@@ -25,11 +25,11 @@ module Command
|
|
25
25
|
end
|
26
26
|
# Examples のコメント部分
|
27
27
|
msg.gsub!(/(#.+)$/) do
|
28
|
-
"<cyan>#{
|
28
|
+
"<cyan>#{TermColorLight.escape($1)}</cyan>".termcolor
|
29
29
|
end
|
30
30
|
# 文字列部分
|
31
31
|
msg.gsub!(/(".+?")/) do
|
32
|
-
"<yellow>#{
|
32
|
+
"<yellow>#{TermColorLight.escape($1)}</yellow>".termcolor
|
33
33
|
end
|
34
34
|
msg
|
35
35
|
end
|
@@ -87,7 +87,7 @@ module Command
|
|
87
87
|
0
|
88
88
|
end
|
89
89
|
|
90
|
-
def self.oneline_help
|
90
|
+
def self.oneline_help
|
91
91
|
""
|
92
92
|
end
|
93
93
|
|
data/lib/commandline.rb
CHANGED
data/lib/converterbase.rb
CHANGED
@@ -12,6 +12,8 @@ require_relative "inspector"
|
|
12
12
|
|
13
13
|
class ConverterBase
|
14
14
|
KANJI_NUM = "〇一二三四五六七八九"
|
15
|
+
ENGLISH_SENTENCES_CHARACTERS = /[\w.,!?'" &:;_-]+/
|
16
|
+
ENGLISH_SENTENCES_MIN_LENGTH = 8 # この文字数以上アルファベットが続くと半角のまま
|
15
17
|
|
16
18
|
attr_reader :use_dakuten_font
|
17
19
|
|
@@ -192,7 +194,7 @@ class ConverterBase
|
|
192
194
|
m1 = total.to_s.tr("0-9", KANJI_NUM)
|
193
195
|
if m1 =~ /〇{#{lower_digit_zero},}$/
|
194
196
|
digits = m1.reverse.scan(/.{1,4}/).map(&:reverse).reverse # 下の桁から4桁ずつ区切った配列を作成
|
195
|
-
keta = digits.
|
197
|
+
keta = digits.size - 1
|
196
198
|
digits.map.with_index { |nums, keta_i|
|
197
199
|
four_digit_num = nums.scan(/./).map.with_index { |d, di|
|
198
200
|
next "" if d == "〇"
|
@@ -245,7 +247,7 @@ class ConverterBase
|
|
245
247
|
target_num = "\d0-9#{KANJI_NUM}十百千万億兆京垓"
|
246
248
|
data.gsub!(/[#{target_num}\//]+/) do |match|
|
247
249
|
numerics = match.split(/[\//]/)
|
248
|
-
case numerics.
|
250
|
+
case numerics.size
|
249
251
|
when 2
|
250
252
|
# 分数
|
251
253
|
if @setting.enable_transform_fraction
|
@@ -470,6 +472,8 @@ class ConverterBase
|
|
470
472
|
#
|
471
473
|
# force : 強制的に全アルファベットを全角にするか?
|
472
474
|
# false の場合、英文章(半角スペースで区切られた2単語以上)を半角のままにする
|
475
|
+
# 英文の定義: 1. 半角スペースで区切られた2単語以上の文章、
|
476
|
+
# 2. 一定以上の長さの一文字以上アルファベットを含む文章
|
473
477
|
#
|
474
478
|
def alphabet_to_zenkaku(data, force = false)
|
475
479
|
if force
|
@@ -477,10 +481,11 @@ class ConverterBase
|
|
477
481
|
match.tr("a-zA-Z", "a-zA-Z")
|
478
482
|
end
|
479
483
|
else
|
480
|
-
|
481
|
-
if match.split(" ").
|
484
|
+
data.gsub!(ENGLISH_SENTENCES_CHARACTERS) do |match|
|
485
|
+
if match.split(" ").size >= 2 \
|
486
|
+
|| (match.length >= ENGLISH_SENTENCES_MIN_LENGTH && match.match(/[a-z]/i))
|
482
487
|
@english_sentences << match
|
483
|
-
"[#英文=#{@english_sentences.
|
488
|
+
"[#英文=#{@english_sentences.size - 1}]"
|
484
489
|
else
|
485
490
|
match.tr("a-zA-Z", "a-zA-Z")
|
486
491
|
end
|
@@ -592,7 +597,6 @@ class ConverterBase
|
|
592
597
|
@@count_of_rebuild_container ||= 0
|
593
598
|
data.gsub!(/^[ \t]*([-―<<〈-]*)([0-90-9#{KANJI_NUM}]{1,3})([-―>>〉-]*)$/) do
|
594
599
|
top, chapter, bottom = $1, $2, $3
|
595
|
-
pre, post = $`, $'
|
596
600
|
if top != "" && "―--".include?(top) # include?は空文字("")だとtrueなのでチェック必須
|
597
601
|
top = "― "
|
598
602
|
bottom = " ―"
|
@@ -854,7 +858,7 @@ class ConverterBase
|
|
854
858
|
ten =~ /^[・、]+$/ && (str.include?("|") || object_of_ruby?(last_char))
|
855
859
|
end
|
856
860
|
|
857
|
-
def sesame(str
|
861
|
+
def sesame(str)
|
858
862
|
if str.include?("|")
|
859
863
|
str.sub("|", "[#傍点]") + "[#傍点終わり]"
|
860
864
|
else
|
@@ -880,7 +884,7 @@ class ConverterBase
|
|
880
884
|
# 直前に|がある場合ルビ化は抑制される
|
881
885
|
"#{m1[0...-1]}#{openclose_symbols[0]}#{m2}#{openclose_symbols[1]}"
|
882
886
|
when is_sesame?(m1, m2, last_char)
|
883
|
-
sesame(m1
|
887
|
+
sesame(m1)
|
884
888
|
when m1.include?("|")
|
885
889
|
"#{m1.sub(/|([^|]*)$/, "[#ルビ用縦線]\\1")}《#{m2}》"
|
886
890
|
when object_of_ruby?(last_char)
|
@@ -922,9 +926,9 @@ class ConverterBase
|
|
922
926
|
# URL っぽい文字列を一旦別のIDに置き換えてあとで復元することで、変換処理の影響を受けさせない
|
923
927
|
#
|
924
928
|
def replace_url(data)
|
925
|
-
data.gsub!(URI.regexp) do |match|
|
929
|
+
data.gsub!(URI.regexp(%w(http https))) do |match|
|
926
930
|
@url_list << match
|
927
|
-
"[#URL=#{@url_list.
|
931
|
+
"[#URL=#{@url_list.size - 1}]"
|
928
932
|
end
|
929
933
|
end
|
930
934
|
|
@@ -943,7 +947,7 @@ class ConverterBase
|
|
943
947
|
@illustration.scanner(data) do |chuki|
|
944
948
|
next "" unless @setting.enable_illust
|
945
949
|
@illust_chuki_list << chuki
|
946
|
-
"[#挿絵=#{@illust_chuki_list.
|
950
|
+
"[#挿絵=#{@illust_chuki_list.size - 1}]\n"
|
947
951
|
end
|
948
952
|
end
|
949
953
|
|
@@ -1089,10 +1093,6 @@ class ConverterBase
|
|
1089
1093
|
convert_special_characters(data)
|
1090
1094
|
convert_fraction_and_date(data)
|
1091
1095
|
modify_kana_ni_to_kanji_ni(data)
|
1092
|
-
if @text_type == "body" || @text_type == "textfile"
|
1093
|
-
half_indent_bracket(data)
|
1094
|
-
auto_indent(data)
|
1095
|
-
end
|
1096
1096
|
convert_dakuten_char_to_font(data)
|
1097
1097
|
end
|
1098
1098
|
|
@@ -1128,8 +1128,10 @@ class ConverterBase
|
|
1128
1128
|
when "postscript"
|
1129
1129
|
return @write_fp if @setting.enable_erase_postscript
|
1130
1130
|
end
|
1131
|
+
title_and_author = nil
|
1131
1132
|
if @text_type == "textfile"
|
1132
|
-
|
1133
|
+
# タイトル・著者名スキップ
|
1134
|
+
title_and_author = io.gets + io.gets
|
1133
1135
|
data = io.read
|
1134
1136
|
else
|
1135
1137
|
data = io.read
|
@@ -1188,6 +1190,10 @@ class ConverterBase
|
|
1188
1190
|
rebuild_hankaku_num_and_comma(data)
|
1189
1191
|
rebuild_kome_to_gaiji(data)
|
1190
1192
|
rebuild_force_indent_special_chapter(data)
|
1193
|
+
if @text_type == "body" || @text_type == "textfile"
|
1194
|
+
half_indent_bracket(data)
|
1195
|
+
auto_indent(data)
|
1196
|
+
end
|
1191
1197
|
# 再構築された文章にルビがふられる可能性を考慮して、
|
1192
1198
|
# この位置でルビの処理を行う
|
1193
1199
|
narou_ruby(data) if @setting.enable_ruby
|
@@ -1196,7 +1202,11 @@ class ConverterBase
|
|
1196
1202
|
# ルビ化されなくて残ったギュメを二重山括弧(の外字)に変換
|
1197
1203
|
convert_double_angle_quotation_to_gaiji(data)
|
1198
1204
|
delete_dust_char(data)
|
1199
|
-
|
1205
|
+
if title_and_author
|
1206
|
+
puts title_and_author
|
1207
|
+
data.replace(title_and_author + data)
|
1208
|
+
end
|
1209
|
+
data.rstrip!
|
1200
1210
|
progressbar.clear if @text_type == "textfile"
|
1201
1211
|
@write_fp
|
1202
1212
|
end
|
data/lib/database.rb
CHANGED
data/lib/device.rb
CHANGED
@@ -94,7 +94,7 @@ class Device
|
|
94
94
|
documents_path = get_documents_path
|
95
95
|
if documents_path
|
96
96
|
dst_path = File.join(documents_path, File.basename(src_file))
|
97
|
-
if File.
|
97
|
+
if File.exist?(dst_path)
|
98
98
|
return File.mtime(src_file) > File.mtime(dst_path)
|
99
99
|
end
|
100
100
|
end
|
data/lib/device/ibooks.rb
CHANGED
@@ -25,7 +25,7 @@ module Device::Ibooks
|
|
25
25
|
"force.enable_half_indent_bracket" => false,
|
26
26
|
})
|
27
27
|
@@__ibooks_container_dir = File.expand_path(IBOOKS_CONTAINER_DIR)
|
28
|
-
unless File.
|
28
|
+
unless File.exist?(@@__ibooks_container_dir)
|
29
29
|
error "iBooksの管理フォルダが見つかりませんでした。" \
|
30
30
|
"MacOSX Mavericks以降のiBooksのみ管理に対応しています"
|
31
31
|
@@__ibooks_container_dir = nil
|
@@ -46,7 +46,7 @@ module Device::Ibooks
|
|
46
46
|
end
|
47
47
|
@toc_url = @novel_data["toc_url"]
|
48
48
|
epubdir_path = get_epubdir_path_in_ibooks_container
|
49
|
-
if epubdir_path && File.
|
49
|
+
if epubdir_path && File.exist?(epubdir_path)
|
50
50
|
extract_epub(ebook_file_path, epubdir_path)
|
51
51
|
puts "iBooksに登録してあるEPUBを更新しました"
|
52
52
|
else
|
data/lib/device/ibunko.rb
CHANGED
@@ -26,12 +26,12 @@ module Device::Ibunko
|
|
26
26
|
dirpath = File.dirname(@converted_txt_path)
|
27
27
|
translate_illust_chuki_to_img_tag
|
28
28
|
zipfile_path = @converted_txt_path.sub(/.txt$/, @device.ebook_file_ext)
|
29
|
-
File.delete(zipfile_path) if File.
|
29
|
+
File.delete(zipfile_path) if File.exist?(zipfile_path)
|
30
30
|
Zip::File.open(zipfile_path, Zip::File::CREATE) do |zip|
|
31
31
|
zip.add(File.basename(@converted_txt_path), @converted_txt_path)
|
32
32
|
illust_dirpath = File.join(dirpath, Illustration::ILLUST_DIR)
|
33
33
|
# 挿絵
|
34
|
-
if File.
|
34
|
+
if File.exist?(illust_dirpath)
|
35
35
|
Dir.glob(File.join(illust_dirpath, "*")) do |img_path|
|
36
36
|
zip.add(File.join(Illustration::ILLUST_DIR, File.basename(img_path)), img_path)
|
37
37
|
end
|
data/lib/diffviewer.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require "diff/lcs"
|
7
|
-
require "termcolor"
|
8
7
|
|
9
8
|
#
|
10
9
|
# 指定されたソースの差分を作成する
|
@@ -91,7 +90,7 @@ class DiffViewer
|
|
91
90
|
# differ には Diff::LCS.sdiff で処理したものをそのまま渡す
|
92
91
|
#
|
93
92
|
def calc_levenshtein_distance(differ)
|
94
|
-
differ.reject { |e| e.unchanged? }.
|
93
|
+
differ.reject { |e| e.unchanged? }.size
|
95
94
|
end
|
96
95
|
|
97
96
|
#
|
@@ -113,12 +112,12 @@ class DiffViewer
|
|
113
112
|
if normalized_distance > 0.7
|
114
113
|
# 双方の文字列があまりにも似ていない場合、編集部分をカラー化すると
|
115
114
|
# 非常に見づらい表示になってしまうので、単純に削除・追加のみ装飾する
|
116
|
-
old_str =
|
117
|
-
new_str =
|
115
|
+
old_str = TermColorLight.escape(old_element)
|
116
|
+
new_str = TermColorLight.escape(new_element)
|
118
117
|
else
|
119
118
|
line_events.each do |e|
|
120
|
-
os =
|
121
|
-
ns =
|
119
|
+
os = TermColorLight.escape(e.old_element) rescue ""
|
120
|
+
ns = TermColorLight.escape(e.new_element) rescue ""
|
122
121
|
case e.action
|
123
122
|
when "="
|
124
123
|
old_str += os
|
@@ -138,9 +137,9 @@ class DiffViewer
|
|
138
137
|
result = "<bold><red>-#{old_str}</red>\n" \
|
139
138
|
"<green>+#{new_str}</green></bold>"
|
140
139
|
when "-"
|
141
|
-
result = "<bold><red>-#{
|
140
|
+
result = "<bold><red>-#{TermColorLight.escape(old_element)}</red></bold>"
|
142
141
|
when "+"
|
143
|
-
result = "<bold><green>+#{
|
142
|
+
result = "<bold><green>+#{TermColorLight.escape(new_element)}</green></bold>"
|
144
143
|
end
|
145
144
|
result.termcolor
|
146
145
|
end
|
data/lib/downloader.rb
CHANGED
@@ -118,7 +118,6 @@ class Downloader
|
|
118
118
|
target = Narou.alias_to_id(target)
|
119
119
|
type = get_target_type(target)
|
120
120
|
data = nil
|
121
|
-
id = nil
|
122
121
|
case type
|
123
122
|
when :url, :ncode
|
124
123
|
toc_url = get_toc_url(target)
|
@@ -132,7 +131,7 @@ class Downloader
|
|
132
131
|
id = data["id"]
|
133
132
|
file_title = data["file_title"] || data["title"] # 互換性維持のための処理
|
134
133
|
path = File.join(Database.archive_root_path, data["sitename"], file_title)
|
135
|
-
if File.
|
134
|
+
if File.exist?(path)
|
136
135
|
return path
|
137
136
|
else
|
138
137
|
@@database.delete(id)
|
@@ -325,7 +324,6 @@ class Downloader
|
|
325
324
|
end
|
326
325
|
end
|
327
326
|
|
328
|
-
|
329
327
|
#
|
330
328
|
# ダウンロードを処理本体を起動
|
331
329
|
#
|
@@ -380,7 +378,7 @@ class Downloader
|
|
380
378
|
id_and_title = "#{@id} #{@title}"
|
381
379
|
|
382
380
|
return_status =
|
383
|
-
if update_subtitles.
|
381
|
+
if update_subtitles.size > 0
|
384
382
|
@cache_dir = create_cache_dir if old_toc.length > 0
|
385
383
|
begin
|
386
384
|
sections_download_and_save(update_subtitles)
|
@@ -394,7 +392,7 @@ class Downloader
|
|
394
392
|
end
|
395
393
|
update_database
|
396
394
|
:ok
|
397
|
-
elsif old_toc["subtitles"].
|
395
|
+
elsif old_toc["subtitles"].size > latest_toc["subtitles"].size
|
398
396
|
# 削除された節がある(かつ更新がない)場合
|
399
397
|
puts "#{id_and_title} は一部の話が削除されています"
|
400
398
|
:ok
|
@@ -419,7 +417,7 @@ class Downloader
|
|
419
417
|
end
|
420
418
|
else
|
421
419
|
if tags.include?("end")
|
422
|
-
update_database if update_subtitles.
|
420
|
+
update_database if update_subtitles.size == 0
|
423
421
|
$stdout.silence do
|
424
422
|
Command::Tag.execute!([@id, "--delete", "end"])
|
425
423
|
end
|
@@ -439,8 +437,8 @@ class Downloader
|
|
439
437
|
#
|
440
438
|
def process_digest(old_toc, latest_toc)
|
441
439
|
return false unless old_toc["subtitles"]
|
442
|
-
latest_subtitles_count = latest_toc["subtitles"].
|
443
|
-
old_subtitles_count = old_toc["subtitles"].
|
440
|
+
latest_subtitles_count = latest_toc["subtitles"].size
|
441
|
+
old_subtitles_count = old_toc["subtitles"].size
|
444
442
|
if latest_subtitles_count < old_subtitles_count
|
445
443
|
STDOUT.puts "#{latest_toc["title"]}"
|
446
444
|
STDOUT.puts "更新後の話数が保存されている話数より減少していることを検知しました"
|
@@ -730,7 +728,7 @@ class Downloader
|
|
730
728
|
latest_section_timestamp_ymd = __strdate_to_ymd(get_section_file_timestamp(old, latest))
|
731
729
|
section_file_name = "#{index} #{old["file_subtitle"]}.yaml"
|
732
730
|
section_file_relative_path = File.join(SECTION_SAVE_DIR_NAME, section_file_name)
|
733
|
-
different_check =
|
731
|
+
different_check = lambda do
|
734
732
|
latest_info_dummy = latest.dup
|
735
733
|
latest_info_dummy["element"] = a_section_download(latest)
|
736
734
|
deffer = different_section?(section_file_relative_path, latest_info_dummy)
|
@@ -741,7 +739,7 @@ class Downloader
|
|
741
739
|
File.utime(now, now, File.join(get_novel_data_dir, section_file_relative_path))
|
742
740
|
end
|
743
741
|
deffer
|
744
|
-
|
742
|
+
end
|
745
743
|
end
|
746
744
|
if old_subupdate && latest_subupdate
|
747
745
|
if old_subupdate == ""
|
@@ -822,14 +820,14 @@ class Downloader
|
|
822
820
|
# subtitles にダウンロードしたいものをまとめた subtitle info を渡す
|
823
821
|
#
|
824
822
|
def sections_download_and_save(subtitles)
|
825
|
-
max = subtitles.
|
823
|
+
max = subtitles.size
|
826
824
|
return if max == 0
|
827
|
-
puts
|
825
|
+
puts "<bold><green>#{"ID:#{@id} #{get_title}".escape} のDL開始</green></bold>".termcolor
|
828
826
|
save_least_one = false
|
829
827
|
subtitles.each_with_index do |subtitle_info, i|
|
830
828
|
index, subtitle, file_subtitle, chapter = %w(index subtitle file_subtitle chapter).map { |k|
|
831
|
-
|
832
|
-
|
829
|
+
subtitle_info[k]
|
830
|
+
}
|
833
831
|
unless chapter.empty?
|
834
832
|
puts "#{chapter}"
|
835
833
|
end
|
@@ -844,9 +842,9 @@ class Downloader
|
|
844
842
|
print "#{subtitle} (#{i+1}/#{max})"
|
845
843
|
info = subtitle_info.dup
|
846
844
|
info["element"] = a_section_download(subtitle_info)
|
847
|
-
section_file_name = "#{
|
845
|
+
section_file_name = "#{index} #{file_subtitle}.yaml"
|
848
846
|
section_file_relative_path = File.join(SECTION_SAVE_DIR_NAME, section_file_name)
|
849
|
-
if File.
|
847
|
+
if File.exist?(File.join(get_novel_data_dir, section_file_relative_path))
|
850
848
|
if @force
|
851
849
|
if different_section?(section_file_relative_path, info)
|
852
850
|
print " (更新あり)"
|
@@ -873,7 +871,7 @@ class Downloader
|
|
873
871
|
#
|
874
872
|
def different_section?(old_relative_path, new_subtitle_info)
|
875
873
|
path = File.join(get_novel_data_dir, old_relative_path)
|
876
|
-
if File.
|
874
|
+
if File.exist?(path)
|
877
875
|
return YAML.load_file(path)["element"] != new_subtitle_info["element"]
|
878
876
|
else
|
879
877
|
return true
|
@@ -885,7 +883,7 @@ class Downloader
|
|
885
883
|
#
|
886
884
|
def move_to_cache_dir(relative_path)
|
887
885
|
path = File.join(get_novel_data_dir, relative_path)
|
888
|
-
if File.
|
886
|
+
if File.exist?(path) && @cache_dir
|
889
887
|
FileUtils.mv(path, @cache_dir)
|
890
888
|
end
|
891
889
|
end
|
@@ -982,7 +980,7 @@ class Downloader
|
|
982
980
|
|
983
981
|
def init_raw_dir
|
984
982
|
path = get_raw_dir
|
985
|
-
FileUtils.mkdir_p(path) unless File.
|
983
|
+
FileUtils.mkdir_p(path) unless File.exist?(path)
|
986
984
|
end
|
987
985
|
|
988
986
|
#
|
@@ -1062,7 +1060,7 @@ class Downloader
|
|
1062
1060
|
def save_novel_data(filename, object)
|
1063
1061
|
path = File.join(get_novel_data_dir, filename)
|
1064
1062
|
dir_path = File.dirname(path)
|
1065
|
-
unless File.
|
1063
|
+
unless File.exist?(dir_path)
|
1066
1064
|
FileUtils.mkdir_p(dir_path)
|
1067
1065
|
end
|
1068
1066
|
File.write(path, YAML.dump(object))
|
@@ -1083,15 +1081,15 @@ class Downloader
|
|
1083
1081
|
def init_novel_dir
|
1084
1082
|
novel_dir_path = get_novel_data_dir
|
1085
1083
|
file_title = File.basename(novel_dir_path)
|
1086
|
-
FileUtils.mkdir_p(novel_dir_path) unless File.
|
1084
|
+
FileUtils.mkdir_p(novel_dir_path) unless File.exist?(novel_dir_path)
|
1087
1085
|
default_settings = NovelSetting::DEFAULT_SETTINGS
|
1088
1086
|
special_preset_dir = File.join(Narou.get_preset_dir, @setting["domain"], @setting["ncode"])
|
1089
|
-
exists_special_preset_dir = File.
|
1087
|
+
exists_special_preset_dir = File.exist?(special_preset_dir)
|
1090
1088
|
[NovelSetting::INI_NAME, "converter.rb", NovelSetting::REPLACE_NAME].each do |filename|
|
1091
1089
|
if exists_special_preset_dir
|
1092
1090
|
preset_file_path = File.join(special_preset_dir, filename)
|
1093
|
-
if File.
|
1094
|
-
unless File.
|
1091
|
+
if File.exist?(preset_file_path)
|
1092
|
+
unless File.exist?(File.join(novel_dir_path, filename))
|
1095
1093
|
FileUtils.cp(preset_file_path, novel_dir_path)
|
1096
1094
|
end
|
1097
1095
|
next
|