narou 3.2.5.1 → 3.3.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 (131) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -5
  3. data/.haml-lint.yml +7 -0
  4. data/.rubocop.yml +23 -5
  5. data/.scss-lint.yml +9 -0
  6. data/ChangeLog.md +86 -0
  7. data/Gemfile.lock +35 -35
  8. data/README.md +80 -64
  9. data/lib/backtracer.rb +2 -2
  10. data/lib/color.rb +5 -1
  11. data/lib/command.rb +7 -2
  12. data/lib/command/alias.rb +3 -5
  13. data/lib/command/backup.rb +3 -5
  14. data/lib/command/browser.rb +3 -5
  15. data/lib/command/clean.rb +5 -1
  16. data/lib/command/console.rb +33 -0
  17. data/lib/command/convert.rb +143 -117
  18. data/lib/command/csv.rb +2 -1
  19. data/lib/command/diff.rb +20 -18
  20. data/lib/command/download.rb +25 -14
  21. data/lib/command/folder.rb +3 -5
  22. data/lib/command/freeze.rb +3 -5
  23. data/lib/command/help.rb +20 -18
  24. data/lib/command/init.rb +4 -3
  25. data/lib/command/inspect.rb +2 -1
  26. data/lib/command/list.rb +10 -8
  27. data/lib/command/list/novel_decorator.rb +2 -1
  28. data/lib/command/log.rb +100 -0
  29. data/lib/command/log/tail.rb +76 -0
  30. data/lib/command/mail.rb +20 -17
  31. data/lib/command/remove.rb +7 -6
  32. data/lib/command/send.rb +23 -20
  33. data/lib/command/setting.rb +74 -40
  34. data/lib/command/tag.rb +16 -15
  35. data/lib/command/trace.rb +2 -2
  36. data/lib/command/update.rb +78 -128
  37. data/lib/command/update/general_lastup_updater.rb +3 -2
  38. data/lib/command/update/hotentry_manager.rb +2 -1
  39. data/lib/command/update/interval.rb +2 -1
  40. data/lib/command/version.rb +2 -1
  41. data/lib/command/web.rb +17 -3
  42. data/lib/commandbase.rb +34 -7
  43. data/lib/commandline.rb +54 -35
  44. data/lib/converterbase.rb +21 -15
  45. data/lib/database.rb +3 -2
  46. data/lib/device.rb +5 -4
  47. data/lib/device/epub.rb +2 -1
  48. data/lib/device/ibooks.rb +2 -1
  49. data/lib/device/ibunko.rb +2 -1
  50. data/lib/device/kindle.rb +2 -1
  51. data/lib/device/kobo.rb +2 -1
  52. data/lib/device/library/cygwin.rb +2 -1
  53. data/lib/device/library/linux.rb +2 -1
  54. data/lib/device/library/mac.rb +2 -1
  55. data/lib/device/library/windows.rb +2 -1
  56. data/lib/device/library/windows/eject.rb +2 -1
  57. data/lib/device/reader.rb +2 -1
  58. data/lib/diffviewer.rb +8 -11
  59. data/lib/downloader.rb +159 -151
  60. data/lib/eventable.rb +2 -1
  61. data/lib/extension.rb +16 -14
  62. data/lib/extensions/jruby.rb +2 -1
  63. data/lib/extensions/monkey_patches.rb +7 -0
  64. data/lib/extensions/monkey_patches/pathname.rb +22 -0
  65. data/lib/extensions/windows.rb +2 -1
  66. data/lib/extensions/windows_write_color.rb +2 -1
  67. data/lib/helper.rb +35 -20
  68. data/lib/html.rb +2 -1
  69. data/lib/illustration.rb +2 -1
  70. data/lib/ini.rb +2 -1
  71. data/lib/input.rb +2 -1
  72. data/lib/inspector.rb +3 -2
  73. data/lib/inventory.rb +3 -3
  74. data/lib/mailer.rb +3 -2
  75. data/lib/mixin/all.rb +8 -0
  76. data/lib/mixin/locker.rb +40 -0
  77. data/lib/mixin/output_error.rb +28 -0
  78. data/lib/narou.rb +69 -51
  79. data/lib/narou/api.rb +2 -4
  80. data/lib/narou_logger.rb +236 -108
  81. data/lib/novelconverter.rb +77 -69
  82. data/lib/novelinfo.rb +4 -2
  83. data/lib/novelsetting.rb +15 -12
  84. data/lib/progressbar.rb +13 -9
  85. data/lib/sitesetting.rb +39 -18
  86. data/lib/template.rb +5 -4
  87. data/lib/version.rb +3 -2
  88. data/lib/web/all.rb +2 -1
  89. data/lib/web/appserver.rb +83 -65
  90. data/lib/web/helper4web.rb +10 -5
  91. data/lib/web/progressbar4web.rb +8 -4
  92. data/lib/web/public/resources/default-style.css +2 -3
  93. data/lib/web/public/resources/narou.library.js +86 -60
  94. data/lib/web/public/resources/narou.queue.js +24 -30
  95. data/lib/web/public/resources/narou.ui.js +22 -3
  96. data/lib/web/public/theme/Cerulean/style.css +5 -5
  97. data/lib/web/public/theme/Darkly/style.css +5 -5
  98. data/lib/web/public/theme/Readable/style.css +5 -5
  99. data/lib/web/public/theme/Slate/style.css +2 -3
  100. data/lib/web/public/theme/Superhero/style.css +2 -3
  101. data/lib/web/public/theme/United/style.css +5 -5
  102. data/lib/web/pushserver.rb +10 -7
  103. data/lib/web/server_helpers.rb +16 -1
  104. data/lib/web/settingmessages.rb +10 -7
  105. data/lib/web/streaminginput.rb +2 -1
  106. data/lib/web/streaminglogger.rb +45 -32
  107. data/lib/web/views/_about.haml +6 -3
  108. data/lib/web/views/_header.haml +2 -3
  109. data/lib/web/views/_move_to_top.haml +2 -0
  110. data/lib/web/views/_queue.haml +7 -0
  111. data/lib/web/views/bookmarklet/insert_button.js.erb +1 -1
  112. data/lib/web/views/index.haml +30 -27
  113. data/lib/web/views/layout.haml +2 -0
  114. data/lib/web/views/novels/setting.haml +3 -4
  115. data/lib/web/views/settings.haml +22 -8
  116. data/lib/web/views/style.scss +54 -3
  117. data/lib/web/views/widget/download.haml +9 -3
  118. data/lib/web/views/widget/drag_and_drop.haml +10 -4
  119. data/lib/web/web_worker.rb +132 -0
  120. data/lib/worker.rb +142 -0
  121. data/narou.gemspec +80 -45
  122. data/narou.rb +6 -4
  123. data/template/novel.txt.erb +1 -0
  124. data/webnovel/kakuyomu.jp.yaml +9 -13
  125. data/webnovel/ncode.syosetu.com.yaml +3 -1
  126. data/webnovel/novel18.syosetu.com.yaml +8 -1
  127. data/webnovel/syosetu.org.yaml +3 -1
  128. data/webnovel/www.akatsuki-novels.com.yaml +4 -2
  129. data/webnovel/www.mai-net.net.yaml +3 -1
  130. metadata +109 -48
  131. data/lib/web/worker.rb +0 -126
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -9,7 +10,7 @@ require_relative "html"
9
10
 
