narou 3.1.11 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of narou might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +12 -9
- data/ChangeLog.md +42 -2
- data/README.md +32 -17
- data/lib/command/convert.rb +22 -7
- data/lib/command/init.rb +65 -29
- data/lib/command/mail.rb +24 -22
- data/lib/command/send.rb +26 -23
- data/lib/command/setting.rb +20 -5
- data/lib/command/update.rb +1 -1
- data/lib/command/update/general_lastup_updater.rb +4 -3
- data/lib/converterbase.rb +0 -33
- data/lib/downloader.rb +25 -4
- data/lib/helper.rb +19 -2
- data/lib/html.rb +4 -0
- data/lib/narou.rb +42 -10
- data/lib/novelconverter.rb +87 -38
- data/lib/novelinfo.rb +2 -1
- data/lib/novelsetting.rb +25 -14
- data/lib/version.rb +1 -1
- data/lib/web/appserver.rb +25 -122
- data/lib/web/public/resources/narou.library.js +34 -1
- data/lib/web/public/resources/narou.ui.js +66 -12
- data/lib/web/server_helpers.rb +121 -0
- data/lib/web/views/settings.haml +1 -1
- data/lib/web/views/style.scss +12 -0
- data/narou.gemspec +1 -0
- data/narou.rb +3 -7
- data/preset/ncode.syosetu.com/n9463br/setting.ini +0 -4
- data/preset/vertical_font.css +1 -1
- data/preset/vertical_font_with_dakuten.css +1 -1
- data/webnovel/kakuyomu.jp.yaml +12 -7
- data/webnovel/ncode.syosetu.com.yaml +5 -0
- data/webnovel/novel18.syosetu.com.yaml +5 -0
- data/webnovel/syosetu.org.yaml +3 -0
- metadata +17 -4
- data/preset/doubledash.png +0 -0
- data/preset/singledash.png +0 -0
    
        data/lib/novelinfo.rb
    CHANGED
    
    | @@ -9,7 +9,7 @@ require_relative "html" | |
| 9 9 |  | 
| 10 10 | 
             
            class NovelInfo
         | 
| 11 11 | 
             
              REFRESH_INTERVAL = 10 # キャッシュを捨てて再取得するまでの時間(s)
         | 
| 12 | 
            -
              DEFAULT_OF = "t-nt-ga-s-gf-nu-gl-w"
         | 
| 12 | 
            +
              DEFAULT_OF = "t-nt-ga-s-gf-nu-gl-w-l"
         | 
| 13 13 | 
             
              @@novel_info_parameters = {}
         | 
| 14 14 |  | 
| 15 15 | 
             
              def self.load(setting, toc_source: nil, of: DEFAULT_OF)
         | 
| @@ -70,6 +70,7 @@ class NovelInfo | |
| 70 70 | 
             
                story_html.strip_decoration_tag = true
         | 
| 71 71 | 
             
                result["story"] = story_html.to_aozora
         | 
| 72 72 | 
             
                result["writer"] = @setting["writer"]
         | 
| 73 | 
            +
                result["length"] = Helper.numeric_length(@setting["length"])
         | 
| 73 74 | 
             
                %w(general_firstup novelupdated_at general_lastup).each do |elm|
         | 
| 74 75 | 
             
                  result[elm] = Helper.date_string_to_time(@setting[elm])
         | 
| 75 76 | 
             
                end
         | 
    
        data/lib/novelsetting.rb
    CHANGED
    
    | @@ -193,14 +193,6 @@ class NovelSetting | |
| 193 193 | 
             
                @settings[name] = value
         | 
| 194 194 | 
             
              end
         | 
| 195 195 |  | 
| 196 | 
            -
              def output_filename
         | 
| 197 | 
            -
                @settings.fetch("output_filename", nil)
         | 
| 198 | 
            -
              end
         | 
| 199 | 
            -
             | 
| 200 | 
            -
              def include?(key)
         | 
| 201 | 
            -
                @settings.include?(key)
         | 
| 202 | 
            -
              end
         | 
| 203 | 
            -
             | 
| 204 196 | 
             
              #
         | 
| 205 197 | 
             
              # replace.txt による置換定義を読み込む
         | 
| 206 198 | 
             
              #
         | 
| @@ -452,12 +444,6 @@ $ntag 小説のタグをカンマ区切りにしたもの | |
| 452 444 | 
             
                  value: false,
         | 
