narou 1.1.1 → 1.1.2

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 (62) hide show
  1. data/ChangeLog.md +17 -1
  2. data/README.md +18 -12
  3. data/bin/narou +1 -1
  4. data/lib/color.rb +89 -0
  5. data/lib/command.rb +1 -1
  6. data/lib/command/alias.rb +5 -5
  7. data/lib/command/browser.rb +4 -2
  8. data/lib/command/convert.rb +14 -12
  9. data/lib/command/diff.rb +8 -8
  10. data/lib/command/download.rb +1 -1
  11. data/lib/command/folder.rb +2 -2
  12. data/lib/command/freeze.rb +1 -1
  13. data/lib/command/help.rb +8 -6
  14. data/lib/command/init.rb +8 -8
  15. data/lib/command/inspect.rb +2 -2
  16. data/lib/command/interactive.rb +1 -1
  17. data/lib/command/list.rb +5 -2
  18. data/lib/command/new.rb +1 -1
  19. data/lib/command/remove.rb +2 -2
  20. data/lib/command/send.rb +7 -7
  21. data/lib/command/setting.rb +8 -8
  22. data/lib/command/update.rb +2 -2
  23. data/lib/command/version.rb +1 -1
  24. data/lib/commandbase.rb +6 -4
  25. data/lib/commandline.rb +2 -2
  26. data/lib/converterbase.rb +81 -44
  27. data/lib/database.rb +1 -1
  28. data/lib/device.rb +3 -3
  29. data/lib/device/kindle.rb +1 -1
  30. data/lib/device/kobo.rb +1 -1
  31. data/lib/device/library/windows.rb +2 -14
  32. data/lib/downloader.rb +41 -14
  33. data/lib/extensions/windows.rb +58 -0
  34. data/lib/globalsetting.rb +1 -1
  35. data/lib/helper.rb +1 -1
  36. data/lib/illustration.rb +1 -1
  37. data/lib/ini.rb +1 -1
  38. data/lib/inspector.rb +2 -2
  39. data/lib/kindlestrip.rb +1 -1
  40. data/lib/loadconverter.rb +2 -2
  41. data/lib/localsetting.rb +1 -1
  42. data/lib/logger.rb +26 -9
  43. data/lib/narou.rb +1 -1
  44. data/lib/narou/api.rb +41 -0
  45. data/lib/novelconverter.rb +14 -14
  46. data/lib/novelsetting.rb +7 -2
  47. data/lib/progressbar.rb +1 -1
  48. data/lib/ruby.rb +1 -1
  49. data/lib/sitesetting.rb +1 -1
  50. data/lib/template.rb +3 -3
  51. data/lib/version.rb +2 -2
  52. data/narou.gemspec +3 -2
  53. data/narou.rb +5 -3
  54. data/template/converter.rb.erb +1 -1
  55. data/template/diff.txt.erb +1 -1
  56. data/template/novel.txt.erb +2 -1
  57. data/template/replace.txt.erb +2 -2
  58. data/template/setting.ini.erb +1 -1
  59. data/webnovel/ncode.syosetu.com.yaml +2 -1
  60. data/webnovel/novel18.syosetu.com.yaml +2 -1
  61. metadata +48 -19
  62. checksums.yaml +0 -7
data/lib/database.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/device.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
@@ -65,7 +65,7 @@ class Device
65
65
  capture = `#{cmd}`
66
66
  if $?.exitstatus > 0
67
67
  puts
68
- warn capture.force_encoding(Encoding::Windows_31J).rstrip
68
+ error capture.force_encoding(Encoding::Windows_31J).rstrip
69
69
  exit 1
70
70
  end
71
71
  else
@@ -73,7 +73,7 @@ class Device
73
73
  FileUtils.cp(src_file, dst_path)
74
74
  rescue => e
75
75
  puts
76
- warn e.message
76
+ error e.message
77
77
  exit 1
78
78
  end
79
79
  end
data/lib/device/kindle.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/device/kobo.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
@@ -1,22 +1,10 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
5
5
 
6
- require "fiddle"
7
6
  require "win32ole"
8
-
9
- module WinAPI
10
- include Fiddle
11
- class InvalidOS < StandardError; end
12
- Handle = RUBY_VERSION >= "2.0.0" ? Fiddle::Handle : DL::Handle
13
-
14
- def self.GetLogicalDriveStrings(buf_size, buffer)
15
- @@get_logical_drive_strings ||= Function.new(Handle.new("kernel32")["GetLogicalDriveStrings"],
16
- [TYPE_LONG, TYPE_VOIDP], TYPE_LONG)
17
- @@get_logical_drive_strings.call(buf_size, buffer)
18
- end
19
- end
7
+ require_relative "../../extensions/windows"
20
8
 
