narou 2.8.3.1 → 2.9.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +77 -0
- data/Gemfile +2 -1
- data/README.md +69 -86
- data/lib/command/convert.rb +10 -11
- data/lib/command/init.rb +2 -2
- data/lib/command/list.rb +12 -3
- data/lib/command/setting.rb +20 -5
- data/lib/command/update.rb +0 -3
- data/lib/command/version.rb +2 -3
- data/lib/command/web.rb +58 -7
- data/lib/converterbase.rb +7 -24
- data/lib/database.rb +7 -6
- data/lib/device.rb +15 -1
- data/lib/device/ibunko.rb +1 -2
- data/lib/device/library/mac.rb +7 -0
- data/lib/downloader.rb +44 -21
- data/lib/extension.rb +25 -0
- data/lib/helper.rb +4 -3
- data/lib/html.rb +18 -2
- data/lib/narou.rb +20 -0
- data/lib/novelconverter.rb +11 -35
- data/lib/novelinfo.rb +19 -8
- data/lib/novelsetting.rb +0 -6
- data/lib/version.rb +1 -1
- data/lib/web/appserver.rb +134 -15
- data/lib/web/public/favicon.ico +0 -0
- data/lib/web/public/resources/common.ui.js +2 -2
- data/lib/web/public/resources/narou.library.js +657 -91
- data/lib/web/public/resources/narou.queue.js +1 -1
- data/lib/web/public/resources/narou.ui.js +253 -102
- data/lib/web/public/resources/sprintf.js +245 -0
- data/lib/web/pushserver.rb +14 -3
- data/lib/web/views/_about.haml +188 -0
- data/lib/web/views/{diff_list.haml → _diff_list.haml} +0 -0
- data/lib/web/views/{edit_replace_txt.haml → _edit_replace_txt.haml} +4 -4
- data/lib/web/views/_rebooting.haml +18 -0
- data/lib/web/views/bookmarklet/download.js.erb +2 -2
- data/lib/web/views/bookmarklet/insert_button.js.erb +1 -1
- data/lib/web/views/edit_menu.haml +223 -0
- data/lib/web/views/help.haml +29 -12
- data/lib/web/views/index.haml +99 -88
- data/lib/web/views/layout.haml +5 -3
- data/lib/web/views/notepad.haml +39 -0
- data/lib/web/views/novels/setting.haml +15 -5
- data/lib/web/views/settings.haml +2 -2
- data/lib/web/views/style.scss +72 -21
- data/lib/web/views/widget/download.haml +3 -2
- data/lib/web/views/widget/drag_and_drop.haml +3 -2
- data/lib/web/views/widget/notepad.haml +44 -0
- data/narou.gemspec +75 -6
- data/narou.rb +8 -14
- data/preset/ncode.syosetu.com/n5115cq/converter.rb +30 -0
- data/preset/ncode.syosetu.com/n7594ct/converter.rb +37 -0
- data/preset/ncode.syosetu.com/n8725k/converter.rb +1 -1
- data/preset/vertical_font.css +0 -10
- data/spec/generator/convert_spec_gen.rb +2 -0
- data/template/novel.txt.erb +3 -0
- data/webnovel/https.syosetu.org.yaml +1 -1
- data/webnovel/kakuyomu.jp.yaml +82 -0
- data/webnovel/ncode.syosetu.com.yaml +1 -0
- data/webnovel/syosetu.org.yaml +1 -1
- metadata +89 -12
- data/lib/web/views/about.haml +0 -85
- data/preset/DMincho.ttf +0 -0
data/lib/narou.rb
CHANGED
@@ -21,6 +21,7 @@ module Narou
|
|
21
21
|
GLOBAL_REPLACE_NAME = "replace.txt"
|
22
22
|
EXIT_ERROR_CODE = 127
|
23
23
|
EXIT_INTERRUPT = 126
|
24
|
+
EXIT_REQUEST_REBOOT = 125
|
24
25
|
|
25
26
|
UPDATE_SORT_KEYS = {
|
26
27
|
"id" => "ID", "last_update" => "更新日", "title" => "タイトル", "author" => "作者名",
|
@@ -275,5 +276,24 @@ module Narou
|
|
275
276
|
type == 2 ? "短編" : "連載"
|
276
277
|
end
|
277
278
|
|
279
|
+
#
|
280
|
+
# Narou.rb gem の最新バージョン番号を取得する
|
281
|
+
#
|
282
|
+
# rubygems公式APIによる取得は、WindowsでのSSL証明書問題で取得出来ない
|
283
|
+
# 環境があるため、gemコマンド経由で取得する
|
284
|
+
#
|
285
|
+
def latest_version
|
286
|
+
response = `gem search ^narou$`.split("\n")
|
287
|
+
if response.last =~ /\Anarou \((.+?)\)\z/
|
288
|
+
$1
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def commit_version
|
293
|
+
cv_path = File.expand_path("commitversion", get_script_dir)
|
294
|
+
File.read(cv_path) if File.exist?(cv_path)
|
295
|
+
end
|
296
|
+
memoize :commit_version
|
297
|
+
|
278
298
|
end
|
279
299
|
end
|
data/lib/novelconverter.rb
CHANGED
@@ -23,8 +23,6 @@ class NovelConverter
|
|
23
23
|
NOVEL_TEXT_TEMPLATE_NAME = "novel.txt"
|
24
24
|
NOVEL_TEXT_TEMPLATE_NAME_FOR_IBUNKO = "ibunko_novel.txt"
|
25
25
|
|
26
|
-
attr_reader :use_dakuten_font
|
27
|
-
|
28
26
|
if Narou.already_init?
|
29
27
|
@@site_settings = Downloader.load_settings
|
30
28
|
end
|
@@ -41,10 +39,7 @@ class NovelConverter
|
|
41
39
|
setting = NovelSetting.load(target, options[:ignore_force], options[:ignore_default])
|
42
40
|
if setting
|
43
41
|
novel_converter = new(setting, options[:output_filename], options[:display_inspector])
|
44
|
-
return
|
45
|
-
converted_txt_path: novel_converter.convert_main,
|
46
|
-
use_dakuten_font: novel_converter.use_dakuten_font
|
47
|
-
}
|
42
|
+
return novel_converter.convert_main
|
48
43
|
end
|
49
44
|
nil
|
50
45
|
end
|
@@ -72,22 +67,8 @@ class NovelConverter
|
|
72
67
|
if options[:encoding]
|
73
68
|
text.force_encoding(options[:encoding]).encode!(Encoding::UTF_8)
|
74
69
|
end
|
75
|
-
{
|
76
|
-
converted_txt_path: novel_converter.convert_main(text),
|
77
|
-
use_dakuten_font: novel_converter.use_dakuten_font
|
78
|
-
}
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.stash_aozora_fonts_directory
|
82
|
-
fonts_path = File.join(File.dirname(Narou.get_aozoraepub3_path), "template/OPS/fonts")
|
83
|
-
return unless File.exist?(fonts_path)
|
84
|
-
FileUtils.mv(fonts_path, fonts_path + "_hide")
|
85
|
-
end
|
86
70
|
|
87
|
-
|
88
|
-
fonts_path = File.join(File.dirname(Narou.get_aozoraepub3_path), "template/OPS/fonts")
|
89
|
-
return unless File.exist?(fonts_path + "_hide")
|
90
|
-
FileUtils.mv(fonts_path + "_hide", fonts_path)
|
71
|
+
novel_converter.convert_main(text)
|
91
72
|
end
|
92
73
|
|
93
74
|
#
|
@@ -100,7 +81,7 @@ class NovelConverter
|
|
100
81
|
#
|
101
82
|
# 返り値:正常終了 :success、エラー終了 :error、AozoraEpub3が見つからなかった nil
|
102
83
|
#
|
103
|
-
def self.txt_to_epub(filename,
|
84
|
+
def self.txt_to_epub(filename, dst_dir = nil, device = nil, verbose = false)
|
104
85
|
abs_srcpath = File.expand_path(filename)
|
105
86
|
src_dir = File.dirname(abs_srcpath)
|
106
87
|
|
@@ -149,14 +130,12 @@ class NovelConverter
|
|
149
130
|
if Helper.os_windows?
|
150
131
|
command = "cmd /c " + command.encode(Encoding::Windows_31J)
|
151
132
|
end
|
152
|
-
stash_aozora_fonts_directory unless use_dakuten_font
|
153
133
|
print "AozoraEpub3でEPUBに変換しています"
|
154
134
|
begin
|
155
135
|
res = Helper::AsyncCommand.exec(command) do
|
156
136
|
print "."
|
157
137
|
end
|
158
138
|
ensure
|
159
|
-
visible_aozora_fonts_directory unless use_dakuten_font
|
160
139
|
Dir.chdir(pwd)
|
161
140
|
end
|
162
141
|
|
@@ -267,7 +246,6 @@ class NovelConverter
|
|
267
246
|
#
|
268
247
|
def self.convert_txt_to_ebook_file(txt_path, options)
|
269
248
|
options = {
|
270
|
-
use_dakuten_font: false,
|
271
249
|
dst_dir: nil,
|
272
250
|
device: nil,
|
273
251
|
verbose: false,
|
@@ -283,8 +261,7 @@ class NovelConverter
|
|
283
261
|
return false if options[:no_epub]
|
284
262
|
clean_up_file_list << txt_path unless options[:no_cleanup_txt]
|
285
263
|
# epub
|
286
|
-
status = NovelConverter.txt_to_epub(txt_path, options[:
|
287
|
-
options[:dst_dir], device, options[:verbose])
|
264
|
+
status = NovelConverter.txt_to_epub(txt_path, options[:dst_dir], device, options[:verbose])
|
288
265
|
return nil if status != :success
|
289
266
|
if device && device.kobo?
|
290
267
|
epub_ext = device.ebook_file_ext
|
@@ -340,7 +317,6 @@ class NovelConverter
|
|
340
317
|
@inspector = Inspector.new(@setting)
|
341
318
|
@illustration = Illustration.new(@setting, @inspector)
|
342
319
|
@display_inspector = display_inspector
|
343
|
-
@use_dakuten_font = false
|
344
320
|
@converter = create_converter
|
345
321
|
@converter.output_text_dir = output_text_dir
|
346
322
|
@data = @novel_id ? Database.instance.get_data("id", @novel_id) : {}
|
@@ -415,11 +391,13 @@ class NovelConverter
|
|
415
391
|
end
|
416
392
|
|
417
393
|
#
|
418
|
-
#
|
394
|
+
# 2035年くらいまでの残り時間を10分単位の36進数で取得する
|
419
395
|
# hyff のような文字列が取得可能
|
396
|
+
# 小説家になろうで、もっとも古い作品が2004年5月1日11時49分なので、
|
397
|
+
# その小説がちょうど4桁の zzzz となるように調整してある
|
420
398
|
#
|
421
399
|
def calc_reverse_short_time(time)
|
422
|
-
((
|
400
|
+
((2091149000 - time.to_i) / (10 * 60)).to_s(36).rjust(4, "0")
|
423
401
|
end
|
424
402
|
|
425
403
|
#
|
@@ -427,7 +405,7 @@ class NovelConverter
|
|
427
405
|
# 日付の種類は title_date_target で指定する
|
428
406
|
#
|
429
407
|
# strftime の書式の他に拡張書式として $s, $t をサポートする
|
430
|
-
# $s
|
408
|
+
# $s 2035年くらいまでの残り時間を10分単位の36進数(4桁)
|
431
409
|
# $t タイトル自身。書式の中で自由な位置にタイトルを埋め込める
|
432
410
|
# $ns 小説が掲載されているサイト名
|
433
411
|
# $nt 小説種別(短編 or 連載)
|
@@ -562,8 +540,6 @@ class NovelConverter
|
|
562
540
|
# 表紙の挿絵注記を3行目に挟み込む
|
563
541
|
converted_text = [splited[0], splited[1], create_cover_chuki, splited[2]].join("\n")
|
564
542
|
|
565
|
-
@use_dakuten_font = @converter.use_dakuten_font
|
566
|
-
|
567
543
|
converted_text
|
568
544
|
end
|
569
545
|
|
@@ -623,8 +599,10 @@ class NovelConverter
|
|
623
599
|
section["chapter"] = @converter.convert(section["chapter"], "chapter")
|
624
600
|
end
|
625
601
|
@inspector.subtitle = section["subtitle"]
|
602
|
+
section["subtitle"] = @converter.convert(section["subtitle"], "subtitle")
|
626
603
|
element = section["element"]
|
627
604
|
data_type = element.delete("data_type") || "text"
|
605
|
+
@converter.data_type = data_type
|
628
606
|
element.each do |text_type, elm_text|
|
629
607
|
if data_type == "html"
|
630
608
|
html.string = elm_text
|
@@ -632,10 +610,8 @@ class NovelConverter
|
|
632
610
|
end
|
633
611
|
element[text_type] = @converter.convert(elm_text, text_type)
|
634
612
|
end
|
635
|
-
section["subtitle"] = @converter.convert(section["subtitle"], "subtitle")
|
636
613
|
sections << section
|
637
614
|
end
|
638
|
-
@use_dakuten_font = @converter.use_dakuten_font
|
639
615
|
sections
|
640
616
|
ensure
|
641
617
|
trigger(:"convert_main.finish")
|
data/lib/novelinfo.rb
CHANGED
@@ -11,36 +11,47 @@ class NovelInfo
|
|
11
11
|
REFRESH_INTERVAL = 10 * 60 # キャッシュを捨てて再取得するまでの時間(s)
|
12
12
|
@@novel_info_parameters = {}
|
13
13
|
|
14
|
-
def self.load(setting)
|
15
|
-
info = new(setting)
|
14
|
+
def self.load(setting, toc_source = nil)
|
15
|
+
info = new(setting, toc_source)
|
16
16
|
info.parse_novel_info
|
17
17
|
end
|
18
18
|
|
19
|
-
def initialize(setting)
|
19
|
+
def initialize(setting, toc_source = nil)
|
20
20
|
@setting = setting
|
21
21
|
@ncode = @setting["ncode"]
|
22
|
+
@toc_source = toc_source
|
22
23
|
@@novel_info_parameters[@setting["name"]] ||= {}
|
23
24
|
end
|
24
25
|
|
25
26
|
def parse_novel_info
|
26
27
|
info_url = @setting["novel_info_url"] or return nil
|
27
28
|
result = @@novel_info_parameters[@setting["name"]][@ncode] ||= {}
|
29
|
+
need_reload = false
|
28
30
|
unless result.empty?
|
29
31
|
# WEB UI でプロセスが常駐している間に小説情報(タイトルやあらすじ等)が
|
30
32
|
# 変更される場合があるので、一定時間過ぎたら再取得をする必要がある
|
31
33
|
if Time.now < result["last_load_time"] + REFRESH_INTERVAL
|
32
34
|
return result # まだ一定時間過ぎていないのでキャッシュを返す
|
33
35
|
end
|
36
|
+
need_reload = true
|
34
37
|
end
|
35
38
|
of = "t-nt-ga-s-gf-nu-gl-w"
|
36
39
|
request_output_parameters = of.split("-")
|
37
40
|
info_source = ""
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
|
42
|
+
if @setting["novel_info_url"] == @setting["toc_url"] && @toc_source && !need_reload
|
43
|
+
# 目次ページのHTML(オプション)。目次と小説情報が同じページにある場合、
|
44
|
+
# 同じページを二度取得するのは非効率なので、使い回す
|
45
|
+
info_source = @toc_source
|
46
|
+
else
|
47
|
+
cookie = @setting["cookie"] || ""
|
48
|
+
open_uri_options = make_open_uri_options("Cookie" => cookie, allow_redirections: :safe)
|
49
|
+
open(info_url, open_uri_options) do |fp|
|
50
|
+
info_source = Helper.restor_entity(Helper.pretreatment_source(fp.read, @setting["encoding"]))
|
51
|
+
raise Downloader::DownloaderNotFoundError if Downloader.detect_error_message(@setting, info_source)
|
52
|
+
end
|
43
53
|
end
|
54
|
+
|
44
55
|
@setting.multi_match(info_source, *request_output_parameters)
|
45
56
|
result["last_load_time"] = Time.now
|
46
57
|
result["title"] = @setting["title"]
|
data/lib/novelsetting.rb
CHANGED
@@ -354,12 +354,6 @@ class NovelSetting
|
|
354
354
|
value: 10,
|
355
355
|
help: "ここで設定した値が `enable_convert_page_break` に反映される"
|
356
356
|
},
|
357
|
-
{
|
358
|
-
name: "enable_dakuten_font",
|
359
|
-
type: :boolean,
|
360
|
-
value: true,
|
361
|
-
help: "濁点フォントを使用する。false の場合は縦中横による擬似表現を使用する"
|
362
|
-
},
|
363
357
|
{
|
364
358
|
name: "enable_display_end_of_book",
|
365
359
|
type: :boolean,
|
data/lib/version.rb
CHANGED
data/lib/web/appserver.rb
CHANGED
@@ -6,10 +6,8 @@
|
|
6
6
|
require "socket"
|
7
7
|
require "sinatra/base"
|
8
8
|
require "sinatra/json"
|
9
|
-
if $
|
10
|
-
|
11
|
-
require "pry"
|
12
|
-
end
|
9
|
+
require "sinatra/reloader" if $development
|
10
|
+
require "better_errors" if $debug
|
13
11
|
require "tilt/erubis"
|
14
12
|
require "tilt/haml"
|
15
13
|
require "tilt/sass"
|
@@ -25,7 +23,7 @@ module Narou::ServerHelpers
|
|
25
23
|
# タグをHTMLで装飾する
|
26
24
|
#
|
27
25
|
def decorate_tags(tags)
|
28
|
-
tags.map do |tag|
|
26
|
+
tags.sort.map do |tag|
|
29
27
|
%!<span class="tag label label-#{Command::Tag.get_color(tag)}" data-tag="#{escape_html(tag)}">#{escape_html(tag)}</span>!
|
30
28
|
end.join(" ")
|
31
29
|
end
|
@@ -103,12 +101,20 @@ module Narou::ServerHelpers
|
|
103
101
|
value
|
104
102
|
end
|
105
103
|
end
|
104
|
+
|
105
|
+
def notepad_text_path
|
106
|
+
File.join(Narou.get_local_setting_dir, "notepad.txt")
|
107
|
+
end
|
106
108
|
end
|
107
109
|
|
108
110
|
class Narou::AppServer < Sinatra::Base
|
109
|
-
register Sinatra::Reloader if $
|
111
|
+
register Sinatra::Reloader if $development
|
110
112
|
helpers Narou::ServerHelpers
|
111
113
|
|
114
|
+
@@request_reboot = false
|
115
|
+
@@already_update_system = false
|
116
|
+
@@gem_update_last_log = ""
|
117
|
+
|
112
118
|
configure do
|
113
119
|
set :app_file, __FILE__
|
114
120
|
set :erb, trim: "-"
|
@@ -119,13 +125,31 @@ class Narou::AppServer < Sinatra::Base
|
|
119
125
|
Command::Version.create_version_string
|
120
126
|
end
|
121
127
|
|
122
|
-
set :environment, :production unless $
|
128
|
+
set :environment, :production unless $development
|
129
|
+
set :server, :webrick
|
130
|
+
|
131
|
+
if $debug
|
132
|
+
use BetterErrors::Middleware
|
133
|
+
BetterErrors.application_root = Narou.get_script_dir
|
134
|
+
end
|
123
135
|
end
|
124
136
|
|
125
137
|
def self.push_server=(server)
|
126
138
|
@@push_server = server
|
127
139
|
end
|
128
140
|
|
141
|
+
def self.push_server
|
142
|
+
@@push_server
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.request_reboot
|
146
|
+
@@request_reboot = true
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.request_reboot?
|
150
|
+
@@request_reboot
|
151
|
+
end
|
152
|
+
|
129
153
|
#
|
130
154
|
# サーバのアドレスを生成
|
131
155
|
#
|
@@ -173,6 +197,30 @@ class Narou::AppServer < Sinatra::Base
|
|
173
197
|
}.call
|
174
198
|
end
|
175
199
|
|
200
|
+
def initialize
|
201
|
+
super
|
202
|
+
puts_hello_messages
|
203
|
+
start_device_ejectable_event
|
204
|
+
end
|
205
|
+
|
206
|
+
def puts_hello_messages
|
207
|
+
puts "<white>Narou.rb version #{::Version}</white>".termcolor
|
208
|
+
end
|
209
|
+
|
210
|
+
def start_device_ejectable_event
|
211
|
+
return unless Device.support_eject?
|
212
|
+
Thread.new do
|
213
|
+
loop do
|
214
|
+
if @@push_server.connections.count > 0
|
215
|
+
device = Narou.get_device
|
216
|
+
@@push_server.send_all(:"device.ejectable" => device && device.ejectable?)
|
217
|
+
end
|
218
|
+
|
219
|
+
sleep 2
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
176
224
|
# ===================================================================
|
177
225
|
# ルーティング
|
178
226
|
# ===================================================================
|
@@ -291,7 +339,7 @@ class Narou::AppServer < Sinatra::Base
|
|
291
339
|
get "/about" do
|
292
340
|
@narourb_version = settings.version
|
293
341
|
@ruby_version = build_ruby_version
|
294
|
-
haml :
|
342
|
+
haml :_about, layout: false
|
295
343
|
end
|
296
344
|
|
297
345
|
post "/shutdown" do
|
@@ -299,6 +347,36 @@ class Narou::AppServer < Sinatra::Base
|
|
299
347
|
"シャットダウンしました。再起動するまで操作は出来ません"
|
300
348
|
end
|
301
349
|
|
350
|
+
post "/reboot" do
|
351
|
+
self.class.request_reboot
|
352
|
+
self.class.quit!
|
353
|
+
haml :_rebooting, layout: false
|
354
|
+
end
|
355
|
+
|
356
|
+
post "/update_system" do
|
357
|
+
Thread.new do
|
358
|
+
buffer = `gem update --no-document narou`
|
359
|
+
@@gem_update_last_log = buffer.strip!
|
360
|
+
if buffer =~ /Nothing to update\z/
|
361
|
+
@@push_server.send_all("server.update.nothing" => buffer)
|
362
|
+
elsif buffer.include?("Gems updated: narou")
|
363
|
+
@@already_update_system = true
|
364
|
+
@@push_server.send_all("server.update.success" => buffer)
|
365
|
+
else
|
366
|
+
@@push_server.send_all("server.update.failure" => buffer)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
post "/gem_update_last_log" do
|
372
|
+
content_type "text/plain"
|
373
|
+
@@gem_update_last_log
|
374
|
+
end
|
375
|
+
|
376
|
+
post "/check_already_update_system" do
|
377
|
+
json({ result: @@already_update_system })
|
378
|
+
end
|
379
|
+
|
302
380
|
before "/novels/:id/*" do
|
303
381
|
@id = params[:id]
|
304
382
|
not_found unless @id =~ /^\d+$/
|
@@ -376,12 +454,26 @@ class Narou::AppServer < Sinatra::Base
|
|
376
454
|
ext = device ? device.ebook_file_ext : ".epub"
|
377
455
|
path = Narou.get_ebook_file_path(@id, ext)
|
378
456
|
if File.exist?(path)
|
379
|
-
send_file(path, filename: File.basename(path))
|
457
|
+
send_file(path, filename: File.basename(path), type: "application/octet-stream")
|
380
458
|
else
|
381
459
|
not_found
|
382
460
|
end
|
383
461
|
end
|
384
462
|
|
463
|
+
get "/notepad" do
|
464
|
+
@title = "メモ帳"
|
465
|
+
haml :notepad
|
466
|
+
end
|
467
|
+
|
468
|
+
get "/edit_menu" do
|
469
|
+
@title = "個別メニューの編集"
|
470
|
+
haml :edit_menu
|
471
|
+
end
|
472
|
+
|
473
|
+
not_found do
|
474
|
+
"not found"
|
475
|
+
end
|
476
|
+
|
385
477
|
# -------------------------------------------------------------------------------
|
386
478
|
# API's
|
387
479
|
# -------------------------------------------------------------------------------
|
@@ -411,7 +503,7 @@ class Narou::AppServer < Sinatra::Base
|
|
411
503
|
tags.include?("end") ? "完結" : nil,
|
412
504
|
tags.include?("404") ? "削除" : nil,
|
413
505
|
].compact.join(", "),
|
414
|
-
download: %!<a href="/novels/#{id}/download" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-
|
506
|
+
download: %!<a href="/novels/#{id}/download" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-download-alt"></span></a>!,
|
415
507
|
frozen: Narou.novel_frozen?(id),
|
416
508
|
new_arrivals_date: data["new_arrivals_date"].tap { |m| break m.to_i if m },
|
417
509
|
general_lastup: data["general_lastup"].tap { |m| break m.to_i if m }
|
@@ -529,7 +621,7 @@ class Narou::AppServer < Sinatra::Base
|
|
529
621
|
target = params["target"] or return ""
|
530
622
|
id = Downloader.get_id_by_target(target) or return ""
|
531
623
|
@list = Command::Diff.new.get_diff_list(id)
|
532
|
-
haml :
|
624
|
+
haml :_diff_list, layout: false
|
533
625
|
end
|
534
626
|
|
535
627
|
post "/api/diff_clean" do
|
@@ -564,9 +656,11 @@ class Narou::AppServer < Sinatra::Base
|
|
564
656
|
end
|
565
657
|
|
566
658
|
get "/api/tag_list" do
|
567
|
-
result =
|
659
|
+
result =
|
660
|
+
'<div><span class="tag label label-default" data-tag="">タグ検索を解除</span></div>' \
|
661
|
+
'<div class="text-muted" style="font-size:10px">Altキーを押しながらで除外検索</div>'
|
568
662
|
tagname_list = Command::Tag.get_tag_list.keys
|
569
|
-
tagname_list.each do |tagname|
|
663
|
+
tagname_list.sort.each do |tagname|
|
570
664
|
result << "<div>#{decorate_tags([tagname])} " \
|
571
665
|
"<span class='select-color-button' data-target-tag='#{h tagname}'>" \
|
572
666
|
"<span class='#{Command::Tag.get_color(tagname)}'>a</span></span></div>"
|
@@ -683,11 +777,32 @@ class Narou::AppServer < Sinatra::Base
|
|
683
777
|
end
|
684
778
|
|
685
779
|
get "/api/version/latest.json" do
|
686
|
-
|
687
|
-
|
780
|
+
json({ version: Narou.latest_version })
|
781
|
+
end
|
782
|
+
|
783
|
+
get "/api/notepad/read" do
|
784
|
+
content_type "text/plain"
|
785
|
+
if File.exist?(notepad_text_path)
|
786
|
+
File.read(notepad_text_path)
|
787
|
+
else
|
788
|
+
""
|
688
789
|
end
|
689
790
|
end
|
690
791
|
|
792
|
+
post "/api/notepad/save" do
|
793
|
+
File.write(notepad_text_path, params["text"])
|
794
|
+
@@push_server.send_all("notepad.change" => {
|
795
|
+
text: params["text"], object_id: params["object_id"]
|
796
|
+
})
|
797
|
+
""
|
798
|
+
end
|
799
|
+
|
800
|
+
post "/api/eject" do
|
801
|
+
device = Narou.get_device
|
802
|
+
device.eject if device
|
803
|
+
""
|
804
|
+
end
|
805
|
+
|
691
806
|
# -------------------------------------------------------------------------------
|
692
807
|
# 一部分に表示するためのHTMLを取得する(パーシャル)
|
693
808
|
# -------------------------------------------------------------------------------
|
@@ -741,5 +856,9 @@ class Narou::AppServer < Sinatra::Base
|
|
741
856
|
get "/widget/drag_and_drop" do
|
742
857
|
haml :"widget/drag_and_drop", layout: nil
|
743
858
|
end
|
859
|
+
|
860
|
+
get "/widget/notepad" do
|
861
|
+
haml :"widget/notepad", layout: nil
|
862
|
+
end
|
744
863
|
end
|
745
864
|
|