narou 1.4.3 → 1.4.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e357d2d3541349dcd9c101577f46371b4dcad85
4
- data.tar.gz: 842dcfd45f32421a67eff684de2be212a0955441
3
+ metadata.gz: cceb9aed1a0e71d711702ca7bb7e2029aa043d0d
4
+ data.tar.gz: c5196bb6cc013bb4db7980aa184aaaa1b7d0139c
5
5
  SHA512:
6
- metadata.gz: 1704c6770acaa3edf92561ef6b1633ce228f1b88898a85a481201058e66c03a6eed5d3b2ba068ee59bc6d0114822bd70cc66ab5f64fca404acaaad22c9d86827
7
- data.tar.gz: 7e4767c4235c59ba90ab7bd21f7402228415037d99858e825720d2dbbf0a9c9b50e77e4fa588f5e56a89ad40b267f28e728ddfd3b236ca964582f9cde9f5bcc9
6
+ metadata.gz: 5397e969955f85d372f261887b0168e5c60c32d10d878119933e7fa82e29ee316ae44e1a2cd1141d5a4f196f20c8a84afe1a0c015303cf89a73651f23203b595
7
+ data.tar.gz: dda17db185326b5db6b390656720e3692584addeac52542bbc7538845bf810cb227c1f9bffa48714a9929c42b812aeff2ed5c57bfa87b6549550b89fd409551e
data/ChangeLog.md CHANGED
@@ -2,6 +2,26 @@
2
2
  更新履歴 - ChangeLog
3
3
  --------------------
4
4
 
5
+ 2014/02/26 : **1.4.4**
6
+ * 追加機能もしくは仕様変更
7
+ - **短編小説** に対応しました
8
+ + `narou list` コマンドで短編小説にはタイトルの後ろに(短編)と付きます
9
+ - `narou list` コマンドが拡張されました
10
+ + 一覧の表示を絞る `--filter` オプションを追加しました(短縮 -f)
11
+ - `--filter` に続いて `series` (連載)、`ss` (短編)を指定出来ます
12
+ - コマンド例: `narou list --filter series` 連載小説のみを表示する
13
+ - コマンド例: `narou list -f ss -rl` 短編小説のみを更新の古い順に表示する
14
+ + 表示する項目を増やす `--type` オプションを追加しました(短縮 -t)
15
+ - オプションを指定すると「種別」という項目が追加され、「連載」か「短編」かが表示されます
16
+ - `narou remove` コマンドに全ての短編小説を削除する `--all-ss` オプションが追加されました
17
+ + ファイルも全て消すには通常通り `--with--file` オプションを同時に付ける必要があります
18
+ - `narou download` コマンドにダウンロードが終わったあと削除する `--remove` オプションが追加されました(短縮 -r)
19
+ + 更新をチェックする必要があまりない短編小説などのためのオプションです
20
+ + 小説データフォルダ下にファイルは残っているので、ダウンロード時に送信まで行わなかった場合は、手動で
21
+ 書籍データをコピーすることが出来ます。また、ファイルを消す場合も手動で削除する必要があります
22
+ * Bug Fix
23
+ - 検索除外設定されている小説がダウンロード出来ない問題を修正
24
+
5
25
  2014/02/24 : **1.4.3**
6
26
  * 追加機能もしくは仕様変更
7
27
  - **i文庫** に対応しました。専用のzipアーカイブを生成出来るようになります(txtと表紙、挿絵をzipで固めたもの)
@@ -15,6 +35,8 @@
15
35
  + `converter#before` 及び `after` メソッドの text_type に、 `story` `chapter` が渡されるようになりました
16
36
  * Bug Fix
17
37
  - Windowsにおいて、タイトル及び作者名にCP392外の文字が使われていた場合に変換がエラーになる問題を修正
38
+ + 変換時にエラーになった小説において、まだエラーが出る場合は一度削除( `narou remove --with-file 小説ID` )
39
+ して再ダウンロードをお願いします
18
40
  - 章タイトルが※で終わる小説をEPUB変換時に警告が出ていたのを修正
