narou 1.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 (69) hide show
  1. data/.gitattributes +22 -0
  2. data/.gitignore +42 -0
  3. data/Gemfile +4 -0
  4. data/README.md +77 -0
  5. data/Rakefile +1 -0
  6. data/bin/narou +10 -0
  7. data/lib/command.rb +46 -0
  8. data/lib/command/alias.rb +82 -0
  9. data/lib/command/browser.rb +43 -0
  10. data/lib/command/convert.rb +227 -0
  11. data/lib/command/diff.rb +229 -0
  12. data/lib/command/download.rb +70 -0
  13. data/lib/command/folder.rb +39 -0
  14. data/lib/command/freeze.rb +75 -0
  15. data/lib/command/help.rb +51 -0
  16. data/lib/command/init.rb +134 -0
  17. data/lib/command/inspect.rb +59 -0
  18. data/lib/command/interactive.rb +16 -0
  19. data/lib/command/list.rb +70 -0
  20. data/lib/command/new.rb +12 -0
  21. data/lib/command/remove.rb +68 -0
  22. data/lib/command/send.rb +95 -0
  23. data/lib/command/setting.rb +259 -0
  24. data/lib/command/update.rb +78 -0
  25. data/lib/command/version.rb +16 -0
  26. data/lib/commandbase.rb +42 -0
  27. data/lib/commandline.rb +34 -0
  28. data/lib/converterbase.rb +916 -0
  29. data/lib/database.rb +104 -0
  30. data/lib/device.rb +89 -0
  31. data/lib/device/kindle.rb +10 -0
  32. data/lib/device/kobo.rb +10 -0
  33. data/lib/device/library/windows.rb +37 -0
  34. data/lib/downloader.rb +604 -0
  35. data/lib/globalsetting.rb +63 -0
  36. data/lib/helper.rb +113 -0
  37. data/lib/illustration.rb +93 -0
  38. data/lib/ini.rb +115 -0
  39. data/lib/inspector.rb +199 -0
  40. data/lib/kindlestrip.rb +249 -0
  41. data/lib/loadconverter.rb +90 -0
  42. data/lib/localsetting.rb +63 -0
  43. data/lib/logger.rb +61 -0
  44. data/lib/narou.rb +146 -0
  45. data/lib/novelconverter.rb +359 -0
  46. data/lib/novelsetting.rb +205 -0
  47. data/lib/progressbar.rb +33 -0
  48. data/lib/ruby.rb +152 -0
  49. data/lib/sitesetting.rb +64 -0
  50. data/lib/template.rb +65 -0
  51. data/lib/version.rb +11 -0
  52. data/narou.gemspec +35 -0
  53. data/narou.rb +28 -0
  54. data/preset/AozoraEpub3.ini +96 -0
  55. data/preset/DMincho.ttf +0 -0
  56. data/preset/bordersymbols.txt +1 -0
  57. data/preset/custom_chuki_tag.txt +22 -0
  58. data/preset/vertical_font.css +98 -0
  59. data/template/converter.rb.erb +18 -0
  60. data/template/diff.txt.erb +31 -0
  61. data/template/novel.txt.erb +39 -0
  62. data/template/replace.txt.erb +18 -0
  63. data/template/setting.ini.erb +9 -0
  64. data/test/data/test.ini +10 -0
  65. data/test/device_spec.rb +55 -0
  66. data/test/ini_spec.rb +145 -0
  67. data/webnovel/ncode.syosetu.com.yaml +32 -0
  68. data/webnovel/novel18.syosetu.com.yaml +32 -0
  69. metadata +118 -0