21
9
  module Device::Library
22
10
  module Windows
data/lib/downloader.rb CHANGED
@@ -1,14 +1,16 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
5
5
 
6
+ require "yaml"
6
7
  require "fileutils"
7
8
  require_relative "narou"
8
9
  require_relative "sitesetting"
9
10
  require_relative "template"
10
11
  require_relative "database"
11
12
  require_relative "localsetting"
13
+ require_relative "narou/api"
12
14
 
13
15
  #
14
16
  # 小説サイトからのダウンロード
@@ -23,6 +25,8 @@ class Downloader
23
25
 
24
26
  attr_reader :id
25
27
 
28
+ class NoSerialNovel < StandardError; end
29
+
26
30
  #
27
31
  # ターゲット(ID、URL、Nコード、小説名)を指定して小説データのダウンロードを開始する
28
32
  #
@@ -35,13 +39,13 @@ class Downloader
35
39
  when :url, :ncode
36
40
  setting = get_sitesetting_by_target(target)
37
41
  unless setting
38
- warn "対応外の#{type}です(#{target})"
42
+ error "対応外の#{type}です(#{target})"
39
43
  return false
40
44
  end
41
45
  when :id
42
46
  data = @@database[target.to_i]
43
47
  unless data
44
- warn "指定のID(#{target})は存在しません"
48
+ error "指定のID(#{target})は存在しません"
45
49
  return false
46
50
  end
47
51
  setting = get_sitesetting_by_sitename(data["sitename"])
@@ -52,7 +56,7 @@ class Downloader
52
56
  setting = get_sitesetting_by_sitename(data["sitename"])
53
57
  setting.multi_match(data["toc_url"], "url")
54
58
  else
55
- warn "指定の小説(#{target})は存在しません"
59
+ error "指定の小説(#{target})は存在しません"
56
60
  return false
57
61
  end
58
62
  end
@@ -126,7 +130,7 @@ class Downloader
126
130
  else
127
131
  @@database.delete(id)
128
132
  @@database.save_database
129
- warn "#{path} が見つかりません。"
133
+ error "#{path} が見つかりません。"
130
134
  warn "保存フォルダが消去されていたため、データベースのインデックスを削除しました。"
131
135
  return nil
132
136
  end
@@ -210,7 +214,7 @@ class Downloader
210
214
  def self.get_sitesetting_by_sitename(sitename)
211
215
  setting = @@settings.find { |s| s["name"] == sitename }
212
216
  return setting if setting
213
- warn "#{data["sitename"]} の設定ファイルが見つかりません"
217
+ error "#{data["sitename"]} の設定ファイルが見つかりません"
214
218
  exit 1
215
219
  end
216
220
 
@@ -227,11 +231,11 @@ class Downloader
227
231
  settings << setting
228
232
  end
229
233
  if settings.empty?
230
- warn "小説サイトの定義ファイルがひとつもありません"
234
+ error "小説サイトの定義ファイルがひとつもありません"
231
235
  exit 1
232
236
  end
233
237
  unless @@narou
234
- warn "小説家になろうの定義ファイルが見つかりませんでした"
238
+ error "小説家になろうの定義ファイルが見つかりませんでした"
235
239
  exit 1
236
240
  end
237
241
  settings
@@ -295,12 +299,18 @@ class Downloader
295
299
  # ダウンロード処理本体
296
300
  #
297
301
  # 返り値:ダウンロードしたものが1話でもあったかどうか(Boolean)
302
+ # nil なら何らかの原因でダウンロード自体出来なかった
298
303
  #
299
304
  def start_download
300
- latest_toc = get_latest_table_of_contents
305
+ begin
306
+ latest_toc = get_latest_table_of_contents
307
+ rescue NoSerialNovel
308
+ error @setting["ncode"] + " は短編小説です。現在短編小説には対応していません"
309
+ return nil
310
+ end
301
311
  unless latest_toc
302
- warn "目次データが取得出来ませんでした"
303
- exit 1
312
+ error @setting["url"] + " の目次データが取得出来ませんでした"
313
+ return nil
304
314
  end
305
315
  if @setting["confirm_over18"]
306
316
  unless confirm_over18?
@@ -364,11 +374,25 @@ class Downloader
364
374
  "file_title" => @file_title,
365
375
  "toc_url" => @setting["toc_url"],
366
376
  "sitename" => @setting["name"],
377
+ "novel_type" => @novel_type,
367
378
  "last_update" => Time.now
368
379
  }
369
380
  @@database.save_database
370
381
  end
371
382
 
