whiteleaf7 / narou

Narou.rb - 小説家になろうのダウンローダ&縦書き整形&管理アプリ。Kindle(などの電子書籍端末)でなろうを読む場合に超便利です!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ENAMETOOLONGエラーが発生する

jam7 opened this issue · comments

いつもお世話になっています。また、エラーが出るパターンがありましたので報告です。

https://ncode.syosetu.com/n2656ev/

これを変換すると以下のエラーとなります。フォルダ名の段階ではタイトルが省略されているのですが、.txtにするところで、タイトルが省略されなくなってしまうようでした。著者名が長いのも関係があるのかもしれません。

$ narou c 539
ID:539 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイムスリップ転移系ファンタジー☆ の変換を開始
600話ごとに分割して変換します
小説状態の調査結果を 調査ログ.txt に出力しました(エラー:0件、警告:10件、INFO:1件)
/usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/extension.rb:39:in `rename': Filename too long @ rb_file_s_rename - (/opt/narou/小説データ
/小説家になろう/n2656ev 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイ/607528c20e8981895cb254f8feff
deb, /opt/narou/小説データ/小説家になろう/n2656ev 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイ/[[
常陸之介寛浩★OVL5金賞受賞☆アルファ第4回歴史時代小説読者賞] 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時    
代歴史改変タイムスリップ転移系ファンタジー☆.txt) (Errno::ENAMETOOLONG)
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/extension.rb:39:in `write'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:404:in `block in convert_main'

  エラーが発生したため終了しました。
  詳細なエラーログは narou trace で表示出来ます。もしくは --backtrace オプションを付けて再度実行して下さい。
$ narou trace
--- 2019/07/06 10:28:02 ---
/usr/bin/narou c 539

/usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/extension.rb:39:in `rename': Filename too long @ rb_file_s_rename - (/opt/narou/小説データ/小説家になろう/n2656ev 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイ/587e6d8415a5bc53303fdb7e45dc14, /opt/narou/小説データ/小説家になろう/n2656ev 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイ/[常陸之介寛浩★OVL5金賞受賞☆アルファ第4回歴史時代小説読者賞] 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時      代歴史改変タイムスリップ転移系ファンタジー☆.txt) (Errno::ENAMETOOLONG)
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/extension.rb:39:in `write'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:404:in `block in convert_main'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:402:in `each'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:402:in `each_with_index'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:402:in `convert_main'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/novelconverter.rb:52:in `convert'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:236:in `convert_novel_main'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:201:in `block (2 levels) in convert_novels'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/mixin/locker.rb:26:in `lock'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:200:in `block in convert_novels'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:199:in `each'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:199:in `with_index'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:199:in `convert_novels'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:159:in `block in main'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:152:in `each'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:152:in `main'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:133:in `execute'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/commandbase.rb:125:in `execute!'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/commandbase.rb:134:in `execute!'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:123:in `block in execute!'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/narou.rb:361:in `concurrency_call'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/command/convert.rb:122:in `execute!'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/commandline.rb:29:in `run'
  from /usr/lib/ruby/gems/2.4.0/gems/narou-3.4.3/lib/commandline.rb:43:in `run!'
...

以前、類似の#220では、setting.iniのnovel_titleを短くすることで回避できていましたが、今回はnovel_titleやoutput_filenameを弄っても、rename先のファイル名が変わらずエラー内容に変化ありませんでした。

また、#220の際に伺った、database.yaml中のfile_titleを縮めてフォルダー名も合わせて変更するというのをやってみましたが、確かにフォルダ名は変わったのですが、ファイル名が長すぎるようで効果ありませんでした。

database.yaml中の、titleとfile_titleを縮めることで、なんとか回避しています。

macOS だとファイル名ちょっと長い程度じゃ全く問題ないので塩対応部分…
調べてみます

From: /Users/whiteleaf/github/narou/lib/extension.rb @ line 40 File.write:                          変換中:1
                                                                                                    変換中:1
    26: def File.write(path, string, *options, mode: nil)                                           変換中:1
    27:   return super if mode                                                                      変換中:1
    28:                                                                                             変換中:1
    29:   dirpath = File.dirname(path)                                                              変換中:1
    30:   temp_path = File.join(dirpath, SecureRandom.hex(15))                                      変換中:1
    31:   if File.extname(path) == ".yaml" && File.basename(dirpath) != Downloader::SECTION_SAVE_DIR_NAME :1
    32:     backup = "#{path}.backup"                                                               変換中:1
    33:   end                                                                                       変換中:1
    34:                                                                                             変換中:1
    35:   res = super(temp_path, string, *options)                                                  変換中:1
    36:   if backup                                                                                 変換中:1
    37:     super(backup, string, *options)                                                         変換中:1
    38:   end                                                                                       変換中:1
    39:   binding.pry                                                                               変換中:1
 => 40:   File.rename(temp_path, path)                                                              変換中:1
    41:   res                                                                                       変換中:1
    42: end                                                                                         変換中:1
                                                                                                    変換中:1
[1] pry(File)> path
=> "/Users/whiteleaf/github/narou/小説データ/小説家になろう/26/n2656ev 本能寺から始める信長との天下統一  《4200万アクセス超え》☆戦国時代歴史改変タイ/長いよ.txt"

スクリーンショット 2019-07-08 10 49 45

スクリーンショット 2019-07-08 10 49 20

特に問題ないような気がするが

特に問題ないような気がするが

setting.iniの変更が反映されない、というのはこちらのミスでした。こちらでも反映されていました。

自分も #220 のn6339doで同様のエラーが発生いたしました。
(Windows => Linuxへ環境を移行した際に発生)
#281#220 をfixしているようですが、本エラーはフルパス名長ではくファイル名単体の最大長に引っかかって発生しておりますので、 #281 のcommitでは対応できていないように思います。

自分の場合 filename-length-limit をtxtファイル名にも反映させるよう下記のパッチを当てて使用しておりますが、可能でしたらmergeしていただければ助かります。

--- narou.rb.org        2019-08-29 16:14:12.807045200 +0900
+++ narou.rb    2019-08-29 19:55:01.088471338 +0900
@@ -235,7 +235,7 @@
         novel_setting.novel_title.presence || novel_data["title"],
         true
       )
-      "[#{author}] #{title}#{ext}"
+      Helper.truncate_path("[#{author}] #{title}#{ext}")
     end
   end

# 補足: ファイル名の最大長

自分の環境の場合CentOS7でXFSを使用しているため、最大ファイル名長が255byteとなっており、下記の通りオーバーしてしまったようです。

irb(main):005:0> title = '[緋色優希(旧 トワイライト)] おっさんのリメイク冒険日記 ~オートキャンプから始まる異世界満喫ライフ~(旧題 おっさんがオートキャンプしてたら、何故か異世界でキャンプする羽目になった).txt'
irb(main):006:0> title.size
=> 98
irb(main):007:0> title.bytesize
=> 278

@aki1-asr

自分の場合 filename-length-limit をtxtファイル名にも反映させるよう下記のパッチを当てて使用しておりますが、可能でしたらmergeしていただければ助かります。

確認します

https://jbbs.shitaraba.net/bbs/read.cgi/computer/44668/1511245701/192
現時点では間違いなく仕様ですが(バグではなく実装時点では意識的に出力ファイル名には適用しなかった)、

対策するとしたら title-length-limit 的なのを新しく作ることを検討します

という考えは改めようかなと思いました。
つまり filename-length-limit を出力電書ファイル名にも効かせる = #325 (comment) の適用をする

以下思考経路

なぜ出力ファイル名に適用しなかったのかは、出力ファイル名は別途制御する方法があったからですが、filename-length-limit を適用せざるを得ない環境では、出力ファイル名も同様の問題が発生する可能性が高いので、出力ファイル名制御の設定の手間がたしかに省けるな、と思い直しました。

@jam7
@aki1-asr
version 3.4.4 released

@whiteleaf7
まさか1日でご対応いただけるとは思いませんでした。ありがとうございます。
updateして確認してみましたが、パッチなしで正常にConvertできました。

デフォルト50文字だからいままで出力してたファイル名が変わって栞が消えるみたいな
ことはあるかもですねとか今更思ったけど設定で100文字とか200文字とかに増やしてくだされ…

@whiteleaf7
すいません、リリース後で申し訳ないのですけども、もう1点オーバーする部分がありました。
バックアップする際のファイル名生成処理についてもタイトルをそのまま使用しているため、おそらく下記の部分にも Helper.truncate_path() が必要かなと思います。

https://github.com/whiteleaf7/narou/blob/develop/lib/command/backup.rb#L34

# 実際n6339doでbackupしてみたら Errno::ENAMETOOLONG が発生しました

尚、現役で使われているファイルシステムの場合殆どが255文字 or 255byteが上限のようです(※)。
UTF-8, UTF-16では長くとも4byteであるため、50文字上限の場合ワーストケースでも200byteとなり、backup時の19byte( _%Y%m%d%H%M%S.zip )を追加してもエラーになることは無さそうです。
(絵文字50文字のタイトルとかでない限り全部4byteなんてありえないですが・・・)

https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0#%E8%AB%B8%E5%85%83

やっぱり filename-length-limit で共有設定は厳しかったかもしれない
当初想定していた別の設定名に分けようかな

厳しい理由:

いままで出力ファイル名は50文字以上も許容していた。
(「文字」数換算なので、バイト換算では許容範囲内の作品はかなりあると思われる)

ファイル名の長さの計算は、出力ファイル名に限れば作者名部分も含むので、意外と50文字に引っかかりやすかった。
それが強制50文字で端折られると、出力ファイル名が変わる作品が多い。
→別のファイルが増える。栞も変わってしまう(後方互換がない)

いままでの設定にあわせて filename-length-limit を増やそうとする
→出力ファイル名はいいかもしれないが、各話保存ファイルの名前も増えるため、再DLが発生してしまう

以上の理由から、今回のアプデはなかったこととして、別設定名に変えます