10
11
  class NovelInfo
11
12
  REFRESH_INTERVAL = 10 # キャッシュを捨てて再取得するまでの時間(s)
12
- DEFAULT_OF = "t-nt-ga-s-gf-nu-gl-w-l"
13
+ DEFAULT_OF = "t-nt-ga-s-gf-nu-gl-w-l-e-sitename"
13
14
  @@novel_info_parameters = {}
14
15
 
15
16
  def self.load(setting, toc_source: nil, of: DEFAULT_OF)
@@ -74,6 +75,7 @@ class NovelInfo
74
75
  %w(general_firstup novelupdated_at general_lastup).each do |elm|
75
76
  result[elm] = Helper.date_string_to_time(@setting[elm])
76
77
  end
78
+ result["sitename"] = @setting["sitename"]
77
79
 
78
80
  result
79
81
  end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -59,7 +60,9 @@ class NovelSetting
59
60
  end
60
61
 
61
62
  def load_setting_ini
62
- Ini.load_file(ini_path) rescue Ini.load("")
63
+ Ini.load_file(ini_path)
64
+ rescue Errno::ENOENT
65
+ Ini.load("")
63
66
  end
64
67
 
65
68
  #
@@ -347,7 +350,7 @@ class NovelSetting
347
350
  name: "date_format",
348
351
  type: :string,
349
352
  value: "%Y年%m月%d日",
350
- help: "書式は http://bit.ly/1m5e3w7 を参考"
353
+ help: "書式は http://bit.ly/date_format を参考"
351
354
  },
