bookbinder 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/lib/bookbinder.rb +6 -5
  2. data/lib/bookbinder/file.rb +1 -2
  3. data/lib/bookbinder/file_system/zip_file.rb +4 -4
  4. data/lib/bookbinder/operations.rb +7 -1
  5. data/lib/bookbinder/package.rb +25 -27
  6. data/lib/bookbinder/package/openbook.rb +2 -3
  7. data/lib/bookbinder/scratch.rb +36 -0
  8. data/lib/bookbinder/transform/{openbook/json.rb → book_json.rb} +1 -1
  9. data/lib/bookbinder/version.rb +1 -1
  10. metadata +12 -63
  11. data/lib/bookbinder/package/epub.rb +0 -64
  12. data/lib/bookbinder/package/media_ripper.rb +0 -47
  13. data/lib/bookbinder/package/mp3_audiobook.rb +0 -43
  14. data/lib/bookbinder/transform/epub/audio_overlay.rb +0 -227
  15. data/lib/bookbinder/transform/epub/audio_soundtrack.rb +0 -73
  16. data/lib/bookbinder/transform/epub/contributor.rb +0 -11
  17. data/lib/bookbinder/transform/epub/cover_image.rb +0 -80
  18. data/lib/bookbinder/transform/epub/cover_page.rb +0 -148
  19. data/lib/bookbinder/transform/epub/creator.rb +0 -67
  20. data/lib/bookbinder/transform/epub/description.rb +0 -43
  21. data/lib/bookbinder/transform/epub/language.rb +0 -29
  22. data/lib/bookbinder/transform/epub/metadata.rb +0 -140
  23. data/lib/bookbinder/transform/epub/nav.rb +0 -60
  24. data/lib/bookbinder/transform/epub/nav_toc.rb +0 -177
  25. data/lib/bookbinder/transform/epub/ncx.rb +0 -63
  26. data/lib/bookbinder/transform/epub/ocf.rb +0 -33
  27. data/lib/bookbinder/transform/epub/opf.rb +0 -22
  28. data/lib/bookbinder/transform/epub/package_identifier.rb +0 -87
  29. data/lib/bookbinder/transform/epub/rendition.rb +0 -273
  30. data/lib/bookbinder/transform/epub/resources.rb +0 -38
  31. data/lib/bookbinder/transform/epub/spine.rb +0 -79
  32. data/lib/bookbinder/transform/epub/title.rb +0 -92
  33. data/lib/bookbinder/transform/epub/version.rb +0 -39
  34. data/lib/bookbinder/transform/media_ripper/cover_image.rb +0 -12
  35. data/lib/bookbinder/transform/media_ripper/eisbn.rb +0 -15
  36. data/lib/bookbinder/transform/media_ripper/metadata.rb +0 -27
  37. data/lib/bookbinder/transform/media_ripper/nav_toc.rb +0 -57
  38. data/lib/bookbinder/transform/media_ripper/publisher.rb +0 -15
  39. data/lib/bookbinder/transform/media_ripper/rendition.rb +0 -7
  40. data/lib/bookbinder/transform/media_ripper/spine.rb +0 -34
  41. data/lib/bookbinder/transform/media_ripper/title.rb +0 -16
  42. data/lib/bookbinder/transform/mp3_audiobook/cover_image.rb +0 -25
  43. data/lib/bookbinder/transform/mp3_audiobook/creator.rb +0 -27
  44. data/lib/bookbinder/transform/mp3_audiobook/description.rb +0 -18
  45. data/lib/bookbinder/transform/mp3_audiobook/metadata.rb +0 -20
  46. data/lib/bookbinder/transform/mp3_audiobook/nav_toc.rb +0 -71
  47. data/lib/bookbinder/transform/mp3_audiobook/publisher.rb +0 -18
  48. data/lib/bookbinder/transform/mp3_audiobook/rendition.rb +0 -7
  49. data/lib/bookbinder/transform/mp3_audiobook/spine.rb +0 -33
  50. data/lib/bookbinder/transform/mp3_audiobook/subject.rb +0 -18
  51. data/lib/bookbinder/transform/mp3_audiobook/title.rb +0 -18
data/lib/bookbinder.rb CHANGED
@@ -4,12 +4,12 @@ require 'zip'
4
4
  require 'json'