383
+ #
384
+ # 連載小説かどうか調べる
385
+ #
386
+ def serial_novel?
387
+ if @@database[@id]
388
+ @novel_type = @@database[@id]["novel_type"] || 1
389
+ else
390
+ api = Narou::API.new(@setting, "nt")
391
+ @novel_type = api["novel_type"]
392
+ end
393
+ @novel_type == 1
394
+ end
395
+
372
396
  #
373
397
  # 目次データを取得する
374
398
  #
@@ -390,12 +414,15 @@ class Downloader
390
414
  end
391
415
  rescue OpenURI::HTTPError => e
392
416
  if e.message =~ /^404/
393
- warn "指定されたURLは存在しません"
417
+ error "指定されたURLは存在しません"
394
418
  return false
395
419
  else
396
420
  raise
397
421
  end
398
422
  end
423
+ if @setting["narou_api_url"] && !serial_novel?
424
+ raise NoSerialNovel
425
+ end
399
426
  @setting.multi_match(toc_source, "title", "author", "story", "tcode")
400
427
  @title = @setting["title"]
401
428
  @file_title = Helper.replace_filename_special_chars(@title)
@@ -461,7 +488,7 @@ class Downloader
461
488
  def sections_download_and_save(subtitles)
462
489
  max = subtitles.count
463
490
  return if max == 0
464
- puts "ID:#{@id} #{@title} のDL開始"
491
+ puts ("<green>" + TermColor.escape("ID:#{@id} #{@title} のDL開始") + "</green>").termcolor
465
492
  interval_sleep_time = LocalSetting.get["local_setting"]["download.interval"] || 0
466
493
  interval_sleep_time = 0 if interval_sleep_time < 0
467
494
  save_least_one = false
@@ -536,7 +563,7 @@ class Downloader
536
563
  rescue OpenURI::HTTPError => e
537
564
  if e.message =~ /^503/
538
565
  if retry_count == 0
539
- warn "上限までリトライしましたがファイルがダウンロード出来ませんでした"
566
+ error "上限までリトライしましたがファイルがダウンロード出来ませんでした"
540
567
  exit 1
541
568
  end
542
569
  retry_count -= 1
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ begin
4
+ require "fiddle"
5
+
6
+ module WinAPI
7
+ include Fiddle
8
+ Handle = RUBY_VERSION >= "2.0.0" ? Fiddle::Handle : DL::Handle
9
+ Kernel32 = Handle.new("kernel32")
10
+
11
+ def self.GetLogicalDriveStrings(buf_size, buffer)
12
+ @@get_logical_drive_strings ||=
13
+ Function.new(Kernel32["GetLogicalDriveStrings"], [TYPE_LONG, TYPE_VOIDP], TYPE_LONG)
14
+ @@get_logical_drive_strings.call(buf_size, buffer)
15
+ end
16
+
17
+ def self.SetConsoleTextAttribute(cons_handle, attr)
18
+ @@set_console_text_attribute ||=
19
+ Function.new(Kernel32["SetConsoleTextAttribute"], [-TYPE_INT, -TYPE_INT], -TYPE_INT)
20
+ @@set_console_text_attribute.call(cons_handle, attr)
21
+ end
22
+
23
+ def self.GetConsoleScreenBufferInfo(cons_handle, lp_buffer)
24
+ @@get_console_screen_buffer_info ||=
25
+ Function.new(Kernel32["GetConsoleScreenBufferInfo"], [TYPE_LONG, TYPE_VOIDP], TYPE_INT)
26
+ @@get_console_screen_buffer_info.call(cons_handle, lp_buffer)
27
+ end
28
+
29
+ def self.GetStdHandle(handle_type)
30
+ @@get_std_handle ||= Function.new(Kernel32["GetStdHandle"], [-TYPE_INT], -TYPE_INT)
31
+ @@get_std_handle.call(handle_type)
32
+ end
33
+
34
+ def self.GetLastError
35
+ @@get_last_error ||= Function.new(Kernel32["GetLastError"], [], -TYPE_INT)
36
+ @@get_last_error.call
37
+ end
38
+ end
39
+ rescue LoadError
40
+ # Fiddle がない環境用(http://www.artonx.org/data/asr/ の1.9.3とか)
41
+ require "dl/import"
42
+
43
+ class InvalidOS < StandardError; end
44
+
45
+ module WinAPI
46
+ extend DL::Importer
47
+ begin
48
+ dlload "kernel32"
49
+ extern "long GetLogicalDriveStrings(long, void*)"
50
+ extern "long SetConsoleTextAttribute(long, long)"
51
+ extern "long GetConsoleScreenBufferInfo(long, void*)"
52
+ extern "long GetStdHandle(long)"
53
+ extern "long GetLastError()"
54
+ rescue DL::DLError
55
+ raise InvalidOS, "not Windows"
56
+ end
57
+ end
58
+ end
data/lib/globalsetting.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/illustration.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/ini.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/inspector.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
@@ -58,7 +58,7 @@ class Inspector
58
58
  @info