352
355
  {
353
356
  name: "enable_convert_horizontal_ellipsis",
@@ -389,15 +392,15 @@ class NovelSetting
389
392
  name: "title_date_format",
390
393
  type: :string,
391
394
  value: "(%-m/%-d)",
392
- help: <<-EOS
393
- enable_add_date_to_title で付与する日付のフォーマット。書式は http://bit.ly/1m5e3w7 を参照。
394
- Narou.rb専用の書式として下記のものも使用可能。
395
- $s 2045年までの残り時間(10分単位の4桁の36進数)
396
- $t 小説のタイトル
397
- $ns 小説が掲載されているサイト名
398
- $nt 小説種別(短編 or 連載)
399
- $ntag 小説のタグをカンマ区切りにしたもの
400
- EOS
395
+ help: <<~HELP
396
+ enable_add_date_to_title で付与する日付のフォーマット。書式は http://bit.ly/date_format を参照。
397
+ Narou.rb専用の書式として下記のものも使用可能。
398
+ $t 小説のタイトル($tを使った場合はtitle_date_alignは無視される)
399
+ $s 2045年までの残り時間(10分単位の4桁の36進数)
400
+ $ns 小説が掲載されているサイト名
401
+ $nt 小説種別(短編 or 連載)
402
+ $ntag 小説のタグをカンマ区切りにしたもの
403
+ HELP
401
404
  },