19
41
 
20
42
  2014/02/20 : **1.4.1.1**
data/README.md CHANGED
@@ -21,6 +21,26 @@ Narou.rb ― 「小説家になろう」「小説を読もう!」ダウンロ
21
21
  更新履歴 - ChangeLog
22
22
  --------------------
23
23
 
24
+ 2014/02/26 : **1.4.4**
25
+ * 追加機能もしくは仕様変更
26
+ - **短編小説** に対応しました
27
+ + `narou list` コマンドで短編小説にはタイトルの後ろに(短編)と付きます
28
+ - `narou list` コマンドが拡張されました
29
+ + 一覧の表示を絞る `--filter` オプションを追加しました(短縮 -f)
30
+ - `--filter` に続いて `series` (連載)、`ss` (短編)を指定出来ます
31
+ - コマンド例: `narou list --filter series` 連載小説のみを表示する
32
+ - コマンド例: `narou list -f ss -rl` 短編小説のみを更新の古い順に表示する
33
+ + 表示する項目を増やす `--type` オプションを追加しました(短縮 -t)
34
+ - オプションを指定すると「種別」という項目が追加され、「連載」か「短編」かが表示されます
35
+ - `narou remove` コマンドに全ての短編小説を削除する `--all-ss` オプションが追加されました
36
+ + ファイルも全て消すには通常通り `--with--file` オプションを同時に付ける必要があります
37
+ - `narou download` コマンドにダウンロードが終わったあと削除する `--remove` オプションが追加されました(短縮 -r)
38
+ + 更新をチェックする必要があまりない短編小説などのためのオプションです
39
+ + 小説データフォルダ下にファイルは残っているので、ダウンロード時に送信まで行わなかった場合は、手動で
40
+ 書籍データをコピーすることが出来ます。また、ファイルを消す場合も手動で削除する必要があります
41
+ * Bug Fix
42
+ - 検索除外設定されている小説がダウンロード出来ない問題を修正
43
+
24
44
  2014/02/24 : **1.4.3**
25
45
  * 追加機能もしくは仕様変更
26
46
  - **i文庫** に対応しました。専用のzipアーカイブを生成出来るようになります(txtと表紙、挿絵をzipで固めたもの)
@@ -34,6 +54,8 @@ Narou.rb ― 「小説家になろう」「小説を読もう!」ダウンロ
34
54
  + `converter#before` 及び `after` メソッドの text_type に、 `story` `chapter` が渡されるようになりました
35
55
  * Bug Fix
36
56
  - Windowsにおいて、タイトル及び作者名にCP392外の文字が使われていた場合に変換がエラーになる問題を修正
57
+ + 変換時にエラーになった小説において、まだエラーが出る場合は一度削除( `narou remove --with-file 小説ID` )
58
+ して再ダウンロードをお願いします
37
59
  - 章タイトルが※で終わる小説をEPUB変換時に警告が出ていたのを修正
38
60
 
39
61
  2014/02/20 : **1.4.1.1**
@@ -48,23 +70,6 @@ Narou.rb ― 「小説家になろう」「小説を読もう!」ダウンロ
48
70
  * 重要な修正
49
71
  - 小説家になろうのレイアウト変更によって更新処理ができなくなっていたものを修正しました
50
72
 