| 453 445 | 
             
                  help: "HTMLの装飾系タグを削除する(主にArcadiaの作品に影響)"
         | 
| 454 446 | 
             
                },
         | 
| 455 | 
            -
                {
         | 
| 456 | 
            -
                  name: "enable_double_dash_to_image",
         | 
| 457 | 
            -
                  type: :boolean,
         | 
| 458 | 
            -
                  value: false,
         | 
| 459 | 
            -
                  help: "2倍ダッシュ(――)を画像に差し替える。Kindleのデフォルトフォントみたいにダッシュが太くて気になる人用"
         | 
| 460 | 
            -
                },
         | 
| 461 447 | 
             
                {
         | 
| 462 448 | 
             
                  name: "enable_add_end_to_title",
         | 
| 463 449 | 
             
                  type: :boolean,
         | 
| @@ -471,6 +457,13 @@ $ntag 小説のタグをカンマ区切りにしたもの | |
| 471 457 | 
             
                  help: "1話目から指定した話数分、変換の対象外にする。" \
         | 
| 472 458 | 
             
                        "全話数分以上の数値を指定した場合、最新話だけ変換する"
         | 
| 473 459 | 
             
                },
         | 
| 460 | 
            +
                {
         | 
| 461 | 
            +
                  name: "slice_size",
         | 
| 462 | 
            +
                  type: :integer,
         | 
| 463 | 
            +
                  value: 0,
         | 
| 464 | 
            +
                  help: "小説が指定した話数より多い場合、指定した話数ごとに分割する。" \
         | 
| 465 | 
            +
                        "cut_old_subtitlesで処理した後の話数を対象に処理する"
         | 
| 466 | 
            +
                },
         | 
| 474 467 | 
             
                {
         | 
| 475 468 | 
             
                  name: "author_comment_style",
         | 
| 476 469 | 
             
                  type: :select,
         | 
| @@ -479,6 +472,24 @@ $ntag 小説のタグをカンマ区切りにしたもの | |
| 479 472 | 
             
                  select_keys: %w(css simple plain),
         | 
| 480 473 | 
             
                  select_summaries: %w(CSSで装飾 シンプルに段落 装飾しない)
         | 
| 481 474 | 
             
                },
         | 
| 475 | 
            +
                {
         | 
| 476 | 
            +
                  name: "novel_author",
         | 
| 477 | 
            +
                  type: :string,
         | 
| 478 | 
            +
                  value: "",
         | 
| 479 | 
            +
                  help: "小説の著者名を変更する。作品内著者名及び出力ファイル名に影響する"
         | 
| 480 | 
            +
                },
         | 
| 481 | 
            +
                {
         | 
| 482 | 
            +
                  name: "novel_title",
         | 
| 483 | 
            +
                  type: :string,
         | 
| 484 | 
            +
                  value: "",
         | 
| 485 | 
            +
                  help: "小説のタイトルを変更する。作品内タイトル及び出力ファイル名に影響する"
         | 
| 486 | 
            +
                },
         | 
| 487 | 
            +
                {
         | 
| 488 | 
            +
                  name: "output_filename",
         | 
| 489 | 
            +
                  type: :string,
         | 
| 490 | 
            +
                  value: "",
         | 
| 491 | 
            +
                  help: "出力ファイル名を任意の文字列に変更する。convert.filename-to-ncode の設定よりも優先される。※拡張子を含めないで下さい"
         | 
| 492 | 
            +
                },
         | 
| 482 493 | 
             
              ]
         | 