402
405
  {
403
406
  name: "title_date_align",
@@ -1,21 +1,25 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
5
6
 
6
7
  class ProgressBar
7
8
  class OverRangeError < StandardError; end
8
-
9
- def initialize(max, interval = 1, width = 50, char = "*")
9
+
10
+ attr_reader :io
11
+
12
+ def initialize(max, interval = 1, width = 50, char = "*", io: $stdout)
10
13
  @max = max == 0 ? 1.0 : max.to_f
11
14
  @interval = interval
12
15
  @width = width
13
16
  @char = char
14
17
  @counter = 0
18
+ @io = io
15
19
  end
16
20
 
17
21
  def output(num)
18
- return if silence?
22
+ return if silent?
19
23
  if num > @max
20
24
  raise OverRangeError, "`#{num}` over `#{@max}(max)`"
21
25
  end
@@ -24,19 +28,19 @@ class ProgressBar
24
28
  ratio = calc_ratio(num)
25
29
  now = (@width * ratio).round
26
30
  rest = @width - now
27
- STDOUT.print "[" + @char * now + ' ' * rest + "] #{(ratio * 100).round}%\r"
31
+ io.stream.print format("[%s%s] %d%%\r", @char * now, " " * rest, (ratio * 100).round)
28
32
  end
29
33
 
30
34
  def clear
31
- return if silence?
32
- STDOUT.print " " * 79 + "\r"
35
+ return if silent?
36
+ io.stream.print "\e[2K\r" # 行削除して行頭へ移動
33
37
  end
34
38
 
35
39
  def calc_ratio(num)
36
40
  num / @max
37
41
  end
38
42
 
39
- def silence?
40
- $debug || ENV["NAROU_ENV"] == "test"
43
+ def silent?
44
+ ENV["NAROU_ENV"] == "test" || !io.tty? || io.silent?
41
45
  end
42
46
  end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -9,6 +10,8 @@ require_relative "narou/api"
9
10
  class SiteSetting
10
11
  NOVEL_SITE_SETTING_DIR = "webnovel/"
11
12
 
13
+ attr_reader :yaml, :path
14
+
12
15
  class << self
13
16
  #
14
17
  # 小説サイトの定義ファイルを全部読み込む
@@ -17,17 +20,18 @@ class SiteSetting
17
20
  # webnovel ディレクトリからも定義ファイルを読み込む
18
21
  #
19
22
  def load_settings
20
- result = []
23
+ result = {}
21
24
  load_paths = [
22
- File.join(Narou.get_script_dir, NOVEL_SITE_SETTING_DIR, "*.yaml"),
23
- File.join(Narou.get_root_dir, NOVEL_SITE_SETTING_DIR, "*.yaml")
25
+ Narou.script_dir.join(NOVEL_SITE_SETTING_DIR, "*.yaml"),
26
+ Narou.root_dir.join(NOVEL_SITE_SETTING_DIR, "*.yaml")
24
27
  ].uniq.join("\0")
25
28
  Dir.glob(load_paths) do |path|
26
29
  setting = SiteSetting.load_file(path)
27
- if setting["name"] == "小説家になろう"
28
- @narou = setting
29
- end
30
- result << setting
30
+ name = setting["name"]
31
+ @narou ||= setting if name == "小説家になろう"
32
+ origin = result[name]
33
+ origin&.merge(setting)
34
+ result[name] ||= setting
31
35
  end
32
36
  if result.empty?
33
37
  error "小説サイトの定義ファイルがひとつもありません"
@@ -37,8 +41,6 @@ class SiteSetting
37
41
  error "小説家になろうの定義ファイルが見つかりませんでした"
38
42
  exit Narou::EXIT_ERROR_CODE
39
43
  end
40
- # TODO: 配列の並び順で先頭をなろうにしておく。find するときになろうがすぐ引っかかるので効率的
41
- # 設定ファイルに priority を追加して、それでソートする
42
44
  result
43
45
  end
44
46
 
@@ -53,7 +55,7 @@ class SiteSetting
53
55
 
54
56
  def find(toc_url)
55
57
  result = nil
56
- settings.each do |s|
58
+ settings.each_value do |s|
57
59
  setting = s.clone
58
60
  if setting.multi_match(toc_url, "url")
59
61
  result = setting
@@ -68,6 +70,12 @@ class SiteSetting
68
70
  end
69
71
  end
70
72
 
73
+ def initialize(path)
74
+ @match_values = {}
75
+ @yaml = YAML.load_file(path)
76
+ @path = path
77
+ end
78
+
71
79
  def [](key)
72
80
  replace_group_values(key)
73
81
  end
@@ -80,11 +88,6 @@ class SiteSetting
80
88
  @match_values.clear
81
89
  end
82
90
 
83
- def initialize(path)
84
- @match_values = {}
85
- @yaml_setting = YAML.load_file(path).freeze
86
- end
87
-
88
91
  def initialize_copy(_obj)
89
92
  @match_values = {}
90
93
  end
@@ -127,7 +130,7 @@ class SiteSetting
127
130
  end
128
131
 
129
132
  def replace_group_values(key, option_values = {})
130
- buf = option_values[key] || @match_values[key] || @yaml_setting[key]
133
+ buf = option_values[key] || @match_values[key] || yaml[key]
131
134
  return buf if is_container?(buf)
132
135
  if buf.is_a?(Array)
133
136
  buf.map do |dest|
@@ -140,7 +143,7 @@ class SiteSetting
140
143
 
141
144
  def do_replace(dest, option_values)
142
145
  return dest unless dest.respond_to?(:gsub)
143
- values = @yaml_setting.merge(@match_values).merge(option_values)
146
+ values = yaml.merge(@match_values).merge(option_values)
144
147
  dest.gsub(/\\\\k<(.+?)>/) do |match|
145
148
  value = values[$1]
146
149
  if value
@@ -152,4 +155,22 @@ class SiteSetting
152
155
  end
153
156
  end
154
157
  end
158
+
159
+ EXCLUDE_KEYS = %w(name version)
160
+
161
+ def merge(setting)
162
+ validate_version(setting) or return
163
+ (setting.yaml.keys - EXCLUDE_KEYS).each do |key|
164
+ yaml[key] = setting.yaml[key]
165
+ end
166
+ end
167
+
168
+ def validate_version(setting)
169
+ version = setting.yaml["version"]
170
+ return true unless version # version が指定されていない場合は常に上書きを許可する
171
+ return true if version >= yaml["version"]
172
+
173
+ error "#{setting.path} の内容が古いため読み込みをスキップしました"
174
+ false
175
+ end
155
176
  end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -45,9 +46,9 @@ class Template
45
46
  def self.get(src_filename, _binding, binary_version)
46
47
  @@binary_version = binary_version
47
48
  @@src_filename = src_filename
48
- [Narou.get_root_dir, Narou.get_script_dir].each do |dir|
49
- path = File.join(dir, TEMPLATE_DIR, src_filename + ".erb")
50
- next unless File.exist?(path)
49
+ [Narou.root_dir, Narou.script_dir].each do |dir|
50
+ path = dir.join(TEMPLATE_DIR, src_filename + ".erb")
51
+ next unless path.exist?
51
52
  src = Helper::CacheLoader.load(path)
52
53
  result = ERB.new(src, nil, "-").result(_binding)
53
54
  return result
@@ -1,8 +1,9 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
5
6
 
6
7
  module Narou
7
- VERSION = "3.2.5.1"
8
+ VERSION = "3.3.0"
8
9
  end
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -1,4 +1,5 @@
1
- # -*- coding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  #
3
4
  # Copyright 2013 whiteleaf. All rights reserved.
4
5
  #
@@ -10,14 +11,13 @@ require "socket"
10
11
  require "sinatra/base"
11
12
  require "sinatra/json"
12
13
  require "sinatra/reloader" if $development
13
- require "better_errors" if $debug
14
+ # require "better_errors" if $debug
14
15
  require "tilt/erubis"
15
16
  require "tilt/haml"
16
17
  require "tilt/sass"
17
- require_relative "../narou_logger"
18
18
  require_relative "../commandline"
19
19
  require_relative "../inventory"
20
- require_relative "worker"
20
+ require_relative "web_worker"
21
21
  require_relative "pushserver"
22
22
  require_relative "settingmessages"
23
23
  require_relative "server_helpers"
@@ -45,7 +45,7 @@ class Narou::AppServer < Sinatra::Base
45
45
 
46
46
  if $debug
47
47
  use BetterErrors::Middleware
48
- BetterErrors.application_root = Narou.get_script_dir
48
+ BetterErrors.application_root = Narou.script_dir
49
49
  end
50
50
  end
51
51
 
@@ -193,7 +193,7 @@ class Narou::AppServer < Sinatra::Base
193
193
  else
194
194
  params["webui.theme"]
195
195
  end
196
- Narou::Worker.push_as_system_worker do
196
+ Narou::WebWorker.push_as_system_worker do
197
197
  Inventory.clear
198
198
  Database.instance.refresh
199
199
  Narou.load_global_replace_pattern
@@ -223,7 +223,6 @@ class Narou::AppServer < Sinatra::Base
223
223
 
224
224
  post "/settings" do
225
225
  built_arguments = []
226
- output = ""
227
226
  device = params.delete("device")
228
227
  [:local, :global].each do |scope|
229
228
  @setting_variables[scope].each do |name, info|
@@ -252,18 +251,14 @@ class Narou::AppServer < Sinatra::Base
252
251
  # されないように最後にまわす
253
252
  built_arguments << "device=#{device}" if device
254
253
  unless built_arguments.empty?
255
- $stdout.silence do
256
- setting = Command::Setting.new
257
- setting.on(:error) do |msg, name|
258
- if name
259
- @error_list[name] = msg
260
- end
261
- end
262
- begin
263
- setting.execute(built_arguments)
264
- rescue SystemExit
254
+ setting = Command::Setting.new
255
+ setting.on(:error) do |msg, name|
256
+ if name
257
+ @error_list[name] = msg
265
258
  end
266
259
  end
260
+ setting.execute!(built_arguments, io: Narou::NullIO.new)
261
+ Inventory.clear
267
262
  end
268
263
 
269
264
  # 置換設定保存
@@ -283,7 +278,7 @@ class Narou::AppServer < Sinatra::Base
283
278
  else
284
279
  session[:alert] = [ "#{@error_list.size}個の設定にエラーがありました", "danger" ]
285
280
  end
286
- haml :settings
281
+ redirect to "/settings"
287
282
  end
288
283
 
289
284
  get "/settings" do
@@ -427,7 +422,7 @@ class Narou::AppServer < Sinatra::Base
427
422
  postscripts_count = 0
428
423
  toc["subtitles"].each do |sub|
429
424
  begin
430
- element = YAML.load_file(downloader.create_section_file_path(sub))["element"]
425
+ element = YAML.load_file(downloader.section_file_path(sub))["element"]
431
426
  data_type = element["data_type"] || "text"
432
427
  introduction = element["introduction"] || ""
433
428
  postscript = element["postscript"] || ""
@@ -505,6 +500,7 @@ class Narou::AppServer < Sinatra::Base
505
500
  is_frozen ? "凍結" : nil,
506
501
  tags.include?("end") ? "完結" : nil,
507
502
  tags.include?("404") ? "削除" : nil,
503
+ data["suspend"] ? "中断" : nil
508
504
  ].compact.join(", "),