51
- 2014/02/03 : **1.3.5.1**
52
- * Bug Fix
53
- - 過去バージョンとの互換性維持のため、フォルダ名のみ末尾スペースを削除するように変更
54
-
55
- 2014/02/03 : **1.3.5**
56
- * Bug Fix
57
- - 小説を削除したあと再度ダウンロードしようとした場合にエラーが出ていたのを修正
58
- - タイトル名の末端に半角スペースがある小説が正常にダウンロード出来ない問題を修正
59
- * 追加機能もしくは仕様変更
60
- - 小説変換プリセットに n2525bs (魔剣ゾルディの女主人公とっかえひっかえ成長記録) 追加
61
- - ダウンロードが完了した時に同時に凍結させるオプションを追加
62
- + `download` コマンドに `--freeze` (短縮名 -z) オプションが追加されました
63
- * コマンド例: `narou download --freeze n4029bs`
64
- * コマンド例: `narou d n4029bs -z`
65
- - Mac上での動作改善コードの取り込み(https://github.com/yossoy/narou)
66
- + java の動作不良対応、Kindle 対応
67
-
68
73
  ----
69
74
 
70
75
  「小説家になろう」は株式会社ヒナプロジェクトの登録商標です
@@ -16,6 +16,7 @@ module Command
16
16
  ・一度に複数の小説を指定する場合は空白で区切って下さい。
17
17
  ・ダウンロード終了後に変換処理を行います。ダウンロードのみする場合は-nオプションを指定して下さい。
18
18
  ・すでにダウンロード済みの小説の場合は何もしません。
19
+ ・--remove オプションをつけてダウンロードすると、ダウンロード(とその後の変換、送信)が終わったあと削除します。データベースのインデックスを外すだけなので、変換した書籍データは残ったままになります。ファイルを全て消す場合は手動で削除する必要があります。
19
20
 
20
21
  Example:
21
22
  narou download n9669bk
@@ -23,6 +24,7 @@ module Command
23
24
  narou download n9669bk http://ncode.syosetu.com/n4259s/
24
25
  narou download 0 1 -f
25
26
  narou download n9669bk -n
27
+ narou download n6864bt --remove
26
28
 
27
29
  Options:
28
30
  EOS
@@ -35,6 +37,9 @@ module Command
35
37
  @opt.on("-z", "--freeze", "ダウンロードが終了したあと凍結する") {
36
38
  @options["freeze"] = true
37
39
  }
40
+ @opt.on("-r", "--remove", "ダウンロードが終了したあと削除する") {
41
+ @options["remove"] = true
42
+ }
38
43
  end
39
44
 
40
45
  def execute(argv)
@@ -72,6 +77,9 @@ module Command
72
77
  end
73
78
  if @options["freeze"]
74
79
  Freeze.execute_and_rescue_exit([download_target])
80
+ elsif @options["remove"]
81
+ # --freeze オプションが指定された場合は --remove オプションは無視する
82
+ Remove.execute_and_rescue_exit([download_target, "-y"])
75
83
  end
76
84
  end
77
85
  end
data/lib/command/list.rb CHANGED
@@ -9,6 +9,10 @@ module Command
9
9
  class List < CommandBase
10
10
  NEW_ARRIVALS_LIMIT = 6 * 60 * 60 # 更新してから何秒までを新着色にするか
11
11
 
12
+ # MEMO: 0 は昔の小説を凍結したままな場合、novel_type が設定されていないので、
13
+ # nil.to_i → 0 という互換性維持のため
14
+ NOVEL_TYPE_LABEL = ["連載", "連載", "短編"]
15
+
12
16
  def initialize
13
17
  super("[<number>] [options]")
14
18
  @opt.separator <<-EOS
@@ -16,12 +20,14 @@ module Command
16
20
  ・現在管理している小説の一覧を表示します。
17
21
  ・表示されるIDは各コマンドで指定することで小説名等を入力する手間を省けます。
18
22
  ・個数を与えることで、最大表示数を制限できます(デフォルトは全て表示)
23
+ ・narou listのデフォルト動作を narou s default_arg.list= で設定すると便利です
19
24
 
20
25
  Example:
21
26
  narou list # IDの小さい順に全て表示
22
27
  narou list 10 -r # IDの大きい順に10件表示
23
28
  narou list 5 -l # 最近更新のあった5件表示
24
- narou list 10 -rl # 最新10件を古い順に表示
29
+ narou list 10 -rl # 古い順に10件表示
30
+ narou list -f ss # 短編小説だけ表示
25
31
 
26
32
  Options:
27
33
  EOS
@@ -34,13 +40,30 @@ module Command
34
40
  @opt.on("-u", "--url", "小説の掲載ページも表示する") {
35
41
  @options["url"] = true
36
42
  }
43
+ @opt.on("-t", "--type", "小説の種別(短編/連載)も表示する") {
44
+ @options["type"] = true
45
+ }
46
+ @opt.on("-f", "--filter VAL", String,
47
+ "表示を絞るためのフィルターの種類(連載:series, 短編:ss)") { |filter|
48
+ @options["filter"] = filter
49
+ }
37
50
  end
38
51
 
39
52
  def output_list(novels)
40
53
  now = Time.now
41
54
  today = now.strftime("%y/%m/%d")
42
- puts " ID | 更新日 | タイトル"
55
+ filter = @options["filter"]
56
+ header = [" ID ", " 更新日 ", @options["type"] ? "種別" : nil, " タイトル"].compact
57
+ puts header.join(" | ")
43
58
  novels.each do |novel|
59
+ novel_type = novel["novel_type"].to_i
60
+ if filter
61
+ if filter == "series" && novel_type != 0 && novel_type != 1
62
+ next
63
+ elsif filter == "ss" && novel_type != 2
64
+ next
65
+ end
66
+ end
44
67
  id = novel["id"]
45
68
  frozen = Narou.novel_frozen?(id)
46
69
  disp_id = ((frozen ? "*" : "") + id.to_s).rjust(4)
@@ -56,7 +79,8 @@ module Command
56
79
  s.replace "<bold><green>#{s}</green></bold>".termcolor
57
80
  end
58
81
  },
