epubinfo 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +4 -0
- data/lib/epubinfo.rb +2 -0
- data/lib/epubinfo/models/book.rb +7 -1
- data/lib/epubinfo/models/cover.rb +99 -0
- data/lib/epubinfo/parser.rb +9 -7
- metadata +89 -28
data/README.md
CHANGED
@@ -13,6 +13,10 @@ Which returns a `EPUBInfo::Models::Book` instance, please refer to the [API docu
|
|
13
13
|
|
14
14
|
## Changelog
|
15
15
|
|
16
|
+
**0.4.0** *July 31, 2012*
|
17
|
+
|
18
|
+
* Added Book#cover method for extracting covers from epubs
|
19
|
+
|
16
20
|
**0.3.6** *June 18, 2012*
|
17
21
|
|
18
22
|
* Upgraded rubyzip dependency to version 0.9.9 for more robust zip handling
|
data/lib/epubinfo.rb
CHANGED
data/lib/epubinfo/models/book.rb
CHANGED
@@ -58,6 +58,10 @@ module EPUBInfo
|
|
58
58
|
def drm_protected; @drm_protected || false; end
|
59
59
|
alias :drm_protected? :drm_protected
|
60
60
|
|
61
|
+
# Cover
|
62
|
+
# @return [Cover]
|
63
|
+
attr_accessor :cover
|
64
|
+
|
61
65
|
# Should never be called directly, go through EPUBInfo.get
|
62
66
|
def initialize(parser)
|
63
67
|
document = parser.metadata_document
|
@@ -76,6 +80,7 @@ module EPUBInfo
|
|
76
80
|
self.languages = metadata.xpath('.//language').map(&:content)
|
77
81
|
self.rights = metadata.xpath('.//rights').first.content rescue nil
|
78
82
|
self.drm_protected = parser.drm_protected?
|
83
|
+
self.cover = EPUBInfo::Models::Cover.new(parser)
|
79
84
|
end
|
80
85
|
|
81
86
|
|
@@ -94,7 +99,8 @@ module EPUBInfo
|
|
94
99
|
:source => @source,
|
95
100
|
:languages => @languages,
|
96
101
|
:rights => @rights,
|
97
|
-
:drm_protected => @drm_protected
|
102
|
+
:drm_protected => @drm_protected,
|
103
|
+
:cover => @cover,
|
98
104
|
}
|
99
105
|
end
|
100
106
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module EPUBInfo
|
2
|
+
module Models
|
3
|
+
class Cover
|
4
|
+
def self.new(parser)
|
5
|
+
return nil unless EPUBInfo::Parser === parser
|
6
|
+
|
7
|
+
cover = super(parser)
|
8
|
+
|
9
|
+
if cover.exists?
|
10
|
+
cover
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(parser)
|
17
|
+
@parser = parser
|
18
|
+
@path = epub_cover_file_path
|
19
|
+
@content_type = epub_cover_content_type
|
20
|
+
end
|
21
|
+
|
22
|
+
# Original name of cover file
|
23
|
+
# @return [String]
|
24
|
+
def original_file_name
|
25
|
+
File.basename(@path) if @path
|
26
|
+
end
|
27
|
+
|
28
|
+
# Content type of cover file
|
29
|
+
# @return [String]
|
30
|
+
attr_accessor :content_type
|
31
|
+
def content_type; @content_type; end
|
32
|
+
|
33
|
+
# Cover exists?
|
34
|
+
# @return [Boolean]
|
35
|
+
# @!visibility private
|
36
|
+
def exists?
|
37
|
+
!!@path && @parser.zip_file.find_entry(zip_file_path)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Cover file
|
41
|
+
# @return [File]
|
42
|
+
# Tempfile is used to enable access to cover file
|
43
|
+
# If block is passed, the tempfile is passed to it
|
44
|
+
# cover.file do { |f| puts f.size }
|
45
|
+
# Otherwise user is responsible to unlink and close tempfile
|
46
|
+
# file = book.cover.file
|
47
|
+
# file.size
|
48
|
+
# file.close!
|
49
|
+
def tempfile(&block)
|
50
|
+
tempfile = Tempfile.new('epubinfo')
|
51
|
+
tempfile.binmode
|
52
|
+
|
53
|
+
cover_file = @parser.zip_file.read(zip_file_path)
|
54
|
+
tempfile.write(cover_file)
|
55
|
+
|
56
|
+
if block_given?
|
57
|
+
yield tempfile
|
58
|
+
tempfile.close!
|
59
|
+
else
|
60
|
+
# user is responsible for closing file
|
61
|
+
tempfile
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def epub_cover_file_path
|
68
|
+
epub_cover_item.attr('href') if epub_cover_item
|
69
|
+
end
|
70
|
+
|
71
|
+
def epub_cover_content_type
|
72
|
+
epub_cover_item.attr('media-type') if epub_cover_item
|
73
|
+
end
|
74
|
+
|
75
|
+
def epub_cover_item
|
76
|
+
@epub_cover_item ||= begin
|
77
|
+
metadata = @parser.metadata_document.css('metadata')
|
78
|
+
cover_id = metadata.css('meta [name=cover]').attr('content').value rescue nil || 'cover-image'
|
79
|
+
|
80
|
+
manifest = @parser.metadata_document.css('manifest')
|
81
|
+
|
82
|
+
manifest.css("item [id = #{cover_id}]").first rescue nil ||
|
83
|
+
manifest.css("item [property = #{cover_id}]").first rescue nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def zip_file_path
|
88
|
+
dir = File.dirname(@parser.metadata_path)
|
89
|
+
path =
|
90
|
+
if dir == '.'
|
91
|
+
@path
|
92
|
+
else
|
93
|
+
File.join(dir, @path)
|
94
|
+
end
|
95
|
+
CGI::unescape(path)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/epubinfo/parser.rb
CHANGED
@@ -16,8 +16,6 @@ module EPUBInfo
|
|
16
16
|
@drm_protected ||= !!zip_file.find_entry('META-INF/rights.xml')
|
17
17
|
end
|
18
18
|
|
19
|
-
private
|
20
|
-
|
21
19
|
def zip_file
|
22
20
|
begin
|
23
21
|
@zip_file ||= Zip::ZipFile.open(@path)
|
@@ -26,6 +24,15 @@ module EPUBInfo
|
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
27
|
+
def metadata_path
|
28
|
+
@metadata_path ||= begin
|
29
|
+
root_document.remove_namespaces!
|
30
|
+
root_document.css('container rootfiles rootfile:first-child').attribute('full-path').content
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
29
36
|
def root_document
|
30
37
|
begin
|
31
38
|
@root_document ||= Nokogiri::XML(zip_file.read('META-INF/container.xml'))
|
@@ -34,11 +41,6 @@ module EPUBInfo
|
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
37
|
-
def metadata_path
|
38
|
-
root_document.remove_namespaces!
|
39
|
-
root_document.css('container rootfiles rootfile:first-child').attribute('full-path').content
|
40
|
-
end
|
41
|
-
|
42
44
|
def load_metadata_file
|
43
45
|
Nokogiri::XML(zip_file.read(metadata_path))
|
44
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: epubinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubyzip
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.9.9
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.9
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: nokogiri
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: 1.4.2
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.4.2
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: 2.10.0
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.10.0
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: yard
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ~>
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 0.8.1
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.8.1
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: bundler
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ~>
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: 1.1.3
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.1.3
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: jeweler
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ~>
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: 1.8.3
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.8.3
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: simplecov
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: guard
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ! '>='
|
@@ -98,10 +133,15 @@ dependencies:
|
|
98
133
|
version: '0'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: guard-rspec
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ! '>='
|
@@ -109,10 +149,15 @@ dependencies:
|
|
109
149
|
version: '0'
|
110
150
|
type: :development
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
113
158
|
- !ruby/object:Gem::Dependency
|
114
159
|
name: rb-fsevent
|
115
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
116
161
|
none: false
|
117
162
|
requirements:
|
118
163
|
- - ! '>='
|
@@ -120,10 +165,15 @@ dependencies:
|
|
120
165
|
version: '0'
|
121
166
|
type: :development
|
122
167
|
prerelease: false
|
123
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
124
174
|
- !ruby/object:Gem::Dependency
|
125
175
|
name: growl
|
126
|
-
requirement:
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
127
177
|
none: false
|
128
178
|
requirements:
|
129
179
|
- - ! '>='
|
@@ -131,10 +181,15 @@ dependencies:
|
|
131
181
|
version: '0'
|
132
182
|
type: :development
|
133
183
|
prerelease: false
|
134
|
-
version_requirements:
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
135
190
|
- !ruby/object:Gem::Dependency
|
136
191
|
name: fuubar
|
137
|
-
requirement:
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
138
193
|
none: false
|
139
194
|
requirements:
|
140
195
|
- - ! '>='
|
@@ -142,7 +197,12 @@ dependencies:
|
|
142
197
|
version: '0'
|
143
198
|
type: :development
|
144
199
|
prerelease: false
|
145
|
-
version_requirements:
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
146
206
|
description: Supports EPUB2 and EPUB3 formats.
|
147
207
|
email: christof@chdorner.com
|
148
208
|
executables: []
|
@@ -153,6 +213,7 @@ extra_rdoc_files:
|
|
153
213
|
files:
|
154
214
|
- lib/epubinfo.rb
|
155
215
|
- lib/epubinfo/models/book.rb
|
216
|
+
- lib/epubinfo/models/cover.rb
|
156
217
|
- lib/epubinfo/models/date.rb
|
157
218
|
- lib/epubinfo/models/identifier.rb
|
158
219
|
- lib/epubinfo/models/person.rb
|
@@ -175,7 +236,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
236
|
version: '0'
|
176
237
|
segments:
|
177
238
|
- 0
|
178
|
-
hash:
|
239
|
+
hash: 425566557774208517
|
179
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
241
|
none: false
|
181
242
|
requirements:
|
@@ -184,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
245
|
version: '0'
|
185
246
|
requirements: []
|
186
247
|
rubyforge_project:
|
187
|
-
rubygems_version: 1.8.
|
248
|
+
rubygems_version: 1.8.24
|
188
249
|
signing_key:
|
189
250
|
specification_version: 3
|
190
251
|
summary: Extracts metadata information from EPUB files
|