509
505
  download: %!<a href="/novels/#{id}/download" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-download-alt"></span></a>!,
510
506
  frozen: is_frozen,
@@ -522,12 +518,13 @@ class Narou::AppServer < Sinatra::Base
522
518
  end
523
519
 
524
520
  post "/api/cancel" do
525
- Narou::Worker.cancel
521
+ Narou::WebWorker.cancel
522
+ Narou::Worker.cancel if Narou.concurrency_enabled?
526
523
  end
527
524
 
528
525
  post "/api/convert" do
529
526
  ids = select_valid_novel_ids(params["ids"]) or pass
530
- Narou::Worker.push do
527
+ concurrency_push do
531
528
  CommandLine.run!("convert", "--no-open", ids)
532
529
  end
533
530
  end
@@ -538,7 +535,7 @@ class Narou::AppServer < Sinatra::Base
538
535
  targets = targets.kind_of?(Array) ? targets : targets.split
539
536
  opt_mail = "--mail" if query_to_boolean(params["mail"])
540
537
  pass if targets.size == 0
541
- Narou::Worker.push do
538
+ Narou::WebWorker.push do
542
539
  CommandLine.run!("download", targets, opt_mail)
543
540
  @@push_server.send_all(:"table.reload")
544
541
  end
@@ -546,7 +543,7 @@ class Narou::AppServer < Sinatra::Base
546
543
 