| 483 494 |  | 
| 484 495 | 
             
              ORIGINAL_SETTINGS_KEY_INDEXES = {}.tap { |hash|
         | 
    
        data/lib/version.rb
    CHANGED
    
    
    
        data/lib/web/appserver.rb
    CHANGED
    
    | @@ -20,115 +20,7 @@ require_relative "../inventory" | |
| 20 20 | 
             
            require_relative "worker"
         | 
| 21 21 | 
             
            require_relative "pushserver"
         | 
| 22 22 | 
             
            require_relative "settingmessages"
         | 
| 23 | 
            -
             | 
| 24 | 
            -
            module Narou::ServerHelpers
         | 
| 25 | 
            -
              #
         | 
| 26 | 
            -
              # タグをHTMLで装飾する
         | 
| 27 | 
            -
              #
         | 
| 28 | 
            -
              def decorate_tags(tags)
         | 
| 29 | 
            -
                tags.sort.map do |tag|
         | 
| 30 | 
            -
                  %!<span class="tag label label-#{Command::Tag.get_color(tag)}" data-tag="#{escape_html(tag)}">#{escape_html(tag)}</span>!
         | 
| 31 | 
            -
                end.join(" ")
         | 
| 32 | 
            -
              end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              #
         | 
| 35 | 
            -
              # タグをHTMLで装飾する(除外タグ指定用)
         | 
| 36 | 
            -
              #
         | 
| 37 | 
            -
              def decorate_exclusion_tags(tags)
         | 
| 38 | 
            -
                tags.sort.map do |tag|
         | 
| 39 | 
            -
                  %!<span class="tag label label-#{Command::Tag.get_color(tag)}" data-exclusion-tag="#{escape_html(tag)}">^tag:#{escape_html(tag)}</span>!
         | 
| 40 | 
            -
                end.join(" ")
         | 
| 41 | 
            -
              end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
              #
         | 
| 44 | 
            -
              # Rubyバージョンを構築
         | 
| 45 | 
            -
              #
         | 
| 46 | 
            -
              def build_ruby_version
         | 
| 47 | 
            -
                begin
         | 
| 48 | 
            -
                  `"#{RbConfig.ruby}" -v`.strip
         | 
| 49 | 
            -
                rescue
         | 
| 50 | 
            -
                  config = RbConfig::CONFIG
         | 
| 51 | 
            -
                  "ruby #{RUBY_VERSION}p#{config["PATCHLEVEL"]} [#{RUBY_PLATFORM}]"
         | 
| 52 | 
            -
                end
         | 
| 53 | 
            -
              end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
              #
         | 
| 56 | 
            -
              # 有効な novel ID だけの配列を生成する
         | 
| 57 | 
            -
              # ID が指定されなかったか、1件も存在しない場合は nil を返す
         | 
| 58 | 
            -
              #
         | 
| 59 | 
            -
              def select_valid_novel_ids(ids)
         | 
| 60 | 
            -
                return nil unless ids.kind_of?(Array)
         | 
| 61 | 
            -
                result = ids.select do |id|
         | 
| 62 | 
            -
                  id =~ /^\d+$/
         | 
| 63 | 
            -
                end
         | 
| 64 | 
            -
                result.empty? ? nil : result
         | 
| 65 | 
            -
              end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
              #
         | 
| 68 | 
            -
              # フォーム情報の真偽値データを実際のデータに変換
         | 
| 69 | 
            -
              #
         | 
| 70 | 
            -
              def convert_on_off_to_boolean(str)
         | 
| 71 | 
            -
                case str
         | 
| 72 | 
            -
                when "on"
         | 
| 73 | 
            -
                  true
         | 
| 74 | 
            -
                when "off"
         | 
| 75 | 
            -
                  false
         | 
| 76 | 
            -
                else
         | 
| 77 | 
            -
                  nil
         | 
| 78 | 
            -
                end
         | 
| 79 | 
            -
              end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
              #
         | 
| 82 | 
            -
              # nil true false を nil on off という文字列に変換
         | 
| 83 | 
            -
              #
         | 
| 84 | 
            -
              def convert_boolean_to_on_off(bool)
         | 
| 85 | 
            -
                case bool
         | 
| 86 | 
            -
                when TrueClass
         | 
| 87 | 
            -
                  "on"
         | 
| 88 | 
            -
                when FalseClass
         | 
| 89 | 
            -
                  "off"
         | 
| 90 | 
            -
                else
         | 
| 91 | 
            -
                  "nil"
         | 
| 92 | 
            -
                end
         | 
| 93 | 
            -
              end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
              #
         | 
| 96 | 
            -
              # HTMLエスケープヘルパー
         | 
| 97 | 
            -
              #
         | 
| 98 | 
            -
              def h(text)
         | 
| 99 | 
            -
                Rack::Utils.escape_html(text)
         | 
| 100 | 
            -
              end
         | 
| 101 | 
            -
             | 
| 102 | 
            -
              #
         | 
| 103 | 
            -
              # 与えられたデータが真偽値だった場合、設定画面用に「はい」「いいえ」に変換する
         | 
| 104 | 
            -
              # 真偽値ではなかった場合、そのまま返す
         | 
| 105 | 
            -
              #
         | 
| 106 | 
            -
              def value_to_msg(value)
         | 
| 107 | 
            -
                case value
         | 
| 108 | 
            -
                when TrueClass
         | 
| 109 | 
            -
                  "はい"
         | 
| 110 | 
            -
                when FalseClass
         | 
| 111 | 
            -
                  "いいえ"
         | 
| 112 | 
            -
                else
         | 
| 113 | 
            -
                  value
         | 
| 114 | 
            -
                end
         | 
| 115 | 
            -
              end
         | 
| 116 | 
            -
             | 
| 117 | 
            -
              def notepad_text_path
         | 
| 118 | 
            -
                File.join(Narou.local_setting_dir, "notepad.txt")
         | 
| 119 | 
            -
              end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
              def query_to_boolean(value, default: false)
         | 
| 122 | 
            -
                case value
         | 
| 123 | 
            -
                when "1", 1, "true", true
         | 
| 124 | 
            -
                  true
         | 
| 125 | 
            -
                when "0", 0, "false", false
         | 
| 126 | 
            -
                  false
         | 
| 127 | 
            -
                else
         | 
| 128 | 
            -
                  default
         | 
| 129 | 
            -
                end
         | 
| 130 | 
            -
              end
         | 
| 131 | 
            -
            end
         | 
| 23 | 
            +
            require_relative "server_helpers"
         | 
| 132 24 |  | 
| 133 25 | 
             
            class Narou::AppServer < Sinatra::Base
         | 
| 134 26 | 
             
              register Sinatra::Reloader if $development
         | 
| @@ -273,12 +165,13 @@ class Narou::AppServer < Sinatra::Base | |
| 273 165 | 
             
              # とりあえずDigest認証のみ
         | 
| 274 166 | 
             
              def setup_server_authentication
         | 
| 275 167 | 
             
                auth = Inventory.load("global_setting", :global).group("server-digest-auth")
         | 
| 276 | 
            -
                return unless auth.enable
         | 
| 277 | 
            -
             | 
| 278 168 | 
             
                user = auth.user
         | 
| 279 169 | 
             
                hashed = auth.hashed_password
         | 
| 280 170 | 
             
                passwd = hashed || auth.password
         | 
| 281 171 |  | 
| 172 | 
            +
                # enableかつユーザー名とパスワードが設定されている時のみ認証を有効にする
         | 
| 173 | 
            +
                return unless auth.enable && user && passwd
         | 
| 174 | 
            +
             | 
| 282 175 | 
             
                self.class.class_exec do
         | 
| 283 176 | 
             
                  use Rack::Auth::Digest::MD5, { realm: "narou.rb", opaque: "", passwords_hashed: hashed } do |username|
         | 
| 284 177 | 
             
                    passwd if username == user
         | 
| @@ -292,13 +185,13 @@ class Narou::AppServer < Sinatra::Base | |
| 292 185 |  | 
| 293 186 | 
             
              before do
         | 
| 294 187 | 
             
                headers "Cache-Control" => "no-cache" if $development
         | 
| 295 | 
            -
                @bootstrap_theme = case params["theme"]
         | 
| 188 | 
            +
                @bootstrap_theme = case params["webui.theme"]
         | 
| 296 189 | 
             
                                   when nil
         | 
| 297 190 | 
             
                                     Narou.get_theme
         | 
| 298 191 | 
             
                                   when ""   # 環境設定画面で未設定が選択された時
         | 
| 299 192 | 
             
                                     nil
         | 
| 300 193 | 
             
                                   else
         | 
| 301 | 
            -
                                     params["theme"]
         | 
| 194 | 
            +
                                     params["webui.theme"]
         | 
| 302 195 | 
             
                                   end
         | 
| 303 196 | 
             
                Narou::Worker.push_as_system_worker do
         | 
| 304 197 | 
             
                  Inventory.clear
         | 
| @@ -518,9 +411,9 @@ class Narou::AppServer < Sinatra::Base | |
| 518 411 | 
             
              get "/novels/:id/download" do
         | 
| 519 412 | 
             
                device = Narou.get_device
         | 
| 520 413 | 
             
                ext = device ? device.ebook_file_ext : ".epub"
         | 
| 521 | 
            -
                 | 
| 522 | 
            -
                if File.exist?( | 
| 523 | 
            -
                  send_file( | 
| 414 | 
            +
                paths = Narou.get_ebook_file_paths(@id, ext)
         | 
| 415 | 
            +
                if !paths.empty? && File.exist?(paths[0])
         | 
| 416 | 
            +
                  send_file(paths[0], filename: File.basename(paths[0]), type: "application/octet-stream")
         | 
| 524 417 | 
             
                else
         | 
| 525 418 | 
             
                  not_found
         | 
| 526 419 | 
             
                end
         | 
| @@ -566,7 +459,12 @@ class Narou::AppServer < Sinatra::Base | |
| 566 459 | 
             
                      sitename: data["sitename"],
         | 
| 567 460 | 
             
                      toc_url: data["toc_url"],
         | 
| 568 461 | 
             
                      novel_type: data["novel_type"] == 2 ? "短編" : "連載",
         | 
| 569 | 
            -
                      tags:  | 
| 462 | 
            +
                      tags: if tags.empty?
         | 
| 463 | 
            +
                              ""
         | 
| 464 | 
            +
                            else
         | 
| 465 | 
            +
                              %!#{decorate_tags(tags)} <span class="tag tag-reset label label-white"! +
         | 
| 466 | 
            +
                              %!data-tag="" data-toggle="tooltip" title="タグ検索を解除"> </span>!
         | 
| 467 | 
            +
                            end,
         | 
| 570 468 | 
             
                      status: [
         | 
| 571 469 | 
             
                        is_frozen ? "凍結" : nil,
         | 
| 572 470 | 
             
                        tags.include?("end") ? "完結" : nil,
         | 
| @@ -579,6 +477,7 @@ class Narou::AppServer < Sinatra::Base | |
| 579 477 | 
             
                      # 掲載話数
         | 
| 580 478 | 
             
                      general_all_no: data["general_all_no"],
         | 
| 581 479 | 
             
                      last_check_date: data["last_check_date"].tap { |m| break m.to_i if m },
         | 
| 480 | 
            +
                      length: data["length"],
         | 
| 582 481 | 
             
                    }
         | 
| 583 482 | 
             
                  end.compact
         | 
| 584 483 | 
             
                json_objects[:recordsTotal] = json_objects[:data].size
         | 
| @@ -631,8 +530,10 @@ class Narou::AppServer < Sinatra::Base | |
| 631 530 | 
             
                end
         | 
| 632 531 | 
             
                Narou::Worker.push do
         | 
| 633 532 | 
             
                  cmd = Command::Update.new
         | 
| 634 | 
            -
                   | 
| 635 | 
            -
                     | 
| 533 | 
            +
                  if table_reload_timing == "every"
         | 
| 534 | 
            +
                    cmd.on(:success) do
         | 
| 535 | 
            +
                      @@push_server.send_all(:"table.reload")
         | 
| 536 | 
            +
                    end
         | 
| 636 537 | 
             
                  end
         | 
| 637 538 | 
             
                  cmd.execute!([ids, opt_arguments].flatten)
         | 
| 638 539 | 
             
                  @@push_server.send_all(:"table.reload")
         | 
| @@ -651,8 +552,10 @@ class Narou::AppServer < Sinatra::Base | |
| 651 552 | 
             
                pass if tag_params.empty?
         | 
| 652 553 | 
             
                Narou::Worker.push do
         | 
| 653 554 | 
             
                  cmd = Command::Update.new
         | 
| 654 | 
            -
                   | 
| 655 | 
            -
                     | 
| 555 | 
            +
                  if table_reload_timing == "every"
         | 
| 556 | 
            +
                    cmd.on(:success) do
         | 
| 557 | 
            +
                      @@push_server.send_all(:"table.reload")
         | 
| 558 | 
            +
                    end
         | 
| 656 559 | 
             
                  end
         | 
| 657 560 | 
             
                  cmd.execute!(tag_params)
         | 
| 658 561 | 
             
                  @@push_server.send_all(:"table.reload")
         | 
| @@ -763,7 +666,7 @@ class Narou::AppServer < Sinatra::Base | |
| 763 666 |  | 
| 764 667 | 
             
              get "/api/tag_list" do
         | 
| 765 668 | 
             
                result =
         | 
| 766 | 
            -
                  '<div><span class="tag label label-default" data-tag="">タグ検索を解除</span></div>' \
         | 
| 669 | 
            +
                  '<div><span class="tag tag-reset label label-default" data-tag="">タグ検索を解除</span></div>' \
         | 
| 767 670 | 
             
                  '<div class="text-muted" style="font-size:10px">Altキーを押しながらで除外検索</div>'
         | 
| 768 671 | 
             
                tagname_list = Command::Tag.get_tag_list.keys
         | 
| 769 672 | 
             
                tagname_list.sort.each do |tagname|
         | 
| @@ -55,7 +55,7 @@ var Narou = (function() { | |
| 55 55 | 
             
              storage = new Storage();
         | 
| 56 56 |  | 
| 57 57 | 
             
              /*************************************************************************
         | 
| 58 | 
            -
               * ユーティリティ
         | 
| 58 | 
            +
               * ユーティリティ / Utility
         | 
| 59 59 | 
             
               *************************************************************************/
         | 
| 60 60 | 
             
              $.extend(Narou, {
         | 
| 61 61 | 
             
                registerCloseHandler: function(callback) {
         | 
| @@ -115,6 +115,19 @@ var Narou = (function() { | |
| 115 115 | 
             
                allowScroll: function() {
         | 
| 116 116 | 
             
                  $("html, body").css("overflow", "");
         | 
| 117 117 | 
             
                },
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                // 桁数の多い数字を、千や万単位に変換する
         | 
| 120 | 
            +
                unitizeNumeric: function(num) {
         | 
| 121 | 
            +
                  var man = num / 10000 | 0;
         | 
| 122 | 
            +
                  if (man) {
         | 
| 123 | 
            +
                    return man + "万";
         | 
| 124 | 
            +
                  }
         | 
| 125 | 
            +
                  var sen = num / 1000 | 0;
         | 
| 126 | 
            +
                  if (sen) {
         | 
| 127 | 
            +
                    return sen + "千";
         | 
| 128 | 
            +
                  }
         | 
| 129 | 
            +
                  return num;
         | 
| 130 | 
            +
                },
         | 
| 118 131 | 
             
              });
         | 
| 119 132 |  | 
| 120 133 | 
             
              /*************************************************************************
         | 
| @@ -1145,8 +1158,20 @@ var Narou = (function() { | |
| 1145 1158 | 
             
                    self.search();
         | 
| 1146 1159 | 
             
                    self.myFilterClearToggleVisiblity();
         | 
| 1147 1160 | 
             
                  });
         | 
| 1161 | 
            +
             | 
| 1162 | 
            +
                  this.table
         | 
| 1163 | 
            +
                    // 通常単語を追加するためのイベント
         | 
| 1164 | 
            +
                    .on("click", "[data-add-filter]", function(e) {
         | 
| 1165 | 
            +
                      e.stopPropagation();
         | 
| 1166 | 
            +
                      self.appendWordToFilter($(this).data("addFilter"));
         | 
| 1167 | 
            +
                    })
         | 
| 1168 | 
            +
                    // 追加イベントが発生した時に行選択イベントが起こらないように
         | 
| 1169 | 
            +
                    .on("mousedown", "[data-add-filter]", function(e) {
         | 
| 1170 | 
            +
                      e.stopPropagation();
         | 
| 1171 | 
            +
                    });
         | 
| 1148 1172 | 
             
                },
         | 
| 1149 1173 |  | 
| 1174 | 
            +
                // フィルタにタグを追加
         | 
| 1150 1175 | 
             
                appendTagToFilter: function(tag_name, exclude) {
         | 
| 1151 1176 | 
             
                  if (_.includes(this.filter_tags, tag_name) ||
         | 
| 1152 1177 | 
             
                      _.includes(this.exclusion_tags, tag_name)) {
         | 
| @@ -1171,6 +1196,14 @@ var Narou = (function() { | |
| 1171 1196 | 
             
                  this.myFilterClearToggleVisiblity();
         | 
| 1172 1197 | 
             
                },
         | 
| 1173 1198 |  | 
| 1199 | 
            +
                // フィルタに通常の単語を追加
         | 
| 1200 | 
            +
                appendWordToFilter: function(word) {
         | 
| 1201 | 
            +
                  var str = (this.myfilter.val() + " " + word).trim() + " ";
         | 
| 1202 | 
            +
                  this.myfilter.val(str);
         | 
| 1203 | 
            +
                  this.search()
         | 
| 1204 | 
            +
                  this.myFilterClearToggleVisiblity();
         | 
| 1205 | 
            +
                },
         | 
| 1206 | 
            +
             | 
| 1174 1207 | 
             
                removeAllTagsByFilter: function() {
         | 
| 1175 1208 | 
             
                  var normal_words = this.splitFilter().normal;
         | 
| 1176 1209 | 
             
                  this.myfilter.val(normal_words.join(" "));
         | 
| @@ -24,14 +24,14 @@ $(document).ready(function() { | |
| 24 24 | 
             
                    id: false, last_update: false, title: true, author: false, sitename: false,
         | 
| 25 25 | 
             
                    toc_url: false, novel_type: false, tags: false, status: false, menu: true,
         | 
| 26 26 | 
             
                    download: true, folder: false, update_button: false, general_lastup: false,
         | 
| 27 | 
            -
                    general_all_no: false, last_check_date: false,
         | 
| 27 | 
            +
                    general_all_no: false, last_check_date: false, length: false, average_length: false,
         | 
| 28 28 | 
             
                  }
         | 
| 29 29 | 
             
                  // PC
         | 
| 30 30 | 
             
                : {
         | 
| 31 31 | 
             
                    id: true, last_update: true, title: true, author: true, sitename: true,
         | 
| 32 32 | 
             
                    toc_url: true, novel_type: false, tags: true, status: true, menu: true,
         | 
| 33 33 | 
             
                    download: false, folder: true, update_button: true, general_lastup: true,
         | 
| 34 | 
            -
                    general_all_no: false, last_check_date: false,
         | 
| 34 | 
            +
                    general_all_no: false, last_check_date: false, length: false, average_length: false,
         | 
| 35 35 | 
             
                  });
         | 
| 36 36 |  | 
| 37 37 | 
             
              $.fn.dataTable.Api.register("fireChangeSelect()", function() {
         | 
| @@ -258,10 +258,30 @@ $(document).ready(function() { | |
| 258 258 | 
             
                    data: "title", visible: cell_visible.title },
         | 
| 259 259 | 
             
                  // 作者名
         | 
| 260 260 | 
             
                  { title: "作者名",
         | 
| 261 | 
            -
                    data: "author", visible: cell_visible.author | 
| 261 | 
            +
                    data: "author", visible: cell_visible.author,
         | 
| 262 | 
            +
                    render: function(author, type, row) {
         | 
| 263 | 
            +
                      if (author && type === "display") {
         | 
| 264 | 
            +
                        return sprintf(
         | 
| 265 | 
            +
                          '<span class="add-filter" data-add-filter="%(author)s">%(author)s</span>',
         | 
| 266 | 
            +
                          { author: author }
         | 
| 267 | 
            +
                        );
         | 
| 268 | 
            +
                      }
         | 
| 269 | 
            +
                      return author;
         | 
| 270 | 
            +
                    }
         | 
| 271 | 
            +
                  },
         | 
| 262 272 | 
             
                  // 掲載サイト
         | 
| 263 273 | 
             
                  { title: "掲載",
         | 
| 264 | 
            -
                    data: "sitename", visible: cell_visible.sitename | 
| 274 | 
            +
                    data: "sitename", visible: cell_visible.sitename,
         | 
| 275 | 
            +
                    render: function(sitename, type, row) {
         | 
| 276 | 
            +
                      if (sitename && type === "display") {
         | 
| 277 | 
            +
                        return sprintf(
         | 
| 278 | 
            +
                          '<span class="add-filter" data-add-filter="%(sitename)s">%(sitename)s</span>',
         | 
| 279 | 
            +
                          { sitename: sitename }
         | 
| 280 | 
            +
                        );
         | 
| 281 | 
            +
                      }
         | 
| 282 | 
            +
                      return sitename;
         | 
| 283 | 
            +
                    }
         | 
| 284 | 
            +
                  },
         | 
| 265 285 | 
             
                  // 小説種別
         | 
| 266 286 | 
             
                  { title: "種別",
         | 
| 267 287 | 
             
                    data: "novel_type", className: "text-center", width: "25px",
         | 
| @@ -282,6 +302,31 @@ $(document).ready(function() { | |
| 282 302 | 
             
                      return data;
         | 
| 283 303 | 
             
                    }
         | 
| 284 304 | 
             
                  },
         | 
| 305 | 
            +
                  // 文字数
         | 
| 306 | 
            +
                  {
         | 
| 307 | 
            +
                    title: "文字数",
         | 
| 308 | 
            +
                    data: "length", visible: cell_visible.length,
         | 
| 309 | 
            +
                    className: "text-center", searchable: false, orderSequence: [ "desc", "asc" ],
         | 
| 310 | 
            +
                    render: function(length, type, row) {
         | 
| 311 | 
            +
                      if (length && type === "display") {
         | 
| 312 | 
            +
                        return Narou.unitizeNumeric(length) + "字";
         | 
| 313 | 
            +
                      }
         | 
| 314 | 
            +
                      return length;
         | 
| 315 | 
            +
                    }
         | 
| 316 | 
            +
                  },
         | 
| 317 | 
            +
                  // 1話あたりの平均文字数
         | 
| 318 | 
            +
                  {
         | 
| 319 | 
            +
                    title: "平均<br>文字数",
         | 
| 320 | 
            +
                    data: "average_length", visible: cell_visible.average_length,
         | 
| 321 | 
            +
                    className: "text-center", searchable: false, orderSequence: [ "desc", "asc" ],
         | 
| 322 | 
            +
                    render: function(_data, type, row) {
         | 
| 323 | 
            +
                      var averageLength = row.length / row.general_all_no | 0;
         | 
| 324 | 
            +
                      if (averageLength && type === "display") {
         | 
| 325 | 
            +
                        return averageLength.toLocaleString();
         | 
| 326 | 
            +
                      }
         | 
| 327 | 
            +
                      return averageLength || null;
         | 
| 328 | 
            +
                    }
         | 
| 329 | 
            +
                  },
         | 
| 285 330 | 
             
                  // 状態
         | 
| 286 331 | 
             
                  { title: "状態",
         | 
| 287 332 | 
             
                    data: "status", visible: cell_visible.status },
         | 
| @@ -850,13 +895,16 @@ $(document).ready(function() { | |
| 850 895 | 
             
              $("#action-view-all").on(click_event_name, function(e) {
         | 
| 851 896 | 
             
                e.preventDefault();
         | 
| 852 897 | 
             
                slideNavbar.slide();
         | 
| 853 | 
            -
                 | 
| 854 | 
            -
             | 
| 855 | 
            -
                   | 
| 856 | 
            -
             | 
| 857 | 
            -
             | 
| 898 | 
            +
                bootbox.confirm("全ての項目を表示します。よろしいですか?", function(result) {
         | 
| 899 | 
            +
                  if (!result) return;
         | 
| 900 | 
            +
                  var aoColumns = table.settings()[0].aoColumns;
         | 
| 901 | 
            +
                  table.columns().eq(0).each(function(index) {
         | 
| 902 | 
            +
                    if (!aoColumns[index].system_column) {
         | 
| 903 | 
            +
                      table.column(index).visible(true);
         | 
| 904 | 
            +
                    }
         | 
| 905 | 
            +
                  });
         | 
| 906 | 
            +
                  table.draw(false);
         | 
| 858 907 | 
             
                });
         | 
| 859 | 
            -
                table.draw(false);
         | 
| 860 908 | 
             
              });
         | 
| 861 909 |  | 
| 862 910 | 
             
              /*
         | 
| @@ -968,8 +1016,14 @@ $(document).ready(function() { | |
| 968 1016 | 
             
               *   表示>表示設定を全てリセット
         | 
| 969 1017 | 
             
               */
         | 
| 970 1018 | 
             
              $("#action-view-reset").on(click_event_name, function(e) {
         | 
| 971 | 
            -
                 | 
| 972 | 
            -
                 | 
| 1019 | 
            +
                e.preventDefault();
         | 
| 1020 | 
            +
                slideNavbar.slide();
         | 
| 1021 | 
            +
                bootbox.confirm("表示に関わる全ての設定がリセットされます。よろしいですか?", function(result) {
         | 
| 1022 | 
            +
                  if (!result) return;
         | 
| 1023 | 
            +
                  // localStorageを全て消してリロードする
         | 
| 1024 | 
            +
                  localStorage.clear();
         | 
| 1025 | 
            +
                  location.href = "/";
         | 
| 1026 | 
            +
                });
         | 
| 973 1027 | 
             
              });
         | 
| 974 1028 |  | 
| 975 1029 | 
             
              /*
         |