59
59
  end
60
60
 
61
- def display(klass = ALL, target = $stderr)
61
+ def display(klass = ALL, target = $stdout)
62
62
  target.puts @messages.map { |msg|
63
63
  if msg =~ /^\[(.+)\]/
64
64
  key = KLASS_TAG.key($1)
data/lib/kindlestrip.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #! ruby
2
- # -*- coding: UTF-8 -*-
2
+ # -*- coding: utf-8 -*-
3
3
  #
4
4
  # It was translated into Ruby script by whiteleaf.
5
5
  #
data/lib/loadconverter.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
@@ -72,7 +72,7 @@ def load_converter(title, archive_path)
72
72
  if conv
73
73
  return conv
74
74
  else
75
- warn "converter.rbは見つかりましたが、`converter'で登録されていないようです。" +
75
+ error "converter.rbは見つかりましたが、`converter'で登録されていないようです。" +
76
76
  "変換処理は converter \"#{title}\" として登録する必要があります"
77
77
  return BlankConverter
78
78
  end
data/lib/localsetting.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/logger.rb CHANGED
@@ -1,10 +1,11 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
5
5
 
6
6
  require "singleton"
7
7
  require "stringio"
8
+ require_relative "color"
8
9
 
9
10
  module LoggerModule
10
11
  def initialize
@@ -20,9 +21,23 @@ module LoggerModule
20
21
  @is_silent
21
22
  end
22
23
 
24
+ def strip_color(str)
25
+ str.gsub(/(?:\e\[\d*[a-zA-Z])+/, "")
26
+ end
27
+
23
28
  def save(path)
24
29
  File.write(path, string)
25
30
  end
31
+
32
+ def write_console(str, target)
33
+ if str.encoding == Encoding::ASCII_8BIT
34
+ str.force_encoding("utf-8")
35
+ end
36
+ unless @is_silent
37
+ str = strip_color(str) if $disable_color
38
+ write_color(str, target)
39
+ end
40
+ end
26
41
  end
27
42
 
28
43
  class Logger < StringIO
@@ -34,10 +49,9 @@ class Logger < StringIO
34
49
  end
35
50
 
36
51
  def write(str)
37
- super
38
- unless @is_silent
39
- STDOUT.write(str)
40
- end
52
+ str = str.to_s
53
+ super(strip_color(str))
54
+ write_console(str, STDOUT)
41
55
  end
42
56
  end
43
57
 
@@ -50,12 +64,15 @@ class LoggerError < StringIO
50
64
  end
51
65
 
52
66
  def write(str)
53
- super
54
- unless @is_silent
55
- STDERR.write(str)
56
- end
67
+ str = str.to_s
68
+ super(strip_color(str))
69
+ write_console(str, STDERR)
57
70
  end
58
71
  end
59
72
 
73
+ def error(str)
74
+ warn "<red>[ERROR]</red> #{str}".termcolor
75
+ end
76
+
60
77
  $stdout = Logger.get
61
78
  $stderr = LoggerError.get
data/lib/narou.rb CHANGED
@@ -1,4 +1,4 @@
1
- # -*- coding: UTF-8 -*-
1
+ # -*- coding: utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 whiteleaf. All rights reserved.
4
4
  #
data/lib/narou/api.rb ADDED
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright 2013 whiteleaf. All rights reserved.
4
+ #
5
+
6
+ require "open-uri"
7
+ require "yaml"
8
+
9
+ module Narou
10
+ #
11
+ # 小説家になろうデベロッパーAPI操作クラス
12
+ #
13
+ class API
14
+ def initialize(setting, of = "")
15
+ @setting = setting
16
+ @api_url = @setting["narou_api_url"]
17
+ @ncode = @setting["ncode"]
18
+ request_api(of)
19
+ end
20
+
21
+ def [](key)
22
+ @api_result[key]
23
+ end
24
+
25
+ def request_api(of)
26
+ url = "#{@api_url}?ncode=#{@ncode}&of=#{of}"
27
+ open(url) do |fp|
28
+ result = YAML.load(fp.read)
29
+ if result[0]["allcount"] == 1
30
+ @api_result = result[1]
31
+ if of.length > 0
32
+ @api_result["novel_type"] = @api_result["noveltype"]
33
+ end
34
+ else
35
+ error "なろうAPIから情報が取得出来ませんでした"
36
+ exit 1
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end