547
544
  post "/api/download_force" do
548
545
  ids = select_valid_novel_ids(params["ids"]) or pass
549
- Narou::Worker.push do
546
+ Narou::WebWorker.push do
550
547
  CommandLine.run!("download", "--force", ids)
551
548
  @@push_server.send_all(:"table.reload")
552
549
  end
@@ -554,8 +551,10 @@ class Narou::AppServer < Sinatra::Base
554
551
 
555
552
  post "/api/mail" do
556
553
  ids = select_valid_novel_ids(params["ids"]) || []
557
- Narou::Worker.push do
558
- CommandLine.run!("mail", ids)
554
+ Narou::WebWorker.push do
555
+ Narou.concurrency_call do
556
+ CommandLine.run!("mail", ids, io: $stdout2)
557
+ end
559
558
  end
560
559
  end
561
560
 
@@ -565,7 +564,8 @@ class Narou::AppServer < Sinatra::Base
565
564
  if params["force"] == "true"
566
565
  opt_arguments << "--force"
567
566
  end
568
- Narou::Worker.push do
567
+ Narou::WebWorker.push do
568
+ puts "<white>更新を開始します</white>".termcolor
569
569
  cmd = Command::Update.new
570
570
  if table_reload_timing == "every"
571
571
  cmd.on(:success) do
@@ -587,7 +587,7 @@ class Narou::AppServer < Sinatra::Base
587
587
  "^tag:#{tag}"
588
588
  end
589
589
  pass if tag_params.empty?
590
- Narou::Worker.push do
590
+ Narou::WebWorker.push do
591
591
  cmd = Command::Update.new
592
592
  if table_reload_timing == "every"
593
593
  cmd.on(:success) do
@@ -601,14 +601,22 @@ class Narou::AppServer < Sinatra::Base
601
601
 
602
602
  post "/api/send" do
603
603
  ids = select_valid_novel_ids(params["ids"]) || []
604
- Narou::Worker.push do
605
- CommandLine.run!("send", ids)
604
+ Narou::WebWorker.push do
605
+ Narou.concurrency_call do
606
+ CommandLine.run!("send", ids, io: $stdout2)
607
+ end
608
+ end
609
+ end
610
+
611
+ post "/api/backup_bookmark" do
612
+ Narou::WebWorker.push do
613
+ CommandLine.run!("send", "--backup-bookmark")
606
614
  end
607
615
  end
608
616
 
609
617
  post "/api/freeze" do
610
618
  ids = select_valid_novel_ids(params["ids"]) or pass
611
- Narou::Worker.push do
619
+ Narou::WebWorker.push do
612
620
  CommandLine.run!("freeze", ids)
613
621
  @@push_server.send_all(:"table.reload")
614
622
  end
@@ -616,7 +624,7 @@ class Narou::AppServer < Sinatra::Base
616
624
 
617
625
  post "/api/freeze_on" do
618
626
  ids = select_valid_novel_ids(params["ids"]) or pass
619
- Narou::Worker.push do
627
+ Narou::WebWorker.push do
620
628
  CommandLine.run!("freeze", "--on", ids)
621
629
  @@push_server.send_all(:"table.reload")
622
630
  end
@@ -624,7 +632,7 @@ class Narou::AppServer < Sinatra::Base
624
632
 
625
633
  post "/api/freeze_off" do
626
634
  ids = select_valid_novel_ids(params["ids"]) or pass
627
- Narou::Worker.push do
635
+ Narou::WebWorker.push do
628
636
  CommandLine.run!("freeze", "--off", ids)
629
637
  @@push_server.send_all(:"table.reload")
630
638
  end
@@ -636,7 +644,7 @@ class Narou::AppServer < Sinatra::Base
636
644
  if params["with_file"] == "true"
