kindai 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +85 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/bin/kindai.rb +15 -0
- data/kindai.gemspec +102 -0
- data/kindai.rb +17 -0
- data/lib/kindai/book.rb +110 -0
- data/lib/kindai/book_downloader.rb +62 -0
- data/lib/kindai/cli.rb +88 -0
- data/lib/kindai/interface.rb +30 -0
- data/lib/kindai/publisher.rb +157 -0
- data/lib/kindai/searcher.rb +52 -0
- data/lib/kindai/spread.rb +39 -0
- data/lib/kindai/spread_downloader.rb +65 -0
- data/lib/kindai/util.rb +239 -0
- data/lib/kindai.rb +24 -0
- data/publish.rb +17 -0
- data/spec/book_downloader_spec.rb +46 -0
- data/spec/book_spec.rb +39 -0
- data/spec/searcher_spec.rb +42 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/spread_downloader_spec.rb +44 -0
- data/spec/spread_spec.rb +26 -0
- metadata +195 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
nokogiri (1.4.4)
|
11
|
+
rake (0.8.7)
|
12
|
+
rcov (0.9.9)
|
13
|
+
rmagick (2.13.1)
|
14
|
+
rspec (2.3.0)
|
15
|
+
rspec-core (~> 2.3.0)
|
16
|
+
rspec-expectations (~> 2.3.0)
|
17
|
+
rspec-mocks (~> 2.3.0)
|
18
|
+
rspec-core (2.3.1)
|
19
|
+
rspec-expectations (2.3.0)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
rspec-mocks (2.3.0)
|
22
|
+
zipruby (0.3.6)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
bundler (~> 1.0.0)
|
29
|
+
jeweler (~> 1.5.2)
|
30
|
+
nokogiri
|
31
|
+
rcov
|
32
|
+
rmagick
|
33
|
+
rspec (~> 2.3.0)
|
34
|
+
zipruby
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 hitode909
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
= kindai.rb
|
2
|
+
|
3
|
+
== 概要
|
4
|
+
|
5
|
+
近代デジタルライブラリーから画像をダウンロードします.
|
6
|
+
|
7
|
+
== インストール
|
8
|
+
|
9
|
+
RubyGemsからインストールできます.
|
10
|
+
|
11
|
+
gem install kindai
|
12
|
+
|
13
|
+
== 使い方
|
14
|
+
|
15
|
+
起動時の引数に,ダウンロードしたい本の URL を指定します.スペース区切りで複数指定できます.
|
16
|
+
|
17
|
+
kindai.rb http://kindai.ndl.go.jp/info:ndljp/pid/922693
|
18
|
+
|
19
|
+
URL の代わりに検索ワードを指定すると,ヒットした本をまとめてダウンロードします.AND検索もできます.
|
20
|
+
|
21
|
+
kindai.rb 調理
|
22
|
+
kindai.rb "松茸 調理"
|
23
|
+
|
24
|
+
--output オプションで,保存先を指定できます.指定したディレクトリの下に,書名のディレクトリができます.
|
25
|
+
|
26
|
+
kindai.rb http://kindai.ndl.go.jp/info:ndljp/pid/922693 --output ~/Documents/
|
27
|
+
|
28
|
+
--retry オプションで,ダウンロードのリトライ回数を指定できます.標準では3回です.
|
29
|
+
|
30
|
+
kindai.rb http://kindai.ndl.go.jp/info:ndljp/pid/922693 --retry 10
|
31
|
+
|
32
|
+
|
33
|
+
== 本の加工(自動)
|
34
|
+
|
35
|
+
ダウンロードされた本は読みやすいように加工され, iPhone 用と Kindle 用のファイルが作られます.
|
36
|
+
以下のようなファイル構成になります.
|
37
|
+
|
38
|
+
正義熱血社 - 正義の叫
|
39
|
+
├── original
|
40
|
+
│ ├── 001.jpg
|
41
|
+
│ ├── 002.jpg
|
42
|
+
│ ├── 003.jpg
|
43
|
+
(中略)
|
44
|
+
│ └── 020.jpg
|
45
|
+
├── trim
|
46
|
+
│ ├── 001.jpg
|
47
|
+
│ ├── 002.jpg
|
48
|
+
│ ├── 003.jpg
|
49
|
+
(中略)
|
50
|
+
│ └── 020.jpg
|
51
|
+
├── 正義熱血社 - 正義の叫_iphone.zip
|
52
|
+
└── 正義熱血社 - 正義の叫_kindle.zip
|
53
|
+
|
54
|
+
* original/以下には加工前の画像が入ります.
|
55
|
+
* trim/以下にはトリミングして余白を取り除いた画像が入ります.パソコンで読むのに適しています.
|
56
|
+
* _iphone.zipは,iPhoneの画面サイズ(1280x960)にリサイズされた見開き画像のzipファイルです.Comic Glassで読むのに適しています.
|
57
|
+
* _kindle.zipは,Kindle3の画面サイズ(600x800)にリサイズされ,1ページずつに裁断された画像のzipファイルです.
|
58
|
+
|
59
|
+
== 本の加工(手動)
|
60
|
+
|
61
|
+
トリミング位置は自動的に決められますが,ダウンロード後に,ずれていることが分かった場合は,publish.rbを使ってトリミング位置を指定できます.
|
62
|
+
|
63
|
+
publish.rb --position 2905x2510+270+190 "~/Documents/正義熱血社 - 正義の叫"
|
64
|
+
|
65
|
+
幅2905ピクセル,高さ2510ピクセル,左の余白270ピクセル,上の余白190ピクセルでトリミングされます.
|
66
|
+
|
67
|
+
== 動作環境
|
68
|
+
|
69
|
+
* Ruby が必要です.
|
70
|
+
* ImageMagick が必要です.
|
71
|
+
* Nokogiri と RMagick が必要です,RubyGems でインストールしてください.
|
72
|
+
* Gemfile を書いてあるので,bundler が入ってる環境では bundle install コマンドを実行するだけで必要な Gem が入ります.
|
73
|
+
|
74
|
+
== その他
|
75
|
+
|
76
|
+
国立国会図書館デジタルアーカイブポータル(PORTA)外部提供インタフェースを利用しています.
|
77
|
+
|
78
|
+
Wiki: 外部提供インタフェースについて
|
79
|
+
|
80
|
+
http://porta.ndl.go.jp/wiki/Wiki.jsp?page=%E5%A4%96%E9%83%A8%E6%8F%90%E4%BE%9B%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
|
81
|
+
|
82
|
+
== Copyright
|
83
|
+
|
84
|
+
Copyright (c) 2011 hitode909. See LICENSE.txt for
|
85
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
gem.name = "kindai"
|
15
|
+
gem.homepage = "http://github.com/hitode909/kindairb"
|
16
|
+
gem.license = "MIT"
|
17
|
+
gem.summary = %Q{kindai digital library downloader}
|
18
|
+
gem.description = %Q{kindai.rb is kindai digital library downloader.}
|
19
|
+
gem.email = "hitode909@gmail.com"
|
20
|
+
gem.authors = ["hitode909"]
|
21
|
+
gem.add_dependency("nokogiri", ">= 1.4.0")
|
22
|
+
gem.add_dependency("zipruby", ">= 0.3.6")
|
23
|
+
gem.add_dependency("rmagick", ">= 2.13.1")
|
24
|
+
|
25
|
+
gem.executables = ["kindai.rb"]
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "kindai #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/bin/kindai.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
self_file =
|
5
|
+
if File.symlink?(__FILE__)
|
6
|
+
require 'pathname'
|
7
|
+
Pathname.new(__FILE__).realpath
|
8
|
+
else
|
9
|
+
__FILE__
|
10
|
+
end
|
11
|
+
$:.unshift(File.dirname(self_file) + "/../lib")
|
12
|
+
|
13
|
+
require 'kindai'
|
14
|
+
|
15
|
+
Kindai::CLI.execute(STDOUT, ARGV)
|
data/kindai.gemspec
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{kindai}
|
8
|
+
s.version = "1.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["hitode909"]
|
12
|
+
s.date = %q{2011-02-11}
|
13
|
+
s.default_executable = %q{kindai.rb}
|
14
|
+
s.description = %q{kindai.rb is kindai digital library downloader.}
|
15
|
+
s.email = %q{hitode909@gmail.com}
|
16
|
+
s.executables = ["kindai.rb"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/kindai.rb",
|
29
|
+
"kindai.gemspec",
|
30
|
+
"kindai.rb",
|
31
|
+
"lib/kindai.rb",
|
32
|
+
"lib/kindai/book.rb",
|
33
|
+
"lib/kindai/book_downloader.rb",
|
34
|
+
"lib/kindai/cli.rb",
|
35
|
+
"lib/kindai/interface.rb",
|
36
|
+
"lib/kindai/publisher.rb",
|
37
|
+
"lib/kindai/searcher.rb",
|
38
|
+
"lib/kindai/spread.rb",
|
39
|
+
"lib/kindai/spread_downloader.rb",
|
40
|
+
"lib/kindai/util.rb",
|
41
|
+
"publish.rb",
|
42
|
+
"spec/book_downloader_spec.rb",
|
43
|
+
"spec/book_spec.rb",
|
44
|
+
"spec/searcher_spec.rb",
|
45
|
+
"spec/spec_helper.rb",
|
46
|
+
"spec/spread_downloader_spec.rb",
|
47
|
+
"spec/spread_spec.rb"
|
48
|
+
]
|
49
|
+
s.homepage = %q{http://github.com/hitode909/kindairb}
|
50
|
+
s.licenses = ["MIT"]
|
51
|
+
s.require_paths = ["lib"]
|
52
|
+
s.rubygems_version = %q{1.5.2}
|
53
|
+
s.summary = %q{kindai digital library downloader}
|
54
|
+
s.test_files = [
|
55
|
+
"spec/book_downloader_spec.rb",
|
56
|
+
"spec/book_spec.rb",
|
57
|
+
"spec/searcher_spec.rb",
|
58
|
+
"spec/spec_helper.rb",
|
59
|
+
"spec/spread_downloader_spec.rb",
|
60
|
+
"spec/spread_spec.rb"
|
61
|
+
]
|
62
|
+
|
63
|
+
if s.respond_to? :specification_version then
|
64
|
+
s.specification_version = 3
|
65
|
+
|
66
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
67
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
68
|
+
s.add_runtime_dependency(%q<rmagick>, [">= 0"])
|
69
|
+
s.add_runtime_dependency(%q<zipruby>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
71
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
73
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
74
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.0"])
|
75
|
+
s.add_runtime_dependency(%q<zipruby>, [">= 0.3.6"])
|
76
|
+
s.add_runtime_dependency(%q<rmagick>, [">= 2.13.1"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
80
|
+
s.add_dependency(%q<zipruby>, [">= 0"])
|
81
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
82
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
84
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
85
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
86
|
+
s.add_dependency(%q<zipruby>, [">= 0.3.6"])
|
87
|
+
s.add_dependency(%q<rmagick>, [">= 2.13.1"])
|
88
|
+
end
|
89
|
+
else
|
90
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
91
|
+
s.add_dependency(%q<rmagick>, [">= 0"])
|
92
|
+
s.add_dependency(%q<zipruby>, [">= 0"])
|
93
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
94
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
95
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
96
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
97
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.0"])
|
98
|
+
s.add_dependency(%q<zipruby>, [">= 0.3.6"])
|
99
|
+
s.add_dependency(%q<rmagick>, [">= 2.13.1"])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
data/kindai.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
self_file =
|
5
|
+
if File.symlink?(__FILE__)
|
6
|
+
require 'pathname'
|
7
|
+
Pathname.new(__FILE__).realpath
|
8
|
+
else
|
9
|
+
__FILE__
|
10
|
+
end
|
11
|
+
$:.unshift(File.dirname(self_file) + "/lib")
|
12
|
+
|
13
|
+
require 'kindai'
|
14
|
+
|
15
|
+
warn 'WARNING: This script is deprecated. Use bin/kindai.rb'
|
16
|
+
|
17
|
+
Kindai::CLI.execute(STDOUT, ARGV)
|
data/lib/kindai/book.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Kindai
|
3
|
+
class Book
|
4
|
+
attr_accessor :permalink_uri
|
5
|
+
|
6
|
+
# ----- constructor -----
|
7
|
+
def self.new_from_permalink(permalink_uri)
|
8
|
+
raise "not info:ndljp" unless permalink_uri.match(/info\:ndljp/)
|
9
|
+
me = new
|
10
|
+
me.permalink_uri = permalink_uri
|
11
|
+
me
|
12
|
+
end
|
13
|
+
|
14
|
+
# ----- metadata -----
|
15
|
+
def title
|
16
|
+
title_container = control_page.at('.titlehead')
|
17
|
+
subtitle_container = control_page.at('.headmenu')
|
18
|
+
title_string = title_container.content.strip
|
19
|
+
title_string += subtitle_container.content.strip if subtitle_container
|
20
|
+
title_string
|
21
|
+
end
|
22
|
+
|
23
|
+
def author
|
24
|
+
metadata['著者標目']
|
25
|
+
end
|
26
|
+
|
27
|
+
def total_spread
|
28
|
+
self.spread_at(1).page.search('select#dlPages option').length
|
29
|
+
end
|
30
|
+
|
31
|
+
def spreads
|
32
|
+
@spreads ||= 1.upto(self.total_spread).map{|i| self.spread_at(i) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def base_uri
|
36
|
+
@base_uri ||=
|
37
|
+
begin
|
38
|
+
Kindai::Util.logger.debug "fetch permalink page"
|
39
|
+
page_uri = URI.parse(permalink_uri) + permalink_page.at('frame[name="W_BODY"]')['src']
|
40
|
+
|
41
|
+
page_file = Kindai::Util.fetch_uri page_uri.to_s
|
42
|
+
uri = page_file.base_uri.to_s + '&vs=10000,10000,0,0,0,0,0,0'
|
43
|
+
# uri += "&ref=" + [@trimming[:x], @trimming[:y], @trimming[:w], @trimming[:h], 5000, 5000, 0, 0].join(',') if @trimming
|
44
|
+
uri
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def spread_at(spread_number)
|
51
|
+
Kindai::Spread.new_from_book_and_spread_number(self, spread_number)
|
52
|
+
end
|
53
|
+
|
54
|
+
def metadata
|
55
|
+
@metadata ||=
|
56
|
+
begin
|
57
|
+
metadata_table = detail_page.search('table').find{ |table|
|
58
|
+
table.at('td').text == 'タイトル'
|
59
|
+
}
|
60
|
+
metadata_table.search('tr').inject({ }) { |prev, tr|
|
61
|
+
key, _, value = *tr.search('td').map{ |elem| elem.text }
|
62
|
+
prev[key] = value
|
63
|
+
prev
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# ----- pages -----
|
69
|
+
def permalink_page
|
70
|
+
@permalink_page ||=
|
71
|
+
begin
|
72
|
+
Kindai::Util.logger.debug "fetch permalink page"
|
73
|
+
page = Kindai::Util.fetch_uri permalink_uri rescue Kindai::Util.fetch_uri URI.escape(permalink_uri)
|
74
|
+
Nokogiri page
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def detail_uri
|
79
|
+
root = URI.parse('http://kindai.ndl.go.jp/BIBibDetail.php')
|
80
|
+
params = { }
|
81
|
+
control_page.search('input').each{ |input|
|
82
|
+
params[input['name']] = input['value'] if input['value']
|
83
|
+
}
|
84
|
+
path = '?' + params.each_pair.map{ |k, v| [URI.escape(k), URI.escape(v)].join('=')}.join('&')
|
85
|
+
root + path
|
86
|
+
end
|
87
|
+
|
88
|
+
def detail_page
|
89
|
+
@detail_page ||=
|
90
|
+
begin
|
91
|
+
Kindai::Util.logger.debug "fetch detail page"
|
92
|
+
page = Kindai::Util.fetch_uri detail_uri rescue Kindai::Util.fetch_uri URI.escape(detail_uri)
|
93
|
+
Nokogiri page
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def control_uri
|
98
|
+
URI.parse(permalink_uri) + permalink_page.at('frame[name="W_CONTROL"]')['src']
|
99
|
+
end
|
100
|
+
|
101
|
+
def control_page
|
102
|
+
@control_page ||=
|
103
|
+
begin
|
104
|
+
Kindai::Util.logger.debug "fetch permalink page"
|
105
|
+
Nokogiri Kindai::Util.fetch_uri control_uri
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Kindai
|
3
|
+
class BookDownloader
|
4
|
+
attr_accessor :book
|
5
|
+
attr_accessor :retry_count
|
6
|
+
attr_accessor :base_path
|
7
|
+
|
8
|
+
def self.new_from_book(book)
|
9
|
+
raise TypeError, "#{book} is not Kindai::Book" unless book.is_a? Kindai::Book
|
10
|
+
me = self.new
|
11
|
+
me.book = book
|
12
|
+
me.retry_count = 30
|
13
|
+
me.base_path = Dir.pwd
|
14
|
+
me
|
15
|
+
end
|
16
|
+
|
17
|
+
def download
|
18
|
+
return false if self.has_file?
|
19
|
+
create_directory
|
20
|
+
download_spreads
|
21
|
+
return true
|
22
|
+
end
|
23
|
+
|
24
|
+
def book_path
|
25
|
+
path = File.join(self.base_path, [@book.author, @book.title].compact.join(' - '))
|
26
|
+
File.expand_path path
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_directory
|
30
|
+
Dir.mkdir(book_path) unless File.directory?(book_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete
|
34
|
+
success = true
|
35
|
+
FileUtils.rm_r(self.book_path) rescue success = false
|
36
|
+
return success
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_file?
|
40
|
+
File.directory?(self.book_path) && self.spread_downloaders.all?(&:has_file?)
|
41
|
+
end
|
42
|
+
|
43
|
+
# --------------------------------------------------------------------
|
44
|
+
protected
|
45
|
+
|
46
|
+
def spread_downloaders
|
47
|
+
self.book.spreads.map{|spread|
|
48
|
+
dl = Kindai::SpreadDownloader.new_from_spread(spread)
|
49
|
+
dl.retry_count = self.retry_count
|
50
|
+
dl.book_path = self.book_path
|
51
|
+
dl
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def download_spreads
|
56
|
+
self.spread_downloaders.each{|dl|
|
57
|
+
dl.download
|
58
|
+
}
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/kindai/cli.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module Kindai
|
5
|
+
class CLI
|
6
|
+
BANNER = <<EOF
|
7
|
+
download:
|
8
|
+
by url: kindai.rb http://kindai.ndl.go.jp/info:ndljp/pid/922693
|
9
|
+
by keyword: kindai.rb 調理法
|
10
|
+
|
11
|
+
publish:
|
12
|
+
auto: kindai.rb publish '~/Desktop/石川,一口;丸山,平次郎 - 講談幽霊の片袖'
|
13
|
+
manual: kindai.rb publish --position 2850x2450+320+380 '~/Desktop/石川,一口;丸山,平次郎 - 講談幽霊の片袖'
|
14
|
+
EOF
|
15
|
+
|
16
|
+
def self.execute(stdout, arguments=[])
|
17
|
+
if arguments.first == 'publish'
|
18
|
+
arguments.shift
|
19
|
+
self.execute_publish(stdout, arguments)
|
20
|
+
else
|
21
|
+
self.execute_download(stdout, arguments)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.execute_download(stdout, arguments)
|
26
|
+
config = { }
|
27
|
+
parser = OptionParser.new(BANNER) {|opt|
|
28
|
+
opt.on('-o OUTPUT_DIRECTORY', '--output', 'specify output directory') {|v|
|
29
|
+
config[:base_path] = v
|
30
|
+
}
|
31
|
+
opt.on('--debug', 'enable debug mode') {|v|
|
32
|
+
Kindai::Util.debug_mode!
|
33
|
+
}
|
34
|
+
opt.on('--retry TIMES', 'retry times (default is 3)') {|v|
|
35
|
+
config[:retry_count] = v.to_i
|
36
|
+
}
|
37
|
+
opt.parse!(arguments)
|
38
|
+
}
|
39
|
+
|
40
|
+
if arguments.empty?
|
41
|
+
stdout.puts parser.help
|
42
|
+
exit 1
|
43
|
+
end
|
44
|
+
|
45
|
+
arguments.each{ |arg|
|
46
|
+
if URI.regexp =~ arg and URI.parse(arg).is_a? URI::HTTP
|
47
|
+
Kindai::Interface.download_url arg, config
|
48
|
+
else
|
49
|
+
Kindai::Interface.download_keyword arg, config
|
50
|
+
end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.execute_publish(stdout, arguments)
|
55
|
+
config = { }
|
56
|
+
parser = OptionParser.new(BANNER) {|opt|
|
57
|
+
opt.on('--position TRIMMING_POSITION', 'specify trimming position (example:') {|v|
|
58
|
+
m = v.match(/^(\d+)x(\d+)\+(\d+)\+(\d+)$/)
|
59
|
+
unless m
|
60
|
+
raise "invalid trimming position( example: 3200x2450+320+380, WIDTHxHEIGHT+OFFSET_X+OFFSET_Y )"
|
61
|
+
end
|
62
|
+
config[:trimming] = {:width => m[1].to_i, :height => m[2].to_i, :x => m[3].to_i, :y => m[4].to_i}
|
63
|
+
}
|
64
|
+
opt.on('--debug', 'enable debug mode') {|v|
|
65
|
+
Kindai::Util.debug_mode!
|
66
|
+
}
|
67
|
+
opt.parse!(arguments)
|
68
|
+
}
|
69
|
+
|
70
|
+
if arguments.empty?
|
71
|
+
stdout.puts parser.help
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
|
75
|
+
arguments.each{|file|
|
76
|
+
Kindai::Util.logger.info "publish #{file}"
|
77
|
+
publisher = Kindai::Publisher.new_from_path file
|
78
|
+
publisher.empty('trim')
|
79
|
+
publisher.empty('*zip')
|
80
|
+
if config[:trimming]
|
81
|
+
publisher.trim(config[:trimming])
|
82
|
+
end
|
83
|
+
publisher.publish_auto
|
84
|
+
}
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Kindai::Interface
|
3
|
+
def self.download_url(url, config = { })
|
4
|
+
book = Kindai::Book.new_from_permalink(url)
|
5
|
+
download_book(book, config)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.download_book(book, config = { })
|
9
|
+
downloader = Kindai::BookDownloader.new_from_book(book)
|
10
|
+
downloader.base_path = config[:base_path] if config[:base_path]
|
11
|
+
downloader.retry_count = config[:retry_count] if config[:retry_count]
|
12
|
+
Kindai::Util.logger.info "download #{book.title}(#{book.total_spread} spreads) to #{downloader.book_path}"
|
13
|
+
downloader.download
|
14
|
+
|
15
|
+
publisher = Kindai::Publisher.new_from_path downloader.book_path
|
16
|
+
publisher.publish_auto
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.download_keyword(keyword, config = { })
|
20
|
+
searcher = Kindai::Searcher.search(keyword)
|
21
|
+
searcher.each_with_index { |book, index|
|
22
|
+
begin
|
23
|
+
Kindai::Util.logger.info "book #{index+1} / #{searcher.length}"
|
24
|
+
download_book book, config
|
25
|
+
rescue => error
|
26
|
+
p error
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|