Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions lib/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -400,28 +400,34 @@ def numeric_length(len)
# end
#
class AsyncCommand
def self.exec(command, sleep_time = 0.5, &block)
def self.exec(*command, &block)
looper = nil
_pid = nil
status, stdout, stderr = systemu(command) do |pid|
_pid = pid
looper = Thread.new(pid) do |pid|
require "open3"
stdout_str = +""
stderr_str = +""
status = nil
Open3.popen3(*command) do |_stdin, stdout, stderr, wait_thr|
_pid = wait_thr.pid
looper = Thread.new(_pid) do |pid|
loop do
block.call if block
sleep(sleep_time)
sleep(0.5)
next unless Narou::Worker.canceled?
next unless Narou::WebWorker.canceled?
Process.kill("KILL", pid)
Process.detach(pid)
Process.kill("KILL", pid) rescue nil
Process.detach(pid) rescue nil
break
end
end
looper.join
looper = nil
t_out = Thread.new { stdout.set_encoding(Encoding::UTF_8, Encoding::UTF_8, invalid: :replace, undef: :replace); stdout_str = stdout.read }
t_err = Thread.new { stderr.set_encoding(Encoding::UTF_8, Encoding::UTF_8, invalid: :replace, undef: :replace); stderr_str = stderr.read }
t_out.join
t_err.join
status = wait_thr.value
looper&.kill rescue nil
end
stdout.force_encoding(Encoding::UTF_8)
stderr.force_encoding(Encoding::UTF_8)
return [stdout, stderr, status]
return [stdout_str, stderr_str, status]
rescue RuntimeError => e
raise unless e.message.include?("interrupted")
process_kill(_pid)
Expand All @@ -430,7 +436,7 @@ def self.exec(command, sleep_time = 0.5, &block)
process_kill(_pid)
raise
ensure
looper&.kill
looper&.kill rescue nil
end

def self.process_kill(pid)
Expand Down
41 changes: 34 additions & 7 deletions lib/novelconverter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,47 @@ def self.txt_to_epub(filename, dst_dir: nil, device: nil, verbose: false, yokoga
if Helper.os_cygwin?
abs_srcpath = Helper.convert_to_windows_path(abs_srcpath)
end
Dir.chdir(aozoraepub3_dir)
command = %!java #{java_encoding} -cp #{aozoraepub3_basename} AozoraEpub3 -enc UTF-8 -of #{device_option} ! +
%!#{cover_option} #{dst_option} #{ext_option} #{yokogaki_option} "#{abs_srcpath}"!
if Helper.os_windows?
command = "cmd /c #{command}".encode(Encoding::Windows_31J)
end
temp_txt_name = "__temp_narou__.txt"
temp_epub_name = "__temp_narou__.epub"
temp_txt_path = File.join(src_dir, temp_txt_name)
temp_epub_path = File.join(src_dir, temp_epub_name)
target_epub_basename = File.basename(abs_srcpath, ".txt") + (device&.name == "Kobo" ? device.ebook_file_ext : ".epub")
target_epub_path = dst_dir ? File.join(File.expand_path(dst_dir), target_epub_basename) : File.join(src_dir, target_epub_basename)
FileUtils.cp(abs_srcpath, temp_txt_path)

java_cmd = File.exist?(File.join(aozoraepub3_dir, "jre", "bin", "java.exe")) ? File.join(aozoraepub3_dir, "jre", "bin", "java.exe") : "java"
command = [
java_cmd,
"-Dfile.encoding=UTF-8",
"-Dsun.jnu.encoding=UTF-8",
"-Dstdout.encoding=UTF-8",
"-Dstderr.encoding=UTF-8",
"-Dsun.stdout.encoding=UTF-8",
"-Dsun.stderr.encoding=UTF-8",
"-cp", aozoraepub3_path.to_s,
"AozoraEpub3",
"-enc", "UTF-8",
"-of"
]
command.concat(["-device", "kindle"]) if device&.name == "Kindle"
command.concat(["-ext", device.ebook_file_ext]) if device&.name == "Kobo"
command.concat(["-c", "0"]) if cover_filename
command << "-hor" if yokogaki
command << temp_txt_name

Dir.chdir(src_dir)
activate_dakuten_font_files if use_dakuten_font
stream_io.print "AozoraEpub3でEPUBに変換しています"
begin
res = Helper::AsyncCommand.exec(command) do
res = Helper::AsyncCommand.exec(*command) do
stream_io.print "."
end
if File.exist?(temp_epub_path)
FileUtils.mv(temp_epub_path, target_epub_path)
end
ensure
Dir.chdir(pwd)
FileUtils.rm_f(temp_txt_path)
inactivate_dakuten_font_files if use_dakuten_font
end

Expand Down
27 changes: 11 additions & 16 deletions webnovel/ncode.syosetu.com.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,44 +61,39 @@ narou_api_url: https://api.syosetu.com/novelapi/api/
novel_info_url: \\k<top_url>/novelview/infotop/ncode/\\k<ncode>/

# タイトル
t: <h1><a href=".+?">(?<title>.+?)</a></h1>
t: |-
<h1 class="p-infotop-title">\s*<a href=".+?">(?<title>.+?)</a>\s*</h1>

# novel_type 小説種別
nt: <span id="noveltype(?:.*?)">(?<novel_type>.+?)</span>
nt: <span class="p-infotop-type__type[^"]*">(?<novel_type>.+?)</span>
novel_type_string:
連載中: 1
完結済: 3
短編: 2