637
645
  opt_arguments << "--with-file"
638
646
  end
639
- Narou::Worker.push do
647
+ Narou::WebWorker.push do
640
648
  CommandLine.run!("remove", "--yes", ids, opt_arguments)
641
649
  @@push_server.send_all(:"table.reload")
642
650
  end
@@ -644,7 +652,7 @@ class Narou::AppServer < Sinatra::Base
644
652
 
645
653
  post "/api/remove_with_file" do
646
654
  ids = select_valid_novel_ids(params["ids"]) or pass
647
- Narou::Worker.push do
655
+ Narou::WebWorker.push do
648
656
  CommandLine.run!("remove", "--yes", "--with-file", ids)
649
657
  @@push_server.send_all(:"table.reload")
650
658
  end
@@ -653,12 +661,13 @@ class Narou::AppServer < Sinatra::Base
653
661
  post "/api/diff" do
654
662
  ids = select_valid_novel_ids(params["ids"]) or pass
655
663
  number = params["number"] || "1"
656
- Narou::Worker.push do
657
- # diff コマンドは1度に一つのIDしか受け取らないので
664
+ disabled_log_io = $stdout.dup_with_disabled_logging
665
+ Narou::WebWorker.push do
666
+ # diff コマンドは1度に一つのIDしか受け取らないので一つずつ表示する
658
667
  ids.each do |id|
659
668
  # セキュリティ的にWEB UIでは独自の差分表示のみ使う
660
669
  CommandLine.run!("diff", "--no-tool", id, "--number", number)
661
- Helper.print_horizontal_rule
670
+ Helper.print_horizontal_rule(disabled_log_io)
662
671
  end
663
672
  end
664
673
  end
@@ -673,14 +682,14 @@ class Narou::AppServer < Sinatra::Base
673
682
  post "/api/diff_clean" do
674
683
  target = params["target"] or pass
675
684
  id = Downloader.get_id_by_target(target) or pass
676
- Narou::Worker.push do
685
+ Narou::WebWorker.push do
677
686
  CommandLine.run!("diff", "--clean", id)
678
687
  end
679
688
  end
680
689
 
681
690
  post "/api/inspect" do
682
691
  ids = select_valid_novel_ids(params["ids"]) or pass
683
- Narou::Worker.push do
692
+ Narou::WebWorker.push do
684
693
  CommandLine.run!("inspect", ids)
685
694
  end
686
695
  end
@@ -692,18 +701,29 @@ class Narou::AppServer < Sinatra::Base
692
701
 
693
702
  post "/api/backup" do
694
703
  ids = select_valid_novel_ids(params["ids"]) or pass
695
- Narou::Worker.push do
704
+ Narou::WebWorker.push do
696
705
  CommandLine.run!("backup", ids)
697
706
  end
698
707
  end
699
708
 
709
+ get "/api/history" do
710
+ case params["stream"]
711
+ when "stdout2"
712
+ $stdout2.string
713
+ else
714
+ $stdout.string
715
+ end
716
+ end
717
+
700
718
  post "/api/clear_history" do
701
719
  Narou::PushServer.instance.clear_history
720
+ $stdout.string.clear
721
+ $stdout2.string.clear if Narou.concurrency_enabled?
702
722
  end
703
723
 
704
724
  get "/api/tag_list" do
705
725
  result =
706
- '<div><span class="tag tag-reset label label-default" data-tag="">タグ検索を解除</span></div>' \
726
+ +'<div><span class="tag tag-reset label label-default" data-tag="">タグ検索を解除</span></div>' \
707
727
  '<div class="text-muted" style="font-size:10px">Altキーを押しながらで除外検索</div>'
708
728
  tagname_list = Command::Tag.get_tag_list.keys
709
729
  tagname_list.sort.each do |tagname|
@@ -714,7 +734,7 @@ class Narou::AppServer < Sinatra::Base
714
734
  result
715
735
  end
716
736
 
717
- get "/api/taginfo.json" do
737
+ post "/api/taginfo.json" do
718
738
  ids = select_valid_novel_ids(params["ids"]) or pass
719
739
  ids.map!(&:to_i)
720
740
  database = Database.instance
@@ -740,18 +760,16 @@ class Narou::AppServer < Sinatra::Base
740
760
  ids = select_valid_novel_ids(params["ids"]) or pass
741
761
  # key と value を重複を維持したまま反転
742
762
  invert_states = params["states"].inject({}) { |h,(k,v)| (h[v] ||= []) << k; h }
