narou 2.6.1 → 2.7.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 +65 -0
- data/README.md +69 -22
- data/lib/command.rb +1 -0
- data/lib/command/alias.rb +2 -2
- data/lib/command/convert.rb +3 -3
- data/lib/command/csv.rb +108 -0
- data/lib/command/download.rb +13 -1
- data/lib/command/freeze.rb +1 -1
- data/lib/command/init.rb +5 -1
- data/lib/command/inspect.rb +1 -1
- data/lib/command/mail.rb +1 -1
- data/lib/command/send.rb +2 -2
- data/lib/command/setting.rb +17 -1
- data/lib/command/tag.rb +28 -9
- data/lib/command/update.rb +57 -30
- data/lib/commandbase.rb +3 -2
- data/lib/commandline.rb +2 -2
- data/lib/converterbase.rb +70 -7
- data/lib/database.rb +1 -1
- data/lib/device.rb +3 -0
- data/lib/device/ibooks.rb +2 -2
- data/lib/device/ibunko.rb +4 -0
- data/lib/diffviewer.rb +2 -2
- data/lib/downloader.rb +16 -9
- data/lib/helper.rb +53 -22
- data/lib/inventory.rb +6 -2
- data/lib/narou.rb +13 -6
- data/lib/novelconverter.rb +35 -13
- data/lib/novelsetting.rb +7 -1
- data/lib/version.rb +1 -1
- data/lib/web/appserver.rb +78 -8
- data/lib/web/public/resources/common.ui.js +0 -39
- data/lib/web/public/resources/dataTables.colVis.js +1 -1
- data/lib/web/public/resources/default-style.css +1 -1
- data/lib/web/public/resources/help/bookmarklet1.png +0 -0
- data/lib/web/public/resources/help/bookmarklet2.png +0 -0
- data/lib/web/public/resources/images/dl_button0.gif +0 -0
- data/lib/web/public/resources/images/dl_button1.gif +0 -0
- data/lib/web/public/resources/narou.library.js +268 -36
- data/lib/web/public/resources/narou.queue.js +51 -0
- data/lib/web/public/resources/narou.ui.js +156 -59
- data/lib/web/settingmessages.rb +2 -1
- data/lib/web/views/{js/widget.erb → bookmarklet/download.js.erb} +1 -1
- data/lib/web/views/bookmarklet/insert_button.js.erb +133 -0
- data/lib/web/views/help.haml +31 -14
- data/lib/web/views/index.haml +62 -0
- data/lib/web/views/layout.haml +8 -7
- data/lib/web/views/parts/csv_import.haml +68 -0
- data/lib/web/views/parts/download_form.haml +89 -0
- data/lib/web/views/settings.haml +8 -3
- data/lib/web/views/style.scss +200 -14
- data/lib/web/views/{widget.haml → widget/download.haml} +18 -4
- data/lib/web/views/widget/drag_and_drop.haml +97 -0
- data/lib/web/worker.rb +39 -1
- data/narou.gemspec +56 -56
- data/preset/custom_chuki_tag.txt +1 -1
- data/preset/doubledash.png +0 -0
- data/preset/singledash.png +0 -0
- data/preset/vertical_font.css +1 -1
- data/spec/convert_spec.rb +5 -1
- data/spec/data/convert_test/auto_join_line/correct_test_auto_join_line.txt +6 -0
- data/spec/data/convert_test/auto_join_line/test_auto_join_line.txt +8 -0
- data/spec/data/convert_test/double_dash_to_image/correct_test_double_dash_to_image.txt +14 -0
- data/spec/data/convert_test/double_dash_to_image/setting.ini +1 -0
- data/spec/data/convert_test/double_dash_to_image/test_double_dash_to_image.txt +12 -0
- data/spec/worker_spec.rb +21 -2
- metadata +97 -60
data/lib/web/settingmessages.rb
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
var url, div, iframe, btn_close;
|
33
33
|
|
34
34
|
url = '<%= "#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}" %>' +
|
35
|
-
"/widget
|
35
|
+
"/widget/download?from=" + location.hostname + "&target=" +
|
36
36
|
encodeURIComponent(location.href) + "&t=" + Date.now();
|
37
37
|
|
38
38
|
// IE の場合、iframe は親のドキュメントモードが汚染して動かない可能性があるので対処
|
@@ -0,0 +1,133 @@
|
|
1
|
+
<%# vim: set ft=javascript : -%>
|
2
|
+
(function() {
|
3
|
+
// オフライン表記を先に消しておく
|
4
|
+
var offline = document.getElementById("narourb-offline");
|
5
|
+
offline.parentNode.removeChild(offline);
|
6
|
+
|
7
|
+
// 対応小説投稿サイトに関する情報
|
8
|
+
var site_settings = {
|
9
|
+
<%- Downloader.load_settings.each.with_index do |setting, i| -%>
|
10
|
+
"<%= setting["domain"] %>": {
|
11
|
+
<%- case setting["domain"] -%>
|
12
|
+
<%- when "www.mai-net.net" -%>
|
13
|
+
add_tail: "&n=0&count=1",
|
14
|
+
<%- when "ncode.syosetu.com", "novel18.syosetu.com", "novel.syosetu.org" -%>
|
15
|
+
add_tail: "/",
|
16
|
+
<%- when "www.akatsuki-novels.com" -%>
|
17
|
+
add_tail: "",
|
18
|
+
<%- end -%>
|
19
|
+
url: '(<%= setting["url"].gsub(/\?<.+?>/, "?:").gsub("\\", "\\\\\\\\") %>)'
|
20
|
+
}
|
21
|
+
<%= i == Downloader.load_settings.length - 1 ? "" : "," %>
|
22
|
+
<%- end -%>
|
23
|
+
};
|
24
|
+
|
25
|
+
// 管理している小説のURL一覧
|
26
|
+
var manage_novel_urls = [
|
27
|
+
<%-# バイナリーサーチ用にソートしておく -%>
|
28
|
+
<%- Database.instance.get_object.values.sort_by { |v| v["toc_url"] }.each do |data| -%>
|
29
|
+
'<%= data["toc_url"] %>',
|
30
|
+
<%- end -%>
|
31
|
+
];
|
32
|
+
|
33
|
+
/*
|
34
|
+
* バイナリーサーチ
|
35
|
+
* 見つかったら見つかった位置のインデックス
|
36
|
+
* 見つからなかったら-1を返す
|
37
|
+
* array はソート済みである必要がある
|
38
|
+
*/
|
39
|
+
var binarySearch = function(array, target) {
|
40
|
+
if (array.length === 0) return -1;
|
41
|
+
var left = 0, right = manage_novel_urls.length - 1;
|
42
|
+
while (left < right) {
|
43
|
+
var center = (left + right) / 2 | 0;
|
44
|
+
if (array[center] < target)
|
45
|
+
left = center + 1;
|
46
|
+
else if (array[center] > target)
|
47
|
+
right = center - 1;
|
48
|
+
else
|
49
|
+
return center;
|
50
|
+
}
|
51
|
+
if (array[left] === target) return left;
|
52
|
+
return -1;
|
53
|
+
};
|
54
|
+
|
55
|
+
/*
|
56
|
+
* 管理している小説のURLリストから検索
|
57
|
+
*/
|
58
|
+
var searchRegisterURL = function(target) {
|
59
|
+
var result = binarySearch(manage_novel_urls, target);
|
60
|
+
if (result === -1)
|
61
|
+
return null;
|
62
|
+
return manage_novel_urls[result];
|
63
|
+
};
|
64
|
+
|
65
|
+
/*
|
66
|
+
* IE10未満のために自力でフォームエンコード
|
67
|
+
*/
|
68
|
+
var encodeHTMLForm = function(data) {
|
69
|
+
var params = [];
|
70
|
+
for (var name in data) {
|
71
|
+
var value = data[name];
|
72
|
+
var param = encodeURIComponent(name) + '=' + encodeURIComponent(value);
|
73
|
+
params.push(param);
|
74
|
+
}
|
75
|
+
return params.join("&").replace(/%20/g, "+");
|
76
|
+
};
|
77
|
+
|
78
|
+
var server_origin = '<%= "#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}" %>';
|
79
|
+
|
80
|
+
var createButtonElement = function(href) {
|
81
|
+
var span = document.createElement("span");
|
82
|
+
var img = document.createElement("img");
|
83
|
+
var space = span.cloneNode();
|
84
|
+
span.appendChild(img);
|
85
|
+
span.appendChild(space);
|
86
|
+
img.style.height = "1.15em";
|
87
|
+
img.style.cursor = "pointer";
|
88
|
+
space.textContent = " ";
|
89
|
+
|
90
|
+
var dl_listener = function(e) {
|
91
|
+
var url = server_origin + "/api/download";
|
92
|
+
try {
|
93
|
+
var xhr = new XMLHttpRequest;
|
94
|
+
xhr.open("POST", url);
|
95
|
+
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
96
|
+
xhr.send(encodeHTMLForm({ targets: href }));
|
97
|
+
img.src = server_origin + "/resources/images/dl_button1.gif";
|
98
|
+
}
|
99
|
+
catch(e) {
|
100
|
+
// IE7モード(なろうのトップページをIEで見た場合)の時は xhr.open の時点で
|
101
|
+
// 例外が発生してWEBUIサーバまでデータが飛ばないので、画像のURLにパラメータ
|
102
|
+
// 仕込んでDLの通知を行う
|
103
|
+
img.src = server_origin + "/api/download4ie?target=" + encodeURIComponent(href);
|
104
|
+
}
|
105
|
+
// 登録したらもう押せないようにイベントを削除
|
106
|
+
img.onclick = null;
|
107
|
+
img.style.cursor = "default";
|
108
|
+
return false;
|
109
|
+
};
|
110
|
+
|
111
|
+
if (searchRegisterURL(href)) {
|
112
|
+
// すでにダンロード済みなら最初からグレー画像
|
113
|
+
img.src = server_origin + "/resources/images/dl_button1.gif";
|
114
|
+
img.style.cursor = "default";
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
img.src = server_origin + "/resources/images/dl_button0.gif";
|
118
|
+
img.onclick = dl_listener;
|
119
|
+
}
|
120
|
+
return span;
|
121
|
+
};
|
122
|
+
|
123
|
+
var links = document.getElementsByTagName("a");
|
124
|
+
for (var i = 0; i < links.length; i++) {
|
125
|
+
//for (var i = 0; i < 3; i++) {
|
126
|
+
var link = links[i];
|
127
|
+
var setting = site_settings[link.hostname];
|
128
|
+
if (setting && link.href.match(setting.url)) {
|
129
|
+
var download_button = createButtonElement(RegExp.$1 + setting.add_tail);
|
130
|
+
link.parentNode.insertBefore(download_button, link);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
})();
|
data/lib/web/views/help.haml
CHANGED
@@ -22,18 +22,20 @@
|
|
22
22
|
},1000);
|
23
23
|
|
24
24
|
u='#{request.scheme}://#{env["SERVER_NAME"]}:#{env["SERVER_PORT"]}'+
|
25
|
-
'/js/widget.js?mode
|
25
|
+
'/js/widget.js?mode=%MODE%&t='+Date.now();
|
26
26
|
e=d.createElement('script');
|
27
27
|
e.charset='utf-8';
|
28
28
|
e.src=u;
|
29
29
|
d.body.appendChild(e)
|
30
30
|
};
|
31
31
|
|
32
|
-
function createBookmarkletStrings(proc) {
|
33
|
-
|
32
|
+
function createBookmarkletStrings(proc, mode) {
|
33
|
+
var proc_string = proc.toString().replace("%MODE%", mode);
|
34
|
+
return ("javascript:(" + proc_string + ")(document)").replace(/ {2,}|\n/g, "");
|
34
35
|
}
|
35
36
|
|
36
|
-
$("#bookmarklet").attr("href", createBookmarkletStrings(bookmarklet));
|
37
|
+
$("#bookmarklet-download").attr("href", createBookmarkletStrings(bookmarklet, "download"));
|
38
|
+
$("#bookmarklet-insert-button").attr("href", createBookmarkletStrings(bookmarklet, "insert_button"));
|
37
39
|
});
|
38
40
|
|
39
41
|
.navbar.navbar-default.navbar-fixed-top(role="navigation")
|
@@ -58,16 +60,28 @@
|
|
58
60
|
%span#queue 0
|
59
61
|
#help-container.container.theme-showcase(role="main")
|
60
62
|
%h2 ブックマークレット
|
61
|
-
%
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
%
|
63
|
+
%h3 小説ページから直接ダウンロード
|
64
|
+
%div
|
65
|
+
%img#ss-bookmarklet1(src="/resources/help/bookmarklet1.png" class="img-thumbnail")
|
66
|
+
%p 小説掲載サイトを表示したまま直接ダウンロード出来るブックマークレットです。
|
67
|
+
%p 下記のリンクをブックマークに登録して、ダウンロードしたい小説のページで実行して下さい。(WEB UIサーバ起動中に限ります)
|
68
|
+
%p ブックマークバーにドラッグ&ドロップしたり、右クリックからブックマークにいれると簡単です。
|
69
|
+
%p
|
70
|
+
%span.glyphicon.glyphicon-bookmark
|
66
71
|
%big
|
67
|
-
%
|
72
|
+
%a#bookmarklet-download(onclick="return false")
|
73
|
+
%u Narou.rbでダウンロード
|
68
74
|
|
69
|
-
%
|
70
|
-
|
75
|
+
%h3 ページ内の小説へのリンクにダウンロードボタンを付ける
|
76
|
+
%div
|
77
|
+
%img#ss-bookmarklet2(src="/resources/help/bookmarklet2.png" class="img-thumbnail")
|
78
|
+
%p 小説投稿サイト内の、各小説へのリンクの横にダウンロード用のボタンを埋め込みます。
|
79
|
+
%p ランキングページや一覧ページなどで実行するとダウンロードが一発で出来るようになったり、どれがダウンロード済みなのかが一目瞭然になります。
|
80
|
+
%p
|
81
|
+
%span.glyphicon.glyphicon-bookmark
|
82
|
+
%big
|
83
|
+
%a#bookmarklet-insert-button(onclick="return false")
|
84
|
+
%u DLボタン設置(Narou.rb)
|
71
85
|
|
72
86
|
%hr
|
73
87
|
|
@@ -110,11 +124,14 @@
|
|
110
124
|
|
111
125
|
%h4 シングル選択モード
|
112
126
|
%div
|
113
|
-
%p
|
127
|
+
%p 小説一覧をクリックしてひとつずつ選択するモードです。小説リストの文字情報を選択してコピー出来るのはこのモードだけです。
|
114
128
|
|
115
129
|
%h4 範囲選択モード
|
116
130
|
%div
|
117
131
|
%img#ss-rect-select(src="/resources/help/rect_select.png" class="img-thumbnail")
|
118
|
-
%p
|
132
|
+
%p 一度に複数の小説を選択する場合に便利なモードです。始点をクリックしたあと終点をクリックして範囲を確定するか、始点から終点までをドラッグすることで範囲を決めることが出来ます。範囲の始点と終点をクリック(タップ)のみで決定できるため、トラックパッドでの操作がし易いモードとなります。
|
119
133
|
%p 範囲が確定された際にメニューが表示されるので、選択や解除等を選択します。反転は現在の選択状態を逆転させます。
|
120
134
|
|
135
|
+
%h4 ハイブリッド選択モード
|
136
|
+
%div
|
137
|
+
%p クリックで選択とドラッグで範囲選択を同時に行える、シングル選択モードと範囲選択モードの特徴を併せ持ったモードです。
|
data/lib/web/views/index.haml
CHANGED
@@ -63,6 +63,12 @@
|
|
63
63
|
%span.active-ok.glyphicon.glyphicon-ok
|
64
64
|
範囲選択モード
|
65
65
|
%span.shortcut R
|
66
|
+
%li#action-select-mode-hybrid
|
67
|
+
%a(href="#")
|
68
|
+
%span
|
69
|
+
%span.active-ok.glyphicon.glyphicon-ok
|
70
|
+
ハイブリッド選択モード
|
71
|
+
%span.shortcut H
|
66
72
|
%li.dropdown
|
67
73
|
%a.dropdown-toggle(data-toggle="dropdown" href="#")
|
68
74
|
タグ
|
@@ -75,6 +81,24 @@
|
|
75
81
|
%a(href="#")
|
76
82
|
%span
|
77
83
|
選択した小説のタグを編集
|
84
|
+
%li.dropdown
|
85
|
+
%a.dropdown-toggle(data-toggle="dropdown" href="#")
|
86
|
+
ツール
|
87
|
+
%span.caret
|
88
|
+
%ul.dropdown-menu(role="menu")
|
89
|
+
%li#action-tool-open-dnd-window
|
90
|
+
%a(href="#")
|
91
|
+
%span
|
92
|
+
D&Dウィンドウを開く
|
93
|
+
%li.divider
|
94
|
+
%li#action-tool-csv-download
|
95
|
+
%a(href="#")
|
96
|
+
%span
|
97
|
+
CSV形式でリストをダウンロード
|
98
|
+
%li#action-tool-csv-import
|
99
|
+
%a(href="#")
|
100
|
+
%span
|
101
|
+
CSVファイルからインポート
|
78
102
|
%ul.nav.navbar-nav.navbar-right
|
79
103
|
%li.dropdown
|
80
104
|
%a.dropdown-toggle(data-toggle="dropdown" href="#")
|
@@ -131,6 +155,7 @@
|
|
131
155
|
#console-container
|
132
156
|
#console.console
|
133
157
|
#console-buttons.console-buttons
|
158
|
+
%span.queue-cancel.glyphicon.glyphicon-remove-circle(data-toggle="tooltip" title="処理を中断")
|
134
159
|
%span.console-trash.glyphicon.glyphicon-trash(data-toggle="tooltip" title="ログと履歴を削除")
|
135
160
|
%span.console-expand
|
136
161
|
%span.glyphicon.glyphicon-resize-full(data-toggle="tooltip" title="拡大")
|
@@ -161,6 +186,13 @@
|
|
161
186
|
%a#button-update-force(href="#") 凍結済みでも更新
|
162
187
|
.btn-group
|
163
188
|
%button#button-send.btn.btn-warning(type="button") Send
|
189
|
+
- if Inventory.load("local_setting")["hotentry"]
|
190
|
+
%button.btn.btn-warning.dropdown-toggle(type="button" data-toggle="dropdown")
|
191
|
+
%span.caret
|
192
|
+
%span.sr-only Toggle Dropdown
|
193
|
+
%ul.dropdown-menu(role="menu")
|
194
|
+
%li
|
195
|
+
%a#button-send-hotentry(href="#") hotentry を送信
|
164
196
|
.btn-group
|
165
197
|
%button.btn.btn-info.dropdown-toggle.enable-selected(type="button" data-toggle="dropdown")
|
166
198
|
Freeze
|
@@ -251,3 +283,33 @@
|
|
251
283
|
.modal-footer
|
252
284
|
%button.btn.btn-primary(type="button" data-dismiss="modal") 閉じる
|
253
285
|
|
286
|
+
%ul#select-color-menu.dropdown-menu(role="menu")
|
287
|
+
%li
|
288
|
+
%a#select-color-menu-green(href="#")
|
289
|
+
%big
|
290
|
+
%span.label.label-green.label-fixed-width Green
|
291
|
+
%li
|
292
|
+
%a#select-color-menu-yellow(href="#")
|
293
|
+
%big
|
294
|
+
%span.label.label-yellow.label-fixed-width Yellow
|
295
|
+
%li
|
296
|
+
%a#select-color-menu-blue(href="#")
|
297
|
+
%big
|
298
|
+
%span.label.label-blue.label-fixed-width Blue
|
299
|
+
%li
|
300
|
+
%a#select-color-menu-magenta(href="#")
|
301
|
+
%big
|
302
|
+
%span.label.label-magenta.label-fixed-width Magenta
|
303
|
+
%li
|
304
|
+
%a#select-color-menu-cyan(href="#")
|
305
|
+
%big
|
306
|
+
%span.label.label-cyan.label-fixed-width Cyan
|
307
|
+
%li
|
308
|
+
%a#select-color-menu-red(href="#")
|
309
|
+
%big
|
310
|
+
%span.label.label-red.label-fixed-width Red
|
311
|
+
%li
|
312
|
+
%a#select-color-menu-white(href="#")
|
313
|
+
%big
|
314
|
+
%span.label.label-white.label-fixed-width White
|
315
|
+
|
data/lib/web/views/layout.haml
CHANGED
@@ -12,15 +12,15 @@
|
|
12
12
|
%link{:href => "/theme/#{@bootstrap_theme}/bootstrap.min.css", :rel => "stylesheet"}/
|
13
13
|
%link{:href => "/theme/#{@bootstrap_theme}/style.css", :rel => "stylesheet"}/
|
14
14
|
- else
|
15
|
-
%link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.
|
16
|
-
%link{:href => "/resources/default-style.css", :rel => "stylesheet"}/
|
15
|
+
%link{:href => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", :rel => "stylesheet"}/
|
16
|
+
%link{:href => "/resources/default-style.css?_=#{Version}", :rel => "stylesheet"}/
|
17
17
|
%link{:href => "//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.css", :rel => "stylesheet"}/
|
18
18
|
%link{:href => "//cdn.datatables.net/colreorder/1.1.2/css/dataTables.colReorder.css", :rel => "stylesheet"}/
|
19
19
|
%link{:href => "//cdn.datatables.net/colvis/1.1.1/css/dataTables.colVis.css", :rel => "stylesheet"}/
|
20
20
|
%link{:href => "//cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.5/css/bootstrap-select.min.css", :rel => "stylesheet"}/
|
21
21
|
%link{:href => "/resources/perfect-scrollbar.min.css", :rel => "stylesheet"}/
|
22
22
|
%link{:href => "/resources/toggle-switch.css", :rel => "stylesheet"}/
|
23
|
-
%link{:href => "/style.css", :rel => "stylesheet"}/
|
23
|
+
%link{:href => "/style.css?_=#{Version}", :rel => "stylesheet"}/
|
24
24
|
/ HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
|
25
25
|
/[if lt IE 9]
|
26
26
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
@@ -37,7 +37,7 @@
|
|
37
37
|
&= message
|
38
38
|
!= yield
|
39
39
|
%script{:src => "//code.jquery.com/jquery-1.11.1.min.js"}
|
40
|
-
%script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.
|
40
|
+
%script{:src => "//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"}
|
41
41
|
%script{:src => "//cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"}
|
42
42
|
%script{:src => "//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.js"}
|
43
43
|
%script{:src => "//cdn.datatables.net/colreorder/1.1.2/js/dataTables.colReorder.min.js"}
|
@@ -49,8 +49,9 @@
|
|
49
49
|
%script{:src => "/resources/jquery.outerclick.js"}
|
50
50
|
%script{:src => "/resources/jquery.slidenavbar.js"}
|
51
51
|
%script{:src => "/resources/jquery.moveto.js"}
|
52
|
-
%script{:src => "/resources/narou.library.js"}
|
53
|
-
%script{:src => "/resources/
|
52
|
+
%script{:src => "/resources/narou.library.js?_=#{Version}"}
|
53
|
+
%script{:src => "/resources/narou.queue.js?_=#{Version}"}
|
54
|
+
%script{:src => "/resources/common.ui.js?_=#{Version}"}
|
54
55
|
:javascript
|
55
56
|
$(document).ready(function($) {
|
56
57
|
slideNavbar = $(".navbar-collapse").slideNavbar();
|
@@ -59,5 +60,5 @@
|
|
59
60
|
});
|
60
61
|
});
|
61
62
|
- if env["PATH_INFO"] == "/"
|
62
|
-
%script{:src => "/resources/narou.ui.js"}
|
63
|
+
%script{:src => "/resources/narou.ui.js?_=#{Version}"}
|
63
64
|
|
@@ -0,0 +1,68 @@
|
|
1
|
+
:javascript
|
2
|
+
var $here = $("#csv-drop-here");
|
3
|
+
var form_data = new FormData;
|
4
|
+
|
5
|
+
var appendFiles = function(files) {
|
6
|
+
$.each(files, function(i, file) {
|
7
|
+
form_data.append("files[]", file);
|
8
|
+
$("#csv-file-list").append($("<div>" + file.name + "</div>"));
|
9
|
+
});
|
10
|
+
};
|
11
|
+
|
12
|
+
$("#csv-drop-cover").hide();
|
13
|
+
$here.on("dragenter", function(e) {
|
14
|
+
$("#csv-drop-cover").show();
|
15
|
+
});
|
16
|
+
|
17
|
+
$("#csv-drop-cover")
|
18
|
+
.on("dragenter", function(e) {
|
19
|
+
$here.addClass("dragover");
|
20
|
+
})
|
21
|
+
.on("dragover", function(e) {
|
22
|
+
e.preventDefault();
|
23
|
+
e.dataTransfer.dropEffect = "copy";
|
24
|
+
return false;
|
25
|
+
})
|
26
|
+
.on("dragleave", function(e) {
|
27
|
+
$here.removeClass("dragover");
|
28
|
+
$(this).hide();
|
29
|
+
})
|
30
|
+
.on("drop", function(e) {
|
31
|
+
e.preventDefault();
|
32
|
+
$here.removeClass("dragover");
|
33
|
+
$(this).hide();
|
34
|
+
appendFiles(e.dataTransfer.files);
|
35
|
+
});
|
36
|
+
|
37
|
+
$("#csv-select-file-button").on("click", function(e) {
|
38
|
+
$("#csv-select-file-input").click();
|
39
|
+
});
|
40
|
+
|
41
|
+
$("#csv-select-file-input").on("change", function(e) {
|
42
|
+
appendFiles(this.files);
|
43
|
+
});
|
44
|
+
|
45
|
+
$("#csv-import-files").on("click", function(e) {
|
46
|
+
$.ajax({
|
47
|
+
url: "/api/csv/import",
|
48
|
+
type: "post",
|
49
|
+
data: form_data,
|
50
|
+
processData: false,
|
51
|
+
contentType: false
|
52
|
+
});
|
53
|
+
});
|
54
|
+
|
55
|
+
#csv-drop-here
|
56
|
+
.inner
|
57
|
+
%div
|
58
|
+
%div ここにCSVファイルをドラッグ&ドロップ
|
59
|
+
%div.else もしくは…
|
60
|
+
%div
|
61
|
+
%input#csv-select-file-input.hidden(type="file" multiple="multiple")
|
62
|
+
%button#csv-select-file-button.btn.btn-warning.btn-xs
|
63
|
+
ファイルを選択
|
64
|
+
#csv-drop-cover.drop-cover(effectAllowed="all")
|
65
|
+
#csv-file-list
|
66
|
+
|
67
|
+
-# インポートダイアログの「インポート」ボタンから処理を移譲されてくる
|
68
|
+
#csv-import-files.hidden
|
@@ -0,0 +1,89 @@
|
|
1
|
+
:javascript
|
2
|
+
var $here = $("#download-link-drop-here");
|
3
|
+
var form_data = new FormData;
|
4
|
+
var dnd = new Narou.DragDrop;
|
5
|
+
var action = new Narou.Action(null);
|
6
|
+
|
7
|
+
var appendLinks = function(event) {
|
8
|
+
dnd.getLinkText(event, function(link) {
|
9
|
+
if (dnd.isValidNovelUrl(link)) {
|
10
|
+
action.download(link);
|
11
|
+
}
|
12
|
+
else {
|
13
|
+
$here.addClass("error").delay(1500).queue(function() {
|
14
|
+
$(this).removeClass("error").dequeue();
|
15
|
+
});
|
16
|
+
}
|
17
|
+
});
|
18
|
+
};
|
19
|
+
|
20
|
+
$("#download-link-drop-cover")
|
21
|
+
.on("dragenter", function(e) {
|
22
|
+
$here.addClass("dragover");
|
23
|
+
})
|
24
|
+
.on("dragover", function(e) {
|
25
|
+
e.preventDefault();
|
26
|
+
e.dataTransfer.dropEffect = "copy";
|
27
|
+
return false;
|
28
|
+
})
|
29
|
+
.on("dragleave", function(e) {
|
30
|
+
$here.removeClass("dragover");
|
31
|
+
})
|
32
|
+
.on("drop", function(e) {
|
33
|
+
e.preventDefault();
|
34
|
+
$here.removeClass("dragover");
|
35
|
+
appendLinks(e);
|
36
|
+
});
|
37
|
+
|
38
|
+
$("#download-link-submit").on("click", function(e) {
|
39
|
+
var targets = $("#download-input").val();
|
40
|
+
$.post("/api/download", { targets: targets });
|
41
|
+
});
|
42
|
+
|
43
|
+
:css
|
44
|
+
#download-link-drop-area {
|
45
|
+
margin-top: 15px;
|
46
|
+
margin-bottom: 15px;
|
47
|
+
}
|
48
|
+
#download-link-drop-here {
|
49
|
+
position: relative;
|
50
|
+
width: 100%;
|
51
|
+
height: 100px;
|
52
|
+
border: 4px dashed #ddd;
|
53
|
+
color: lightgray;
|
54
|
+
transition: border-color 0.4s ease, background-color 0.4s ease, color 0.4s ease;
|
55
|
+
}
|
56
|
+
#download-link-drop-here.dragover {
|
57
|
+
border-color: #ada;
|
58
|
+
background-color: #efe;
|
59
|
+
color: #5cb85c;
|
60
|
+
}
|
61
|
+
#download-link-drop-here.error {
|
62
|
+
border-color: #ebccd1;
|
63
|
+
background-color: #fff5f5;
|
64
|
+
color: #ebccc1;
|
65
|
+
}
|
66
|
+
#download-link-drop-here .inner {
|
67
|
+
position: absolute;
|
68
|
+
display: table;
|
69
|
+
width: 100%;
|
70
|
+
height: 100%;
|
71
|
+
text-align: center;
|
72
|
+
font-size: 1.2em;
|
73
|
+
font-weight: bold;
|
74
|
+
}
|
75
|
+
#download-link-drop-here .inner > div {
|
76
|
+
display: table-cell;
|
77
|
+
vertical-align: middle;
|
78
|
+
}
|
79
|
+
|
80
|
+
-# Downloadダイアログの「ダウンロード」ボタンから処理を移譲されてくる
|
81
|
+
#download-link-submit.hidden
|
82
|
+
|
83
|
+
%textarea#download-input.form-control(rows="4" placeholder="小説のURLを入力(複数入力する場合は半角スペースか改行で区切る)")
|
84
|
+
|
85
|
+
#download-link-drop-area
|
86
|
+
#download-link-drop-here
|
87
|
+
.inner
|
88
|
+
%div ここにリンクかショートカットファイルをドラッグ
|
89
|
+
#download-link-drop-cover.drop-cover(effectAllowed="all")
|