epub-directory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ ### 0.1.0 / 2018-10-21
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'kramdown'
7
+ end
8
+
9
+ group :test do
10
+ if RUBY_PLATFORM.match /darwin/
11
+ gem 'terminal-notifier'
12
+ end
13
+ end
@@ -0,0 +1,57 @@
1
+ # EPUB Directory
2
+
3
+ * [Homepage](https://rubygems.org/gems/epub-directory)
4
+ * [Documentation](http://rubydoc.info/gems/epub-directory/frames)
5
+ * [Email](mailto:KitaitiMakoto at gmail.com)
6
+
7
+ ## Description
8
+
9
+ Builds EPUB directory static site from EPUB files, package documents or Web Publication manifests.
10
+
11
+ ## Features
12
+
13
+ * Registers EPUB information into `src` directory.
14
+ * Builds static EPUB directory site to `build` directory.
15
+
16
+ ## Examples
17
+
18
+ require 'epub/directory'
19
+
20
+ ## Requirements
21
+
22
+ ## Install
23
+
24
+ $ gem install epub-directory
25
+
26
+ ## Synopsis
27
+
28
+ ### Registering EPUB info
29
+
30
+ $ epub-directory path/to/document.epub
31
+
32
+ This command makes `src` directory, registers under it, and then build EPUB directory site.
33
+
34
+ ### Build EPUB directory site
35
+
36
+ $ epub-directory
37
+
38
+ This command builds EPUB directory site to `build` directory.
39
+
40
+ ## Copyright
41
+
42
+ #
43
+ # Copyright (c) 2018 Kitaiti Makoto
44
+ #
45
+ # EPUB Directory is free software: you can redistribute it and/or modify
46
+ # it under the terms of the GNU Affero General Public License as published
47
+ # by the Free Software Foundation, either version 3 of the License, or
48
+ # (at your option) any later version.
49
+ #
50
+ # EPUB Directory is distributed in the hope that it will be useful,
51
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
52
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53
+ # GNU Affero General Public License for more details.
54
+ #
55
+ # You should have received a copy of the GNU Affero General Public License
56
+ # along with EPUB Directory. If not, see <http://www.gnu.org/licenses/>.
57
+ #
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler/setup'
7
+ rescue LoadError => e
8
+ abort e.message
9
+ end
10
+
11
+ require 'rake'
12
+
13
+ task :default => :test
14
+
15
+ require 'rubygems/tasks'
16
+ Gem::Tasks.new
17
+
18
+ require 'rake/testtask'
19
+ Rake::TestTask.new do |test|
20
+ test.libs << 'test'
21
+ test.pattern = 'test/**/test_*.rb'
22
+ test.verbose = true
23
+ end
24
+ task :test => ["test/fixtures/wasteland.epub"]
25
+
26
+ directory "test/fixtures"
27
+
28
+ require "open-uri"
29
+ file "test/fixtures/wasteland.epub" => "test/fixtures" do |t|
30
+ open "https://github.com/IDPF/epub3-samples/releases/download/20170606/wasteland.epub" do |f|
31
+ File.write t.name, f.read
32
+ end
33
+ end
34
+
35
+ require 'yard'
36
+ YARD::Rake::YardocTask.new
37
+ task :doc => :yard
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path(File.join(File.dirname(__FILE__),'..'))
4
+ if File.directory?(File.join(root,'.git'))
5
+ Dir.chdir(root) do
6
+ begin
7
+ require 'bundler/setup'
8
+ rescue LoadError => e
9
+ warn e.message
10
+ warn "Run `gem install bundler` to install Bundler"
11
+ exit -1
12
+ end
13
+ end
14
+ end
15
+
16
+ require "epub/directory"
17
+
18
+ def main(argv)
19
+ EPUB::Directory.run argv
20
+ end
21
+
22
+ main(ARGV)
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'epub/directory/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "epub-directory"
9
+ gem.version = EPUB::Directory::VERSION
10
+ gem.summary = %q{EPUB directory builder}
11
+ gem.description = %q{Builds EPUB directory static site from EPUB files, package documents or Web Publication manifests.}
12
+ gem.license = "AGPL"
13
+ gem.authors = ["KITAITI Makoto"]
14
+ gem.email = "KitaitiMakoto@gmail.com"
15
+ gem.homepage = "https://rubygems.org/gems/epub-directory"
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+
19
+ `git submodule --quiet foreach --recursive pwd`.split($/).each do |submodule|
20
+ submodule.sub!("#{Dir.pwd}/",'')
21
+
22
+ Dir.chdir(submodule) do
23
+ `git ls-files`.split($/).map do |subpath|
24
+ gem.files << File.join(submodule,subpath)
25
+ end
26
+ end
27
+ end
28
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
29
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
30
+ gem.require_paths = ['lib']
31
+
32
+ gem.add_development_dependency "epub-parser"
33
+ gem.add_development_dependency "tomlrb"
34
+ gem.add_development_dependency "haml"
35
+ gem.add_development_dependency "rss-opds"
36
+
37
+ gem.add_development_dependency 'bundler', '~> 1.10'
38
+ gem.add_development_dependency 'rake', '~> 10.0'
39
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
40
+ gem.add_development_dependency 'yard', '~> 0.8'
41
+ gem.add_development_dependency "test-unit"
42
+ gem.add_development_dependency "test-unit-notify"
43
+ end
@@ -0,0 +1,139 @@
1
+ require 'epub/directory/version'
2
+ require "epub/parser"
3
+ require "pathname"
4
+ require "rss/opds"
5
+ require "haml"
6
+
7
+ module EPUB
8
+ class Directory
9
+ SRC_DIR = Pathname.new("src")
10
+ DEST_DIR = Pathname.new("build")
11
+
12
+ class << self
13
+ def run(paths)
14
+ paths.each do |path|
15
+ add path
16
+ end
17
+ build
18
+ end
19
+
20
+ def add(path)
21
+ EPUB::Parser.parse(path).renditions.each do |rendition|
22
+ add_rendition rendition
23
+ end
24
+ end
25
+
26
+ def build
27
+ new.build
28
+ end
29
+
30
+ def add_rendition(rendition)
31
+ Rendition.add rendition
32
+ end
33
+ end
34
+
35
+ def build
36
+ DEST_DIR.mkpath
37
+ Pathname.glob("#{SRC_DIR}/**/*.opf").each do |opf_path|
38
+ make_destination_directory opf_path
39
+ build_opf opf_path
40
+ build_html opf_path
41
+ build_opds opf_path
42
+ end
43
+ end
44
+
45
+ def make_destination_directory(opf_path)
46
+ dest_path = opf_path.to_path.sub(SRC_DIR.to_path, DEST_DIR.to_path)
47
+ dest_path = Pathname.new(dest_path)
48
+ dest_path.dirname.mkpath
49
+ end
50
+
51
+ def build_opf(opf_path)
52
+ dest_path = opf_path.to_path.sub(SRC_DIR.to_path, DEST_DIR.to_path)
53
+ dest_path = Pathname.new(dest_path)
54
+ dest_path.write opf_path.read
55
+ end
56
+
57
+ def build_html(opf_path)
58
+ dest_path = opf_path.sub_ext(".html").to_path.sub(SRC_DIR.to_path, DEST_DIR.to_path)
59
+ dest_path = Pathname.new(dest_path)
60
+ rendition = EPUB::Parser::Publication.new(opf_path.read).parse
61
+ metadata = rendition.metadata
62
+ page_title = "Information on EPUB Rendition with Release Identifier #{metadata.release_identifier}"
63
+ template_path = File.join(__dir__, "../../templates/release-identifier.haml")
64
+ engine = Haml::Engine.new(File.read(template_path))
65
+ engine.options[:format] = :html5
66
+ dest_path.write engine.render(binding)
67
+ end
68
+
69
+ def build_opds(opf_path)
70
+ dest_path = opf_path.sub_ext(".opds").to_path.sub(SRC_DIR.to_path, DEST_DIR.to_path)
71
+ dest_path = Pathname.new(dest_path)
72
+ rendition = EPUB::Parser::Publication.new(opf_path.read).parse
73
+ opds = RSS::Maker.make("atom:entry") {|maker|
74
+ maker.items.new_item do |entry|
75
+ entry.id = rendition.metadata.release_identifier
76
+ entry.updated = rendition.metadata.modified.to_s
77
+ entry.title = rendition.metadata.title
78
+ # TODO: Filter authors by refines
79
+ rendition.metadata.creators.each do |creator|
80
+ entry.authors.new_author do |author|
81
+ author.name = creator.to_s
82
+ end
83
+ end
84
+ entry.summary = rendition.metadata.description
85
+ entry.links.new_link do |link|
86
+ link.rel = RSS::OPDS::RELATIONS["acquisition"] # TODO: Arrange by info.toml
87
+ link.href = dest_path.basename.sub_ext(".epub").to_path # TODO: Arrange by info.toml
88
+ link.type = "application/epub+zip"
89
+ end
90
+ end
91
+ }
92
+ dest_path.write opds
93
+ end
94
+
95
+ def build_json(opf_path)
96
+ raise NotImplementedError
97
+ end
98
+
99
+ class Rendition
100
+ class << self
101
+ def add(rendition)
102
+ new(rendition).add
103
+ end
104
+ end
105
+
106
+ def initialize(rendition)
107
+ @rendition = rendition
108
+ end
109
+
110
+ def add
111
+ make_source_directory
112
+ add_package_document
113
+ end
114
+
115
+ private
116
+
117
+ def book
118
+ @rendition.book
119
+ end
120
+
121
+ def source_directory
122
+ SRC_DIR/@rendition.unique_identifier.to_s
123
+ end
124
+
125
+ def source_path
126
+ source_directory/"#{@rendition.metadata.modified}.opf"
127
+ end
128
+
129
+ def make_source_directory
130
+ source_directory.mkpath
131
+ end
132
+
133
+ def add_package_document
134
+ package_xml = book.container_adapter.read(book.epub_file, @rendition.full_path.to_s)
135
+ source_path.write package_xml
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Copyright (c) 2018 KITAITI Makoto (KitaitiMakoto at gmail.com)
3
+ #
4
+ # epub-directory is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as published
6
+ # by the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # epub-directory is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with epub-directory. If not, see <http://www.gnu.org/licenses/>.
16
+ #
17
+
18
+ module EPUB
19
+ class Directory
20
+ # epub-directory version
21
+ VERSION = "0.1.0"
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ !!! 5
2
+ %meta{charset: "UTF-8"}
3
+ %title= page_title
4
+ %link{rel: "alternate", href: "#{metadata.modified}.opds", type: RSS::OPDS::TYPES["acquisition"]}
5
+ %h1= page_title
6
+ %dl
7
+ - metadata.to_h.each_pair do |prop, elems|
8
+ - case prop
9
+ - when :titles
10
+ %dt Title
11
+ %dd= elems.join(" ")
12
+ - else
13
+ %dt= prop.capitalize
14
+ - if elems.empty?
15
+ %dd N/A
16
+ - else
17
+ - elems.each do |elem|
18
+ - if elem == metadata.unique_identifier
19
+ %dd= elem.to_s + "(Unique Identifier)"
20
+ - else
21
+ %dd= elem
22
+ - metadata.primary_metas.each do |meta|
23
+ - if meta == metadata.modified
24
+ %dt Modified
25
+ %dd
26
+ %time= meta
27
+ - else
28
+ %dt= meta.property
29
+ %dd= meta
30
+ %dt EPUB Version
31
+ %dd= rendition.version
32
+ %dt OPF
33
+ %dd
34
+ %a{href: "#{metadata.modified}.opf"} #{metadata.modified}.opf
35
+ %dt OPDS Catalog Entry
36
+ %dd
37
+ %a{href: "#{metadata.modified}.opds"} #{metadata.modified}.opds
@@ -0,0 +1,54 @@
1
+ <!DOCTYPE html>
2
+ <title>Information on EPUB Rendition with Release Identifier code.google.com.epub-samples.wasteland-basic@2012-01-18T12:47:00Z</title>
3
+ <h1>Information on EPUB Rendition with Release Identifier code.google.com.epub-samples.wasteland-basic@2012-01-18T12:47:00Z</h1>
4
+ <link href='2012-01-18T12:47:00Z.opds' rel='alternative' type='application/atom+xml;profile=opds-catalog;kind=acquisition'>
5
+ <dl>
6
+ <dt>Identifiers</dt>
7
+ <dd>code.google.com.epub-samples.wasteland-basic(Unique Identifier)</dd>
8
+ <dt>Title</dt>
9
+ <dd>The Waste Land</dd>
10
+ <dt>Languages</dt>
11
+ <dd>en-US</dd>
12
+ <dt>Contributors</dt>
13
+ <dd>N/A</dd>
14
+ <dt>Coverages</dt>
15
+ <dd>N/A</dd>
16
+ <dt>Creators</dt>
17
+ <dd>T.S. Eliot</dd>
18
+ <dt>Dates</dt>
19
+ <dd>2011-09-01</dd>
20
+ <dt>Descriptions</dt>
21
+ <dd>N/A</dd>
22
+ <dt>Formats</dt>
23
+ <dd>N/A</dd>
24
+ <dt>Publishers</dt>
25
+ <dd>N/A</dd>
26
+ <dt>Relations</dt>
27
+ <dd>N/A</dd>
28
+ <dt>Rights</dt>
29
+ <dd>This work is shared with the public using the Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license.</dd>
30
+ <dt>Sources</dt>
31
+ <dd>N/A</dd>
32
+ <dt>Subjects</dt>
33
+ <dd>N/A</dd>
34
+ <dt>Types</dt>
35
+ <dd>N/A</dd>
36
+ <dt>Modified</dt>
37
+ <dd>
38
+ <time>2012-01-18T12:47:00Z</time>
39
+ </dd>
40
+ <dt>cc:attributionURL</dt>
41
+ <dd>http://code.google.com/p/epub-samples/</dd>
42
+ <dt></dt>
43
+ <dd></dd>
44
+ <dt>EPUB Version</dt>
45
+ <dd>3.0</dd>
46
+ <dt>OPF</dt>
47
+ <dd>
48
+ <a href='2012-01-18T12:47:00Z.opf'>2012-01-18T12:47:00Z.opf</a>
49
+ </dd>
50
+ <dt>OPDS Catalog Entry</dt>
51
+ <dd>
52
+ <a href='2012-01-18T12:47:00Z.opds'>2012-01-18T12:47:00Z.opds</a>
53
+ </dd>
54
+ </dl>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <entry xmlns="http://www.w3.org/2005/Atom"
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ xmlns:dcterms="http://purl.org/dc/terms/"
5
+ xmlns:fh="http://purl.org/syndication/history/1.0"
6
+ xmlns:opds="http://opds-spec.org/2010/catalog">
7
+ <author>
8
+ <name>T.S. Eliot</name>
9
+ </author>
10
+ <id>code.google.com.epub-samples.wasteland-basic@2012-01-18T12:47:00Z</id>
11
+ <link href="2012-01-18T12:47:00Z.epub"
12
+ rel="http://opds-spec.org/acquisition"
13
+ type="application/epub+zip"/>
14
+ <summary></summary>
15
+ <title>The Waste Land</title>
16
+ <updated>2012-01-18T12:47:00Z</updated>
17
+ <dc:date>2012-01-18T12:47:00Z</dc:date>
18
+ <dcterms:date>2012-01-18T12:47:00Z</dcterms:date>
19
+ </entry>