743
- $stdout.silence do
744
- invert_states.each do |state, tags|
745
- case state.to_i
746
- when 0
747
- # タグを削除
748
- CommandLine.run!("tag", "--delete", tags.join(" "), ids)
749
- when 1
750
- # 現状を維持(何もしない)
751
- when 2
752
- # タグを追加
753
- CommandLine.run!("tag", "--add", tags.join(" "), ids)
754
- end
763
+ invert_states.each do |state, tags|
764
+ case state.to_i
765
+ when 0
766
+ # タグを削除
767
+ Command::Tag.execute!("--delete", tags.join(" "), ids, io: Narou::NullIO.new)
768
+ when 1
769
+ # 現状を維持(何もしない)
770
+ when 2
771
+ # タグを追加
772
+ Command::Tag.execute!("--add", tags.join(" "), ids, io: Narou::NullIO.new)
755
773
  end
756
774
  end
757
775
  @@push_server.send_all(:"table.reload")
@@ -759,9 +777,9 @@ class Narou::AppServer < Sinatra::Base
759
777
  end
760
778
 
761
779
  get "/api/get_queue_size" do
762
- res = {
763
- size: Narou::Worker.instance.size
764
- }
780
+ res = [
781
+ Narou::WebWorker.instance.size, Narou::Worker.size
782
+ ]
765
783
  json res
766
784
  end
767
785
 
@@ -769,7 +787,7 @@ class Narou::AppServer < Sinatra::Base
769
787
  option = params["option"]
770
788
  option = nil if option == "all"
771
789
  is_update_modified = params["is_update_modified"] == "true"
772
- Narou::Worker.push do
790
+ Narou::WebWorker.push do
773
791
  CommandLine.run!(["update", "--gl", option].compact)
774
792
  @@push_server.send_all(:"table.reload")
775
793
  @@push_server.send_all(:"tag.updateCanvas")
@@ -784,7 +802,7 @@ class Narou::AppServer < Sinatra::Base
784
802
 
785
803
  post "/api/setting_burn" do
786
804
  ids = select_valid_novel_ids(params["ids"]) or pass
787
- Narou::Worker.push do
805
+ Narou::WebWorker.push do
788
806
  CommandLine.run!("setting", "--burn", ids)
789
807
  end
790
808
  end
@@ -817,7 +835,7 @@ class Narou::AppServer < Sinatra::Base
817
835
 
818
836
  # ダウンロード登録すると同時にグレーのボタン画像を返す
819
837
  get "/api/download4ssl" do
820
- Narou::Worker.push do
838
+ Narou::WebWorker.push do
821
839
  CommandLine.run!("download", params["target"])
822
840
  @@push_server.send_all(:"table.reload")
823
841
  end
@@ -838,7 +856,7 @@ class Narou::AppServer < Sinatra::Base
838
856
  end
839
857
 
840
858
  get "/api/validate_url_regexp_list" do
841
- json SiteSetting.settings.map { |setting|
859
+ json SiteSetting.settings.values.map { |setting|
842
860
  Array(setting["url"]).map do |url|
843
861
  "(#{url.gsub(/\?<.+?>/, "?:").gsub("\\", "\\\\")})"
844
862
  end
@@ -877,8 +895,8 @@ class Narou::AppServer < Sinatra::Base
877
895
  puts "<bold><green>端末を取り外しました</green></bold>".termcolor
878
896
  end
879
897
  if params["enqueue"] == "true"
880
- Narou::Worker.push do
881
- do_eject.call
898
+ Narou::WebWorker.push do
899
+ Narou.concurrency_call(&do_eject)
882
900
  end
883
901
  else
884
902
  do_eject.call
@@ -923,7 +941,7 @@ class Narou::AppServer < Sinatra::Base
923
941
  end
924
942
 
925
943
  ALLOW_HOSTS = [].tap do |hosts|
926
- SiteSetting.settings.each do |s|
944
+ SiteSetting.settings.each_value do |s|
927
945
  hosts << s["domain"]
928
946
  end
929
947
  hosts.freeze
@@ -939,7 +957,7 @@ class Narou::AppServer < Sinatra::Base
939
957
  get "/widget/download" do
940
958
  target = params["target"] or error("targetを指定して下さい")
941
959
  mail = query_to_boolean(params["mail"]) ? "--mail" : nil
942
- Narou::Worker.push do
960
+ Narou::WebWorker.push do
943
961
  CommandLine.run!("download", target, mail)
944
962
  @@push_server.send_all(:"table.reload")
945
963
  end