59
- novel["title"],
82
+ @options["type"] ? NOVEL_TYPE_LABEL[novel_type] : nil,
83
+ novel["title"] + (!@options["type"] && novel_type == 2 ? " (#{NOVEL_TYPE_LABEL[novel_type]})" : ""),
60
84
  @options["url"] ? novel["toc_url"] : nil
61
85
  ].compact.join(" | ")
62
86
  end
@@ -16,7 +16,7 @@ module Command
16
16
  IDは #{@opt.program_name} list を参照して下さい。
17
17
  ・一度に複数の小説を指定する場合は空白で区切って下さい。
18
18
  ・削除確認をスキップするには -y オプションを有効にして下さい。
19
- ・削除するのはデータベースのインデックスだけで、変換済みテキストファイルやMOBIファイル等はそのまま残ります。
19
+ ・削除するのはデータベースのインデックスだけで、変換済みテキストファイルやMOBIファイル等はそのまま残ります。ファイルをすべて削除する場合は --with-file オプションを指定して下さい。
20
20
 
21
21
  Example:
22
22
  narou remove n9669bk
@@ -24,6 +24,8 @@ module Command
24
24
  narou remove n9669bk http://ncode.syosetu.com/n4259s/
25
25
  narou remove 0 1 -y
26
26
  narou remove n9669bk --with-file # ファイルも完全に削除する
27
+ narou remove --all-ss # 連載小説をすべて削除する
28
+ narou remove --all-ss --with-file # 短編小説をファイルも含めてすべて削除する
27
29
 
28
30
  Options:
29
31
  EOS
@@ -33,10 +35,26 @@ module Command
33
35
  @opt.on("--with-file", "小説の保存フォルダ・ファイルも全て削除する") {
34
36
  @options["with-file"] = true
35
37
  }
38
+ @opt.on("--all-ss", "短編小説をすべて削除する") {
39
+ @options["all-ss"] = true
40
+ }
41
+ end
42
+
43
+ def get_all_short_story
44
+ Database.instance.get_object.values.select { |v| v["novel_type"] == 2 }
36
45
  end
37
46
 
38
47
  def execute(argv)
39
48
  super
49
+ novels = []
50
+ if @options["all-ss"]
51
+ novels = get_all_short_story
52
+ if novels.count == 0
53
+ puts "短編小説がひとつもありません"
54
+ return
55
+ end
56
+ argv += novels.map { |n| n["id"].to_s }
57
+ end
40
58
  if argv.empty?