data/.gitattributes ADDED
@@ -0,0 +1,22 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+ *.sln merge=union
7
+ *.csproj merge=union
8
+ *.vbproj merge=union
9
+ *.fsproj merge=union
10
+ *.dbproj merge=union
11
+
12
+ # Standard to msysgit
13
+ *.doc diff=astextplain
14
+ *.DOC diff=astextplain
15
+ *.docx diff=astextplain
16
+ *.DOCX diff=astextplain
17
+ *.dot diff=astextplain
18
+ *.DOT diff=astextplain
19
+ *.pdf diff=astextplain
20
+ *.PDF diff=astextplain
21
+ *.rtf diff=astextplain
22
+ *.RTF diff=astextplain
data/.gitignore ADDED
@@ -0,0 +1,42 @@
1
+ #
2
+ # My Project (Narou.rb)
3
+ #
4
+ .backup/
5
+ 小説データ/
6
+ kindlestrip.py
7
+ kindlegen.exe
8
+ t.rb
9
+ 資料
10
+ AozoraEpub3
11
+ TODO.txt
12
+ MEMO.txt
13
+ .narou/
14
+ *.zip
15
+ debug
16
+
17
+ \#*\#
18
+
19
+ archive
20
+ commitversion
21
+
22
+ #
23
+ # for gem
24
+ #
25
+ *.gem
26
+ *.rbc
27
+ .bundle
28
+ .config
29
+ .yardoc
30
+ Gemfile.lock
31
+ InstalledFiles
32
+ _yardoc
33
+ coverage
34
+ doc/
35
+ lib/bundler/man
36
+ pkg
37
+ rdoc
38
+ spec/reports
39
+ test/tmp
40
+ test/version_tmp
41
+ tmp
42
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in narou.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ Narou.rb ― 小説家になろうダウンローダ&縦書用整形スクリプト
2
+ ============
3
+
4
+ 説明
5
+ ------------
6
+
7
+ 小説家になろうから小説をダウンロードして、縦書で読みやすいようにテキストを整形し、AozoraEPUB3を使ってEPUB化します。
8
+ 小説の更新管理もできます。
9
+
10
+ 超絶開発中なため、触れるな危険。
11
+
12
+ 必須ツール
13
+ ------------
14
+ * Ruby 1.9.3以上 (Windows: http://www.artonx.org/data/asr/, その他OS: 適当に)
15
+ * AozoraEpub3 1.1.0系 (http://www18.atwiki.jp/hmdev/pages/21.html)
16
+ * Java 6以降(AozoraEpub3で必須)
17
+ * kindlegen 2.7 (http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211)
18
+
19
+ 機能っぽい一覧
20
+ ------------
21
+ ```
22
+ Usage: narou <command> [arguments...] [options...]
23
+
24
+ コマンドの簡単な説明:
25
+ download 指定した小説をダウンロードします
26
+ update 小説を更新します
27
+ list 現在管理している小説の一覧を表示します
28
+ convert 小説を変換します。管理小説以外にテキストファイルも変換可能
29
+ diff アップデートされた小説の変更点を表示します
30
+ setting 各コマンドの設定を変更します
31
+ alias 小説のIDに紐付けた別名を作成します
32
+ inspect 小説状態の調査状況ログを表示します
33
+ send 変換したEPUB/MOBIを電子書籍端末に送信します
34
+ folder 小説の保存フォルダを開きます
35
+ browser 小説の掲載ページをブラウザで開きます
36
+ remove 小説を削除します
37
+ freeze 小説の凍結設定を行います
38
+ help このヘルプを表示します
39
+ version バージョンを表示します
40
+ init AozoraEpub3 の再設定を行います
41
+
42
+ 各コマンドの詳細は narou <command> -h/--help を参照してください。
43
+ 各コマンドは先頭の一文字か二文字でも指定できます。
44
+ (e.g. `narou d n4259s', `narou fr musyoku')
45
+ ```
46
+
47
+ インストール
48
+ ------------
49
+ * 事前に AozoraEpub3 をインストールしておきます。
50
+ → http://www18.atwiki.jp/hmdev/pages/21.html
51
+
52
+ * kindlegen を AozoraEpub3 をインストールしたフォルダにコピーします。
53
+ → http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211
54
+
55
+ * Narou.rb をインストールします。
56
+ コンソールで
57
+ ```
58
+ gem install narou
59
+ ```
60
+
61
+ * 小説の管理用として任意のフォルダで、
62
+ ```
63
+ narou init
64
+ ```
65
+ あとは画面の説明に従って下さい。
66
+
67
+ 使い方 - How To Use
68
+ -------------------
69
+ 基本的な使い方
70
+
71
+ narou init したフォルダで、narou <command> を適宜実行します。
72
+ ```
73
+ narou downlaod Nコード
74
+ narou update Nコード
75
+ narou convert Nコード
76
+ ```
77
+ 等と使います。
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/narou ADDED
@@ -0,0 +1,10 @@
1
+ #! ruby
2
+ # -*- mode: ruby -*-
3
+ # -*- coding: UTF-8 -*-
4
+ #
5
+ # Narou.rb ― 小説家になろうダウンロード&整形スクリプト
6
+ #
7
+ # Copyright 2013 whiteleaf. All rights reserved.
8
+ #
9
+
10
+ require_relative "../narou.rb"
data/lib/command.rb ADDED
@@ -0,0 +1,46 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ require "optparse"
7
+ require_relative "commandbase"
8
+ Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), "command", "*.rb"))) do |path|
9
+ require path
10
+ end
11
+
12
+ module Command
13
+ #
14
+ # コマンド一覧を取得
15
+ #
16
+ def self.get_list
17
+ COMMAND_LIST
18
+ end
19
+
20
+ COMMAND_LIST = {
21
+ "download" => Download.new,
22
+ "update" => Update.new,
23
+ "list" => List.new,
24
+ "convert" => Convert.new,
25
+ "diff" => Diff.new,
26
+ "setting" => Setting.new,
27
+ "alias" => Alias.new,
28
+ "inspect"=> Inspect.new,
29
+ "send" => Send.new,
30
+ "folder" => Folder.new,
31
+ "browser" => Browser.new,
32
+ "remove" => Remove.new,
33
+ "freeze" => Freeze.new,
34
+ "help" => Help.new,
35
+ "version" => Version.new,
36
+ #"new" => New.new,
37
+ #"interactive" => Interactive.new,
38
+ "init" => Init.new
39
+ }
40
+
41
+ # ショートカット定義
42
+ # COMMAND_LIST の上から順に優先度が高い
43
+ Shortcuts = Hash[*get_list.keys.reverse.map { |s|
44
+ [s[0], s, s[0..1], s]
45
+ }.flatten]
46
+ end
@@ -0,0 +1,82 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ require_relative "../localsetting"
7
+
8
+ module Command
9
+ class Alias < CommandBase
10
+ def initialize
11
+ super("[<alias_name>=<target> ...] [options]")
12
+ @opt.separator <<-EOS
13
+
14
+ ・小説のIDに紐付けた好きな別名を作ることが出来ます。IDやNコード等を覚える必要がなくなります。
15
+ ・<alias_name>にはアルファベット及び数字、アンダースコアが使用出来ます。
16
+ ・<target>は他のコマンドで指定出来るものがそのまま使えますが、すでにダウンロード済みである必要があります。
17
+
18
+ Example:
19
+ narou alias --list
20
+ narou alias musyoku=n9669bk
21
+ narou alias harem=1
22
+ narou convert harem # 他のコマンドで別名が使えるようになる
23
+ narou alias harem= # 右辺に何も書かないとその別名を解除できる
24
+
25
+ Options:
26
+ EOS
27
+ @opt.on("-l", "--list", "現在の割り当て一覧を表示する") {
28
+ output_aliases_list
29
+ exit 0
30
+ }
31
+ end
32
+
33
+ def output_aliases_list
34
+ aliases = LocalSetting.get["alias"]
35
+ database = Database.instance
36
+ aliases.each do |name, id|
37
+ title = database[id]["title"] rescue "(すでに削除されています)"
38
+ puts "#{name} = #{title}"
39
+ end
40
+ end
41
+
42
+ def execute(argv)
43
+ super
44
+ if argv.empty?
45
+ puts @opt.help
46
+ return
47
+ end
48
+ aliases = LocalSetting.get["alias"]
49
+ argv.each_with_index do |arg, i|
50
+ Helper.print_horizontal_rule if i > 0
51
+ alias_name, target = arg.split("=", 2)
52
+ unless alias_name =~ /^\w+$/
53
+ warn "別名にはアルファベット・数字・アンダースコアしか使えません"
54
+ next
55
+ end
56
+ if target.nil?
57
+ warn "書式が間違っています。#{alias_name}=別名 のように書いて下さい"
58
+ next
59
+ end
60
+ if target == ""
61
+ aliases.delete(alias_name)
62
+ puts "#{alias_name} を解除しました"
63
+ next
64
+ end
65
+ unless Downloader.novel_exists?(target)
66
+ warn "#{target} は存在しません"
67
+ next
68
+ end
69
+ data = Downloader.get_data_by_target(target)
70
+ id = data["id"]
71
+ title = data["title"]
72
+ aliases[alias_name] = id
73
+ puts "#{alias_name} を #{title} の別名に設定しました"
74
+ end
75
+ LocalSetting.get.save_settings
76
+ end
77
+
78
+ def oneline_help
79
+ "小説のIDに紐付けた別名を作成します"
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,43 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ require_relative "../localsetting"
7
+
8
+ module Command
9
+ class Browser < CommandBase
10
+ def initialize
11
+ super("<target> [<target2> ...]")
12
+ @opt.separator <<-EOS
13
+
14
+ ・指定した小説の掲載ページをブラウザで開きます。
15
+
16
+ Example:
17
+ narou browser n9669bk
18
+ narou browser musyoku
19
+ EOS
20
+ end
21
+
22
+ def execute(argv)
23
+ super
24
+ if argv.empty?
25
+ puts @opt.help
26
+ return
27
+ end
28
+ argv.each do |target|
29
+ toc_url = Downloader.get_toc_url(target)
30
+ unless toc_url
31
+ warn "#{target} は存在しません"
32
+ next
33
+ end
34
+ Helper.open_url_by_browser(toc_url)
35
+ puts toc_url
36
+ end
37
+ end
38
+
39
+ def oneline_help
40
+ "小説の掲載ページをブラウザで開きます"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,227 @@
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ require "fileutils"
7
+ require_relative "../database"
8
+ require_relative "../downloader"
9
+ require_relative "../novelconverter"
10
+ require_relative "../localsetting"
11
+ require_relative "../kindlestrip"
12
+
13
+ module Command
14
+ class Convert < CommandBase
15
+ @@database = Database.instance
16
+
17
+ def oneline_help
18
+ "小説を変換します。管理小説以外にテキストファイルも変換可能"
19
+ end
20
+
21
+ def initialize
22
+ super("<target> [<target2> ...] [option]")
23
+ @opt.separator <<-EOS
24
+
25
+ ・指定した小説を縦書用に整形及びEPUB、MOBIに変換します。
26
+ ・変換したい小説のNコード、URL、タイトルもしくはIDを指定して下さい。
27
+ IDは #{@opt.program_name} list を参照して下さい。
28
+ ・一度に複数の小説を指定する場合は空白で区切って下さい。
29
+ ※-oオプションがない場合、[変換]小説名.txtが小説の保存フォルダに出力されます
30
+ ・管理小説以外にもテキストファイルを変換出来ます。
31
+ テキストファイルのファイルパスを指定します。
32
+ ※複数指定した場合に-oオプションがあった場合、ファイル名に連番がつきます。
33
+ ・MOBI化する場合は narou setting device=kindle をして下さい。
34
+ ・device=kobo の場合、.kepub.epub を出力します。
35
+
36
+ Example:
37
+ narou convert n9669bk
38
+ narou convert http://ncode.syosetu.com/n9669bk/
39
+ narou convert 異世界迷宮で奴隷ハーレムを
40
+ narou convert 1 -o "ハーレム -変換済み-.txt"
41
+ narou convert mynovel.txt --enc sjis
42
+
43
+ Options:
44
+ EOS
45
+ @opt.on("-o FILE", "--output FILE", "出力ファイル名を指定する。フォルダパス部分は無視される") { |filename|
46
+ @options["output"] = filename
47
+ }
48
+ @opt.on("-e ENCODING", "--enc ENCODING",
49
+ "テキストファイル指定時の文字コードを指定する。デフォルトはUTF-8") { |encoding|
50
+ encoding = "utf-8" if encoding =~ /UTF8/i
51
+ @options["encoding"] = encoding
52
+ }
53
+ @opt.on("--no-epub", "AozoraEpub3でEPUB化しない") {
54
+ @options["no-epub"] = true
55
+ }
56
+ @opt.on("--no-mobi", "kindlegenでMOBI化しない") {
57
+ @options["no-mobi"] = true
58
+ }
59
+ @opt.on("--no-strip", "MOBIをstripしない") {
60
+ @options["no-strip"] = true
61
+ }
62
+ @opt.on("--no-open", "出力時に保存フォルダを開かない") {
63
+ @options["no-open"] = true
64
+ }
65
+ @opt.on("-i", "--inspect", "小説状態の調査結果を表示する") {
66
+ @options["inspect"] = true
67
+ }
68
+ @opt.separator <<-EOS
69
+
70
+ Configuration:
71
+ --no-epub, --no-mobi, --no-strip, --no-open , --inspect は narou setting コマンドで恒常的な設定にすることが可能です。
72
+ convert.copy_to を設定すれば変換したEPUB/MOBIを指定のフォルダに自動でコピー出来ます。
73
+ device で設定した端末が接続されていた場合、対応するデータを自動送信します。
74
+ 詳しくは narou setting --help を参照して下さい。
75
+ EOS
76
+ end
77
+
78
+ def load_local_settings
79
+ local_settings = LocalSetting.get["local_setting"]
80
+ local_settings.each do |name, value|
81
+ if name =~ /^convert\.(.+)$/
82
+ @options[$1] = value
83
+ end
84
+ end
85
+ end
86
+
87
+ def get_device
88
+ device_name = LocalSetting.get["local_setting"]["device"]
89
+ if device_name && Device.exists?(device_name)
90
+ return Device.new(device_name)
91
+ end
92
+ nil
93
+ end
94
+
95
+ def execute(argv)
96
+ load_local_settings # @opt.on 実行前に設定ロードしたいので super 前で実行する
97
+ super
98
+ if argv.empty?
99
+ puts @opt.help
100
+ return
101
+ end
102
+ @output_filename = @options["output"]
103
+ if @output_filename && argv.length > 1
104
+ @ext = File.extname(@output_filename)
105
+ @basename = File.basename(@output_filename, @ext)
106
+ else
107
+ @basename = nil
108
+ end
109
+ if @options["encoding"]
110
+ @enc = Encoding.find(@options["encoding"]) rescue nil
111
+ unless @enc
112
+ warn "--enc で指定された文字コードは存在しません。sjis, eucjp, utf-8 等を指定して下さい"
113
+ return
114
+ end
115
+ end
116
+ @device = get_device
117
+ convert_novels(argv)
118
+ end
119
+
120
+ def convert_novels(argv)
121
+ argv.each.with_index(1) do |target, i|
122
+ Helper.print_horizontal_rule if i > 1
123
+ @output_filename = @basename ? "#{@basename} (#{i})#{@ext}" : nil
124
+ if File.file?(target.to_s)
125
+ @argument_target_type = :file
126
+ res = convert_txt(target) or next
127
+ else
128
+ @argument_target_type = :novel
129
+ unless Downloader.novel_exists?(target)
130
+ warn "#{target} は存在しません"
131
+ next
132
+ end
133
+ res = NovelConverter.convert(target, @output_filename, @options["inspect"])
134
+ end
135
+ @converted_txt_path = res[:converted_txt_path]
136
+ @use_dakuten_font = res[:use_dakuten_font]
137
+ next unless @converted_txt_path
138
+
139
+ ebook_file = convert_txt_to_ebook_file
140
+ next if ebook_file.nil?
141
+ if ebook_file
142
+ copied_file_path = copy_to_converted_file(ebook_file)
143
+ if copied_file_path
144
+ puts copied_file_path.encode(Encoding::UTF_8) + " へコピーしました"
145
+ end
146
+ if @device && @device.connecting? && File.extname(ebook_file) == @device.ebook_file_ext
147
+ Send.execute_and_rescue_exit([@device.name, target])
148
+ end
149
+ end
150
+
151
+ unless @options["no-open"]
152
+ Helper.open_directory_by_os_filer(converted_txt_dir, "小説の保存フォルダを開きますか")
153
+ end
154
+ end
155
+ rescue Interrupt
156
+ puts
157
+ puts "変換を中断しました"
158
+ exit 1
159
+ end
160
+
161
+ def convert_txt(target)
162
+ return NovelConverter.convert_file(target, @enc, @output_filename, @options["inspect"])
163
+ rescue ArgumentError => e
164
+ if e.message =~ /invalid byte sequence in UTF-8/
165
+ warn "#{target}"
166
+ warn "テキストファイルの文字コードがUTF-8ではありません。" +
167
+ "--enc オプションでテキストの文字コードを指定して下さい"
168
+ warn "(#{e.message})"
169
+ return nil
170
+ else
171
+ raise
172
+ end
173
+ rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError
174
+ warn "#{target}"
175
+ warn "テキストファイルの文字コードは#{@options["encoding"]}ではありませんでした。" +
176
+ "正しい文字コードを指定して下さい"
177
+ return nil
178
+ end
179
+
180
+ def convert_txt_to_ebook_file
181
+ return false if @options["no-epub"]
182
+ # epub
183
+ status = NovelConverter.txt_to_epub(@converted_txt_path, @use_dakuten_font, nil, @device)
184
+ return nil if status != :success
185
+ if @device && @device.kobo?
186
+ epub_ext = @device.ebook_file_ext
187
+ else
188
+ epub_ext = ".epub"
189
+ end
190
+ epub_path = @converted_txt_path.sub(/.txt$/, epub_ext)
191
+
192
+ if !@device || !@device.kindle? || @options["no-mobi"]
193
+ return epub_path
194
+ end
195
+
196
+ # mobi
197
+ status = NovelConverter.epub_to_mobi(epub_path)
198
+ return nil if status != :success
199
+ mobi_path = epub_path.sub(/\.epub$/, @device.ebook_file_ext)
200
+
201
+ # strip
202
+ unless @options["no-strip"]
203
+ puts "kindlestrip実行中"
204
+ begin
205
+ SectionStripper.strip(mobi_path, nil, false)
206
+ rescue StripException => e
207
+ warn "Error: #{e.message}"
208
+ end
209
+ end
210
+ puts "MOBIファイルを出力しました"
211
+
212
+ return mobi_path
213
+ end
214
+
215
+ def copy_to_converted_file(src_path)
216
+ copy_to_dir = @options["copy_to"]
217
+ return nil unless copy_to_dir
218
+ if File.directory?(copy_to_dir)
219
+ FileUtils.copy(src_path, copy_to_dir)
220
+ return File.join(copy_to_dir, File.basename(src_path))
221
+ else
222
+ warn "#{copy_to_dir} はフォルダではないかすでに削除されています。コピー出来ませんでした"
223
+ return nil
224
+ end
225
+ end
226
+ end
227
+ end