# general_all_no 掲載話数
ga: </span>全(?<general_all_no>\d+)エピソード
ga: 全(?<general_all_no>\d+)エピソード

# story あらすじ
s: <td class="ex">(?<story>.+?)</td>
s: |-
<dt class="p-infotop-data__title">あらすじ</dt>\s*<dd class="p-infotop-data__value">(?<story>.+?)</dd>

# general_firstup 初回掲載日
gf: |-
<th>掲載日</th>
<td>(?<general_firstup>.+?)</td>
<dt class="p-infotop-data__title">掲載日</dt>\s*<dd class="p-infotop-data__value">(?<general_firstup>.+?)</td>|<dt class="p-infotop-data__title">掲載日</dt>\s*<dd class="p-infotop-data__value">(?<general_firstup>.+?)</dd>

# novelupdated_at 小説の更新時刻。連載小説だと書いてないので最終掲載日で代用
nu: |-
<th>(?:最終更新日|最新掲載日|最終掲載日)</th>
<td>(?:
)?(?<novelupdated_at>.+?)(?:
)?</td>
<dt class="p-infotop-data__title">(?:最終更新日|最新掲載日|最終掲載日)</dt>\s*<dd class="p-infotop-data__value">(?<novelupdated_at>.+?)</dd>

# general_lastup 最終掲載日
gl: |-
<th>(?:最新掲載日|最終掲載日)</th>
<td>(?<general_lastup>.+?)</td>
<dt class="p-infotop-data__title">(?:最新掲載日|最終掲載日)</dt>\s*<dd class="p-infotop-data__value">(?<general_lastup>.+?)</dd>

# writer 作者名
w: |-
<th>作者名</th>
<td>(?:<a href=".+?">)?(?<writer>.+?)(?:</a>)?.?</td>
<dt class="p-infotop-data__title">作者名</dt>\s*<dd class="p-infotop-data__value">\s*(?:<a href=".+?">)?(?<writer>.+?)(?:</a>)?\s*</dd>

# length 文字数
l: |-
<th>文字数</th>
<td>(?<length>.+?)文字</td>
<dt class="p-infotop-data__title">文字数</dt>\s*<dd class="p-infotop-data__value">(?<length>.+?)文字</dd>
27 changes: 11 additions & 16 deletions webnovel/novel18.syosetu.com.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,44 +66,39 @@ narou_api_url: https://api.syosetu.com/novel18api/api/
novel_info_url: \\k<top_url>/novelview/infotop/ncode/\\k<ncode>/

# タイトル
t: <h1><a href=".+?">(?<title>.+?)</a></h1>
t: |-
<h1 class="p-infotop-title">\s*<a href=".+?">(?<title>.+?)</a>\s*</h1>

# novel_type 小説種別
nt: <span id="noveltype(?:.*?)">(?<novel_type>.+?)</span>
nt: <span class="p-infotop-type__type[^"]*">(?<novel_type>.+?)</span>
novel_type_string:
連載中: 1
完結済: 3
短編: 2

# general_all_no 掲載話数
ga: </span>全(?<general_all_no>\d+)エピソード
ga: 全(?<general_all_no>\d+)エピソード

# story あらすじ
s: <td class="ex">(?<story>.+?)</td>
s: |-
<dt class="p-infotop-data__title">あらすじ</dt>\s*<dd class="p-infotop-data__value">(?<story>.+?)</dd>

# general_firstup 初回掲載日
gf: |-
<th>掲載日</th>
<td>(?<general_firstup>.+?)</td>
<dt class="p-infotop-data__title">掲載日</dt>\s*<dd class="p-infotop-data__value">(?<general_firstup>.+?)</dd>

# novelupdated_at 小説の更新時刻。連載小説だと書いてないので最終掲載日で代用
nu: |-
<th>(?:最終更新日|最新掲載日|最終掲載日)</th>
<td>(?:
)?(?<novelupdated_at>.+?)(?:
)?</td>
<dt class="p-infotop-data__title">(?:最終更新日|最新掲載日|最終掲載日)</dt>\s*<dd class="p-infotop-data__value">(?<novelupdated_at>.+?)</dd>

# general_lastup 最終掲載日
gl: |-
<th>(?:最新掲載日|最終掲載日)</th>
<td>(?<general_lastup>.+?)</td>
<dt class="p-infotop-data__title">(?:最新掲載日|最終掲載日)</dt>\s*<dd class="p-infotop-data__value">(?<general_lastup>.+?)</dd>

# writer 作者名
w: |-
<th>作者名</th>
<td>(?:<a href=".+?">)?(?<writer>.+?)(?:</a>)?.?</td>
<dt class="p-infotop-data__title">作者名</dt>\s*<dd class="p-infotop-data__value">\s*(?:<a href=".+?">)?(?<writer>.+?)(?:</a>)?\s*</dd>

# length 文字数
l: |-
<th>文字数</th>
<td>(?<length>.+?)文字</td>
<dt class="p-infotop-data__title">文字数</dt>\s*<dd class="p-infotop-data__value">(?<length>.+?)文字</dd>