41
59
  puts @opt.help
42
60
  return
data/lib/downloader.rb CHANGED
@@ -26,8 +26,6 @@ class Downloader
26
26
 
27
27
  attr_reader :id
28
28
 
29
- class NoSerialNovel < StandardError; end
30
-
31
29
  #
32
30
  # ターゲット(ID、URL、Nコード、小説名)を指定して小説データのダウンロードを開始する
33
31
  #
@@ -278,6 +276,7 @@ class Downloader
278
276
  @from_download = from_download
279
277
  @cache_dir = nil
280
278
  @new_arrivals = false
279
+ @novel_type = nil
281
280
  @id = @@database.get_id("toc_url", @setting["toc_url"]) || @@database.get_new_id
282
281
  end
283
282
 
@@ -305,12 +304,7 @@ class Downloader
305
304
  # nil なら何らかの原因でダウンロード自体出来なかった
306
305
  #
307
306
  def start_download
308
- begin
309
- latest_toc = get_latest_table_of_contents
310
- rescue NoSerialNovel
311
- error @setting["ncode"] + " は短編小説です。現在短編小説には対応していません"
312
- return :failed
313
- end
307
+ latest_toc = get_latest_table_of_contents
314
308
  unless latest_toc
315
309
  error @setting["toc_url"] + " の目次データが取得出来ませんでした"
316
310
  return :failed
@@ -430,22 +424,28 @@ class Downloader
430
424
  "file_title" => @file_title,
431
425
  "toc_url" => @setting["toc_url"],
432
426
  "sitename" => @setting["name"],
433
- "novel_type" => @novel_type,
427
+ "novel_type" => get_novel_type,
434
428
  "last_update" => Time.now,
435
429
  "new_arrivals_date" => (@new_arrivals ? Time.now : @@database[@id]["new_arrivals_date"])
436
430
  }
437
431
  @@database.save_database
438
432
  end
439
433
 
434
+ def get_novel_type
435
+ @novel_type ||= @@database[@id]["novel_type"] || 1
436
+ end
437
+
440
438
  #
441
439
  # 連載小説かどうか調べる
442
440
  #
443
- def serial_novel?
444
- if @@database[@id]
445
- @novel_type = @@database[@id]["novel_type"] || 1
446
- else
447
- api = Narou::API.new(@setting, "nt")
448
- @novel_type = api["novel_type"]
441
+ def series_novel?
442
+ unless @novel_type
443
+ if @@database[@id]
444
+ @novel_type = get_novel_type
445
+ else
446
+ api = Narou::API.new(@setting, "nt")
447
+ @novel_type = api["novel_type"]
448
+ end
449
449
  end
450
450
  @novel_type == 1
451
451
  end
@@ -467,7 +467,7 @@ class Downloader
467
467
  @setting = Downloader.get_sitesetting_by_target(toc_fp.base_uri.to_s)
468
468
  toc_url = @setting["toc_url"]
469
469
  end
470
- toc_source = pretreatment_source(toc_fp.read)
470
+ toc_source = Helper.pretreatment_source(toc_fp.read, @setting["encoding"])
471
471
  end
472
472
  rescue OpenURI::HTTPError => e
473
473
  if e.message =~ /^404/
@@ -477,10 +477,16 @@ class Downloader
477
477
  raise
478
478
  end
479
479
  end
480
- if @setting["narou_api_url"] && !serial_novel?
481
- raise NoSerialNovel
482
- end
483
480
  @setting.multi_match(toc_source, "title", "author", "story", "tcode")
481
+ if @setting["narou_api_url"] && series_novel?
482
+ # 連載小説
483
+ subtitles = get_subtitles(toc_source)
484
+ else
485
+ # 短編小説
486
+ api = Narou::API.new(@setting, "s-gf-nu")
487
+ @setting["story"] = api["story"]
488
+ subtitles = create_short_story_subtitles(api)
489
+ end
484
490
  @title = @setting["title"]