5
5
  require 'time'
6
6
  require 'cgi'
7
- require 'mp3info'
8
7
 
9
8
  module Bookbinder
10
9
  end
11
10
 
12
11
  require 'bookbinder/version'
12
+ require 'bookbinder/scratch'
13
13
  require 'bookbinder/media_type'
14
14
  require 'bookbinder/operations'
15
15
  require 'bookbinder/file_system'
@@ -25,8 +25,9 @@ require 'bookbinder/file_system/memory'
25
25
  require 'bookbinder/file_system/directory'
26
26
  require 'bookbinder/file_system/zip_file'
27
27
 
28
- # Package types
28
+ # Core package types
29
29
  require 'bookbinder/package/openbook'
30
- require 'bookbinder/package/epub'
31
- require 'bookbinder/package/media_ripper'
32
- require 'bookbinder/package/mp3_audiobook'
30
+ begin
31
+ require 'bb-epub'
32
+ rescue LoadError
33
+ end
@@ -108,7 +108,7 @@ class Bookbinder::File
108
108
  # Proxy through to FileSystem#set_file.
109
109
  #
110
110
  def set_file(file_io)
111
- @file_system.set_file(path, io)
111
+ @file_system.set_file(path, file_io)
112
112
  end
113
113
 
114
114
 
@@ -145,5 +145,4 @@ class Bookbinder::File
145
145
  end
146
146
  end
147
147
 
148
-
149
148
  end
@@ -8,7 +8,9 @@ class Bookbinder::FileSystem::ZipFile < Bookbinder::FileSystem
8
8
 
9
9
 
10
10
  def exists?(path)
11
- @zipfile && @zipfile.find_entry(path) ? true : false
11
+ ascii_path = path
12
+ ascii_path.force_encoding('ASCII-8BIT')
13
+ @zipfile && @zipfile.find_entry(ascii_path) ? true : false
12
14
  end
13
15
 
14
16
 
@@ -36,9 +38,7 @@ class Bookbinder::FileSystem::ZipFile < Bookbinder::FileSystem
36
38
  write_after = mode[0] != 'r'
37
39
  if read_before
38
40
  must_exist(path)
39
- tmp_path = Dir::Tmpname.create(File.basename(path)) { |tmp_path|
40
- raise Errno::EEXIST if File.exists?(tmp_path)
41
- }
41
+ tmp_path = Bookbinder::Scratch.file(path)
42
42
  @zipfile.commit
43
43
  @zipfile.extract(path, tmp_path)