485
491
  @file_title = Helper.replace_filename_special_chars(@title, invalid_replace: true).strip
486
492
  @setting["story"] = @setting["story"].gsub("<br />", "")
@@ -489,7 +495,7 @@ class Downloader
489
495
  "author" => @setting["author"],
490
496
  "toc_url" => @setting["toc_url"],
491
497
  "story" => @setting["story"],
492
- "subtitles" => get_subtitles(toc_source)
498
+ "subtitles" => subtitles
493
499
  }
494
500
  toc_objects
495
501
  end
@@ -553,6 +559,22 @@ class Downloader
553
559
  subtitles
554
560
  end
555
561
 
562
+ #
563
+ # 短編用の情報を生成
564
+ #
565
+ def create_short_story_subtitles(api)
566
+ subtitle = {
567
+ "index" => "1",
568
+ "href" => "/",
569
+ "chapter" => "",
570
+ "subtitle" => @setting["title"],
571
+ "file_subtitle" => Helper.replace_filename_special_chars(@setting["title"]),
572
+ "subdate" => api["general_firstup"],
573
+ "subupdate" => api["novelupdated_at"]
574
+ }
575
+ [subtitle]
576
+ end
577
+
556
578
  #
557
579
  # 小説本文をまとめてダウンロードして保存
558
580
  #
@@ -581,7 +603,12 @@ class Downloader
581
603
  unless chapter.empty?
582
604
  puts "#{chapter}"
583
605
  end
584
- print "第#{index}部分 #{subtitle} (#{i+1}/#{max})"
606
+ if @novel_type == 1
607
+ print "第#{index}部分"
608
+ else
609
+ print "短編"
610
+ end
611
+ print " #{subtitle} (#{i+1}/#{max})"
585
612
  section_element = a_section_download(subtitle_info)
586
613
  info = subtitle_info.dup
587
614
  info["element"] = section_element
@@ -639,12 +666,21 @@ class Downloader
639
666
  else
640
667
  subtitle_url = @setting["toc_url"] + href
641
668
  end
642
- section = nil
669
+ section = download_raw_data(subtitle_url)
670
+ save_raw_data(section, subtitle_info)
671
+ element = extract_elements_in_section(section, subtitle_info["subtitle"])
672
+ element
673
+ end
674
+
675
+ #
676
+ # 指定したURLからデータをダウンロード
677
+ #
678
+ def download_raw_data(url)
679
+ raw = nil
643
680
  retry_count = RETRY_MAX_FOR_503
644
681
  begin
645
- open(subtitle_url) do |fp|
646
- section = pretreatment_source(fp.read)
647
- save_raw_data(section, subtitle_info)
682
+ open(url) do |fp|
683
+ raw = Helper.pretreatment_source(fp.read, @setting["encoding"])
648
684
  end
649
685
  rescue OpenURI::HTTPError => e
650
686
  if e.message =~ /^503/
@@ -661,8 +697,7 @@ class Downloader
661
697
  raise
662
698
  end
663
699
  end
664
- element = extract_elements_in_section(section, subtitle_info["subtitle"])
665
- element
700
+ raw
666
701
  end
667
702
 
668
703
  def get_raw_dir
@@ -777,23 +812,4 @@ class Downloader
777
812
  Template.write(filename, novel_dir_path, binding)
778
813
  end
779
814
  end
780
-
781
- #
782
- # ダウンロードしてきたデータを使いやすいように処理
783
- #
784
- def pretreatment_source(src)
785
- restor_entity(src.force_encoding(@setting["encoding"])).gsub("\r", "")
786
- end
787
-
788
- ENTITIES = { quot: '"', amp: "&", nbsp: " ", lt: "<", gt: ">", copy: "(c)" }
789
- #
790
- # エンティティ復号
791
- #
792
- def restor_entity(str)
793
- result = str.dup
794
- ENTITIES.each do |key, value|
795
- result.gsub!("&#{key};", value)
796
- end
797
- result
798
- end
799
815
  end