44
44
  File.open(tmp_path, mode) { |tmp_file|
@@ -27,7 +27,11 @@ class Bookbinder::Operations
27
27
  def validate(path)
28
28
  pkg_klass = recognize(path)
29
29
  pkg = pkg_klass.read(path)
30
- # TODO: emit warnings?
30
+ # TODO: Warnings?
31
+ # pkg.warnings.each { |warn|
32
+ # STDERR.puts("#{warn[:transform]}##{warn[:method]}: #{warn[:message]}")
33
+ # }
34
+ Bookbinder::Scratch.cleanup
31
35
  pkg
32
36
  end
33
37
 
@@ -40,6 +44,7 @@ class Bookbinder::Operations
40
44
  pkg_klass = recognize(path)
41
45
  pkg = pkg_klass.read(path)
42
46
  pkg.write(path)
47
+ Bookbinder::Scratch.cleanup
43
48
  pkg
44
49
  end
45
50
 
@@ -54,6 +59,7 @@ class Bookbinder::Operations
54
59
  src_pkg = src_klass.read(src_path)
55
60
  dest_pkg = src_pkg.export(dest_klass)
56
61
  dest_pkg.write(dest_path)
62
+ Bookbinder::Scratch.cleanup
57
63
  [src_pkg, dest_pkg]
58
64
  end
59
65
 
@@ -13,19 +13,8 @@ class Bookbinder::Package
13
13
  end
14
14
 
15
15
 
16
- # This will require() all the .rb files within the given subdirectory
17
- # of 'bookbinder/transform'. So, for the EPUB package, you'd just call:
18
- #
19
- # require_transforms('epub')
20
- #
21
- # ... to load all the EPUB-specific transforms.
22
- #
23
- def self.require_transforms(dir)
24
- Dir.glob(
25
- File.join(File.dirname(__FILE__), 'transform', dir, '*.rb')
26
- ).each { |rb|
27
- require("bookbinder/transform/#{dir}/#{File.basename(rb, '.rb')}")
28
- }
16
+ def self.require_transforms(path)
17
+ Dir[File.join(path, '*.rb')].each { |rb| require(rb) }
29
18
  end
30
19
 
31
20
 
@@ -115,7 +104,7 @@ class Bookbinder::Package
115
104
  if path_or_file_system.kind_of?(String)
116
105
  dest_file_system = file_system_from_path(dest_file_system)
117
106
  end
118
- all_book_content.each { |ref|
107
+ copy_file = lambda { |ref|
119
108
  rsrc = file(ref['path'])
120
109
  dest_path = ref['path']
121
110
  if content_root && !content_root.empty?
@@ -124,28 +113,33 @@ class Bookbinder::Package
124
113
  end
125
114
  rsrc.copy_to(dest_file_system, dest_path)
126
115
  }
116
+ map['cover'].values.each(&copy_file) if map['cover']
117
+ map['spine'].each(&copy_file) if map['spine']
118
+ if map['resources']
119
+ missing = []
120
+ map['resources'].each { |ref|
121
+ begin
122
+ copy_file.call(ref)
123
+ rescue Bookbinder::FileSystem::UnknownPath
124
+ missing << ref
125
+ end
126
+ }
127
+ missing.each { |ref|
128
+ map['resources'].delete(ref)
129
+ warn("Resource not found: #{ref['path']}. IGNORED.")
130
+ }
131
+ end
127
132
  self.class.new.tap { |pkg|
128
133
  pkg.import(@map, dest_file_system, content_root, @options)
129
134
  }
130
135
  end
131
136
 
132
137
 
133
- def all_book_content
134
- book_content = []
135
- book_content += map['cover'].values if map['cover']
136
- book_content += map['spine'] if map['spine']
137
- book_content += map['resources'] if map['resources']
138
- book_content
139
- end
140
-
141
-
142
138
  # Writes package to path. This is destructive! Anything already
143
139
  # at the path will be replaced.
144
140
  #
145
141
  def write(path)
146
- tmp_path = Dir::Tmpname.create(File.basename(path)) { |tmp_path|
147
- raise Errno::EEXIST if File.exists?(tmp_path)
148
- }
142
+ tmp_path = Bookbinder::Scratch.file(path)
149
143
  dest_fs = file_system_from_path(tmp_path)
150
144
  write_to_file_system(dest_fs)
151
145
  dest_fs.close if dest_fs.respond_to?(:close)
@@ -273,7 +267,11 @@ class Bookbinder::Package
273
267
  if File.directory?(path) || File.extname(path).empty?
274
268
  Bookbinder::FileSystem::Directory.new(path)
275
269
  else
276
- Bookbinder::FileSystem::ZipFile.new(path)
270
+ begin
271
+ Bookbinder::FileSystem::ZipFile.new(path)
272
+ rescue Zip::ZipError
273
+ path
274
+ end
277
275
  end
278
276
  end
279
277
 
@@ -1,6 +1,6 @@
1
1
  class Bookbinder::Package::Openbook < Bookbinder::Package
2
2
 
3
- require_transforms('openbook')
3
+ require('bookbinder/transform/book_json')
4
4
 
5
5
  DEFAULT_CONTENT_ROOT = ''
6
6
  attr_accessor(:mip)
@@ -19,7 +19,7 @@ class Bookbinder::Package::Openbook < Bookbinder::Package
19
19
  def self.transforms
20
20
  @transforms ||= [
21
21
  Bookbinder::Transform::Generator,
22
- Bookbinder::Transform::Openbook_JSON
22
+ Bookbinder::Transform::BookJSON
23
23
  ]
24
24
  end
25
25
 
@@ -29,5 +29,4 @@ class Bookbinder::Package::Openbook < Bookbinder::Package
29
29
  super
30
30
  end
31
31
 
32
-
33
32
  end
@@ -0,0 +1,36 @@
1
+ # Manages temporary files and temporary directories, which are
2
+ # removed when the Ruby process exits.
3
+ #
4
+ class Bookbinder::Scratch
5
+
6
+ def self.directory(path)
7
+ @paths ||= []
8
+ create_tmpname(path).tap { |path| @paths << path }
9
+ end
10
+
11
+
12
+ def self.file(path)
13
+ @paths ||= []
14
+ ext = File.extname(path)
15
+ base = File.basename(path, ext)
16
+ create_tmpname([base, ext]).tap { |path| @paths << path }
17
+ end
18
+
19
+
20
+ def self.cleanup
21
+ return unless defined?(@paths)
22
+ while @paths.size > 0
23
+ path = @paths.shift
24
+ FileUtils.rm_r(path) if File.exists?(path)
25
+ end
26
+ end
27
+
28
+
29
+ def self.create_tmpname(parts)
30
+ Dir::Tmpname.create(parts) { |p| raise Errno::EEXIST if File.exists?(p) }
31
+ end
32
+
33
+
34
+ at_exit { cleanup }
35
+
36
+ end
@@ -1,4 +1,4 @@
1
- class Bookbinder::Transform::Openbook_JSON < Bookbinder::Transform
1
+ class Bookbinder::Transform::BookJSON < Bookbinder::Transform
2
2
 
3
3
  JSON_PATH = 'book.json'
4
4
 
@@ -1,5 +1,5 @@
1
1
  module Bookbinder
2
2
 
3
- VERSION = "0.3.4"
3
+ VERSION = "0.4.0"
4
4
 
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bookbinder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
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: 2015-01-29 00:00:00.000000000 Z
12
+ date: 2015-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &15331860 !ruby/object:Gem::Requirement
16
+ requirement: &20788320 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *15331860
24
+ version_requirements: *20788320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rubyzip
27
- requirement: &15331360 !ruby/object:Gem::Requirement
27
+ requirement: &20794420 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.0.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *15331360
35
+ version_requirements: *20794420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mime-types
38
- requirement: &15330940 !ruby/object:Gem::Requirement
38
+ requirement: &20809240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,21 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *15330940
47
- - !ruby/object:Gem::Dependency
48
- name: ruby-mp3info
49
- requirement: &15330460 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :runtime
56
- prerelease: false
57
- version_requirements: *15330460
46
+ version_requirements: *20809240
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: rake
60
- requirement: &15330040 !ruby/object:Gem::Requirement
49
+ requirement: &20804560 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - ! '>='
@@ -65,7 +54,7 @@ dependencies:
65
54
  version: '0'
66
55
  type: :development
67
56
  prerelease: false
68
- version_requirements: *15330040
57
+ version_requirements: *20804560
69
58
  description: Convert easily between common ebook formats.
70
59
  email:
71
60
  - jpearson@overdrive.com
@@ -83,51 +72,11 @@ files:
83
72
  - lib/bookbinder/file_system.rb
84
73
  - lib/bookbinder/media_type.rb
85
74
  - lib/bookbinder/operations.rb
86
- - lib/bookbinder/package/epub.rb
87
- - lib/bookbinder/package/media_ripper.rb
88
- - lib/bookbinder/package/mp3_audiobook.rb
89
75
  - lib/bookbinder/package/openbook.rb
90
76
  - lib/bookbinder/package.rb
91
- - lib/bookbinder/transform/epub/audio_overlay.rb
92
- - lib/bookbinder/transform/epub/audio_soundtrack.rb
93
- - lib/bookbinder/transform/epub/contributor.rb
94
- - lib/bookbinder/transform/epub/cover_image.rb
95
- - lib/bookbinder/transform/epub/cover_page.rb
96
- - lib/bookbinder/transform/epub/creator.rb
97
- - lib/bookbinder/transform/epub/description.rb
98
- - lib/bookbinder/transform/epub/language.rb
99
- - lib/bookbinder/transform/epub/metadata.rb
100
- - lib/bookbinder/transform/epub/nav.rb
101
- - lib/bookbinder/transform/epub/nav_toc.rb
102
- - lib/bookbinder/transform/epub/ncx.rb
103
- - lib/bookbinder/transform/epub/ocf.rb
104
- - lib/bookbinder/transform/epub/opf.rb
105
- - lib/bookbinder/transform/epub/package_identifier.rb
106
- - lib/bookbinder/transform/epub/rendition.rb
107
- - lib/bookbinder/transform/epub/resources.rb
108
- - lib/bookbinder/transform/epub/spine.rb
109
- - lib/bookbinder/transform/epub/title.rb
110
- - lib/bookbinder/transform/epub/version.rb
77
+ - lib/bookbinder/scratch.rb
78
+ - lib/bookbinder/transform/book_json.rb
111
79
  - lib/bookbinder/transform/generator.rb
112
- - lib/bookbinder/transform/media_ripper/cover_image.rb
113
- - lib/bookbinder/transform/media_ripper/eisbn.rb
114
- - lib/bookbinder/transform/media_ripper/metadata.rb
115
- - lib/bookbinder/transform/media_ripper/nav_toc.rb
116
- - lib/bookbinder/transform/media_ripper/publisher.rb
117
- - lib/bookbinder/transform/media_ripper/rendition.rb
118
- - lib/bookbinder/transform/media_ripper/spine.rb
119
- - lib/bookbinder/transform/media_ripper/title.rb
120
- - lib/bookbinder/transform/mp3_audiobook/cover_image.rb
121
- - lib/bookbinder/transform/mp3_audiobook/creator.rb
122
- - lib/bookbinder/transform/mp3_audiobook/description.rb
123
- - lib/bookbinder/transform/mp3_audiobook/metadata.rb
124
- - lib/bookbinder/transform/mp3_audiobook/nav_toc.rb
125
- - lib/bookbinder/transform/mp3_audiobook/publisher.rb
126
- - lib/bookbinder/transform/mp3_audiobook/rendition.rb
127
- - lib/bookbinder/transform/mp3_audiobook/spine.rb
128
- - lib/bookbinder/transform/mp3_audiobook/subject.rb
129
- - lib/bookbinder/transform/mp3_audiobook/title.rb
130
- - lib/bookbinder/transform/openbook/json.rb
131
80
  - lib/bookbinder/transform/organizer.rb
132
81
  - lib/bookbinder/transform.rb
133
82
  - lib/bookbinder/version.rb
@@ -1,64 +0,0 @@
1
- class Bookbinder::Package::EPUB < Bookbinder::Package
2
-
3
- require_transforms('epub')
4
-
5
- DEFAULT_TRANSFORMS = [
6
- Bookbinder::Transform::EPUB_PackageIdentifier,
7
- Bookbinder::Transform::EPUB_Title,
8
- Bookbinder::Transform::EPUB_Creator,
9
- Bookbinder::Transform::EPUB_Contributor,
10
- Bookbinder::Transform::EPUB_Language,
11
- Bookbinder::Transform::EPUB_CoverImage,
12
- Bookbinder::Transform::EPUB_Description,
13
- Bookbinder::Transform::EPUB_Version,
14
- Bookbinder::Transform::EPUB_Spine,
15
- Bookbinder::Transform::EPUB_Resources,
16
- Bookbinder::Transform::EPUB_NavToc,
17
- Bookbinder::Transform::EPUB_CoverPage,
18
- Bookbinder::Transform::EPUB_Rendition,
19
- Bookbinder::Transform::EPUB_AudioOverlay,
20
- Bookbinder::Transform::Organizer,
21
- Bookbinder::Transform::Generator
22
- ]
23
-
24
- DEFAULT_CONTENT_ROOT = 'EPUB'
25
-
26
-
27
- def self.recognize(path)
28
- return (
29
- File.extname(path).downcase == '.epub' ||
30
- File.directory?(File.join(path, 'META-INF'))
31
- )
32
- end
33
-
34
-
35
- def self.transforms
36
- @transforms ||= DEFAULT_TRANSFORMS
37
- end
38
-
39
-
40
- def make_id(path)
41
- path.gsub(/[^\w]/, '-')
42
- end
43
-
44
-
45
- def make_path(href)
46
- CGI.unescape(href)
47
- end
48
-
49
-
50
- def make_href(path)
51
- CGI.escape(path)
52
- end
53
-
54
-
55
- protected
56
-
57
- # Overriding this Package method to inject EPUB's mimetype file.
58
- #
59
- def write_to_file_system(dest_file_system)
60
- dest_file_system.write('mimetype', 'application/epub+zip')
61
- super
62
- end
63
-
64
- end