ebook_generator 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d00c5f445bb58f02fd5421fbc9f449b2fc8ad45
4
+ data.tar.gz: f56981f51e890a4fb2d6d5762731fb4be0df7586
5
+ SHA512:
6
+ metadata.gz: b217a3d82a044ee065111b94aa9ada5e86b5087348c35659b5b9a93898d45a4cba34aab3d30881c09756974789d736435ee1642847209f17d5c6769e37593a19
7
+ data.tar.gz: f0ef7a57ca03587fd3dd8c4343bb53900158339d7674d80b1f501c6a875320d2a37a717cf1733134215ee9545e8dfda1eb278be198477c0893be7a782dc0993d
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Changelog.md ADDED
@@ -0,0 +1,10 @@
1
+ # EbookGenerator Changelog
2
+
3
+ ## 0.0.2 (2014-04-18)
4
+
5
+ - Fixed bug where the methods could not be accessed
6
+
7
+ ## 0.0.1 (2014-04-17)
8
+
9
+ - Added db migrations
10
+ - Added generate ePub class
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Kris Quigley
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # EbookGenerator
2
+
3
+ Rails gem to generate eBooks using the Markdown syntax to format content for sections of the book.
4
+
5
+ An example of this gem being used can be found at: [ebook-generator.affinity-tech.com](http://ebook-generator.affinity-tech.com)
6
+
7
+ Requires:
8
+ - Postgres with UUID support (uses the id to generate the ebook UUID)
9
+ - Rubyzip (to generate the .epub)
10
+ - Redcarpet (to render Markdown into HTML)
11
+ - Friendly_id (for nice slugs and for naming of generated ebook file)
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'ebook_generator'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install ebook_generator
26
+
27
+ ## Usage
28
+
29
+ Generate the tables needed to process the ebooks:
30
+
31
+ `rails generate ebook_generator`
32
+
33
+ Migrate the db:
34
+
35
+ `rake db:migrate`
36
+
37
+ Require the ebook_generator module in your class:
38
+
39
+ `include 'EbookGenerator'`
40
+
41
+ Pass the id for the ebook you want to generate:
42
+
43
+ `EbookGenerator.generate_ebook(ebook.id)`
44
+
45
+ This will then generate an ebook based on the values in the db in the /tmp folder.
46
+
47
+ ## Feature roadmap
48
+
49
+ ### 0.1.0
50
+ - Kindle support
51
+ - Tests
52
+
53
+ ### 0.2.0
54
+ - Style editing
55
+
56
+ ### 0.3.0
57
+ - PDF out
58
+
59
+ ### 0.4.0
60
+ - HTML out
61
+ - Image support for the front cover
62
+
63
+ ### 0.5.0
64
+ - HTML to eBook conversion
65
+
66
+ ### 0.6.0
67
+ - User membership to manage books
68
+
69
+ Publishing support?
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it ( https://github.com/[my-github-username]/ebook_generator/fork )
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ebook_generator/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'ebook_generator'
7
+ s.version = EbookGenerator::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = "Generates eBooks"
10
+ s.description = "A simple eBook (ePub) generator gem"
11
+ s.authors = ["Kris Quigley"]
12
+ s.email = 'kris@krisquigley.co.uk'
13
+ s.homepage =
14
+ 'https://github.com/krisquigley/ebook_generator'
15
+
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.license = 'MIT'
23
+ end
@@ -0,0 +1,5 @@
1
+ # Nothing needed here at this time
2
+
3
+ EbookGenerator.defaults do |config|
4
+
5
+ end
@@ -0,0 +1,30 @@
1
+ class CreateEbookGeneratorTables < ActiveRecord::Migration
2
+ def change
3
+ enable_extension 'uuid-ossp'
4
+
5
+ create_table :ebooks, id: :uuid, default: "uuid_generate_v4()" do |t|
6
+ t.string "title", null: false
7
+ t.string "creator"
8
+ t.string "language", limit: 2
9
+ t.string "contributor"
10
+ t.text "description"
11
+ t.string "publisher"
12
+ t.text "rights"
13
+ t.string "subject"
14
+ t.datetime "created_at"
15
+ t.datetime "updated_at"
16
+ end
17
+
18
+ create_table "sections", force: true do |t|
19
+ t.string "title", null: false
20
+ t.text "content", null: false
21
+ t.uuid "ebook_id", null: false
22
+ t.integer "position", null: false
23
+ t.datetime "created_at"
24
+ t.datetime "updated_at"
25
+ end
26
+
27
+ add_index "sections", ["ebook_id"], name: "index_sections_on_ebook_id", using: :btree
28
+ add_index "sections", ["position"], name: "index_sections_on_position", using: :btree
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module EbookGenerator
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,208 @@
1
+ require "ebook_generator/version"
2
+
3
+ module EbookGenerator
4
+
5
+ def self.included(model_class)
6
+ model_class.extend self
7
+ end
8
+
9
+ # Move writing of files into its own class that accepts an array
10
+ def self.make_dir(path)
11
+ Dir.mkdir(path, 0777) unless File.exists?(path)
12
+ end
13
+
14
+ def self.initialise_files(path)
15
+ metainf_path = path + "/META-INF"
16
+
17
+ Dir.mkdir(metainf_path) unless File.exists?(metainf_path)
18
+
19
+ metainf = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
20
+ <container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">
21
+ <rootfiles>
22
+ <rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>
23
+ </rootfiles>
24
+ </container>"
25
+
26
+ File.open(metainf_path + "/container.xml", "w+") do |f|
27
+ f.write(metainf)
28
+ end
29
+
30
+ mimetype = "application/epub+zip"
31
+ mimetype_path = path + "/mimetype"
32
+
33
+ File.open(mimetype_path, "w+") do |f|
34
+ f.write(mimetype)
35
+ end
36
+
37
+ FileUtils.chmod 0755, mimetype_path
38
+
39
+ content_path = path + "/OEBPS"
40
+
41
+ Dir.mkdir(content_path) unless File.exists?(content_path)
42
+
43
+ Dir.mkdir(content_path + "/Text") unless File.exists?(content_path + "/Text")
44
+
45
+ Dir.mkdir(content_path + "/Styles") unless File.exists?(content_path + "/Styles")
46
+
47
+ root = Rails.root.to_s
48
+
49
+ FileUtils.cp "#{root}/app/ebook/style.css", content_path+"/Styles"
50
+
51
+ return content_path
52
+
53
+ end
54
+
55
+ def self.generate_headers(attrs)
56
+ xml = "<title>#{attrs.title}</title>
57
+ <meta content=\"#{attrs.title}\" name=\"Title\" />
58
+ <meta content=\"#{attrs.title}\" name=\"Author\" />
59
+ <link href=\"../Styles/style.css\" rel=\"stylesheet\" type=\"text/css\" />"
60
+ return xml
61
+ end
62
+
63
+ def self.generate_sections(path, attrs)
64
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
65
+ headers = generate_headers(attrs)
66
+
67
+ attrs.sections.each do |section|
68
+ xml = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>
69
+ <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"
70
+ \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">
71
+ <html xmlns=\"http://www.w3.org/1999/xhtml\">
72
+ <head>
73
+ #{headers}
74
+ </head>
75
+ <body>
76
+ <div id=\"#{section.title}\">
77
+ "
78
+ xml += markdown.render(section.content)
79
+ xml += "
80
+ </div>
81
+ </body>
82
+ </html>"
83
+
84
+ File.open(path + "/Section#{section.position}.html", "w+") do |f|
85
+ f.write(xml)
86
+ end
87
+ end
88
+ end
89
+
90
+ def self.generate_content_opf(path, attrs)
91
+ xml = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>
92
+ <package xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"BookId\" version=\"2.0\">
93
+ <metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\">
94
+ <dc:identifier id=\"BookId\" opf:scheme=\"UUID\">#{attrs.id}</dc:identifier>
95
+ <dc:title>#{attrs.title}</dc:title>
96
+ <dc:creator opf:role=\"aut\">#{attrs.creator}</dc:creator>
97
+ <dc:language>#{attrs.language}</dc:language>
98
+ <dc:date opf:event=\"modification\">#{attrs.updated_at}</dc:date>
99
+ <dc:description>#{attrs.description}</dc:description>
100
+ <dc:publisher>#{attrs.publisher}</dc:publisher>
101
+ <dc:rights>#{attrs.rights}</dc:rights>
102
+ <dc:subject>#{attrs.subject}</dc:subject>
103
+ <dc:contributor opf:role=\"cov\">#{attrs.contributor}</dc:contributor>
104
+ <meta content=\"0.7.2\" name=\"Sigil version\" />
105
+ </metadata>
106
+ <manifest>
107
+ <item href=\"toc.ncx\" id=\"ncx\" media-type=\"application/x-dtbncx+xml\" />
108
+ <item href=\"Styles/style.css\" id=\"style.css\" media-type=\"text/css\" />"
109
+
110
+ attrs.sections.each do |section|
111
+ xml += "<item href=\"Text/Section#{section.position}.html\" id=\"Section#{section.position}.html\" media-type=\"application/xhtml+xml\" />"
112
+ end
113
+
114
+ xml += "<item href=\"Fonts/junicode-italic-webfont.ttf\" id=\"junicode-italic-webfont.ttf\" media-type=\"application/x-font-ttf\" />
115
+ <item href=\"Fonts/junicode-webfont.ttf\" id=\"junicode-webfont.ttf\" media-type=\"application/x-font-ttf\" />
116
+ <item href=\"Fonts/junicode-bold-webfont.ttf\" id=\"junicode-bold-webfont.ttf\" media-type=\"application/x-font-ttf\" />
117
+ </manifest>
118
+ <spine toc=\"ncx\">"
119
+
120
+ attrs.sections.each do |section|
121
+ xml += "<itemref idref=\"Section#{section.position}.html\" />"
122
+
123
+ end
124
+ xml += "</spine>
125
+ <guide />
126
+ </package>"
127
+
128
+ content_path = path + "/content.opf"
129
+
130
+ File.open(content_path, "w+") do |f|
131
+ f.write(xml)
132
+ end
133
+
134
+ FileUtils.chmod 0755, content_path
135
+
136
+ end
137
+
138
+ def self.generate_toc_ncx(path, attrs)
139
+ xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>
140
+ <!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\"
141
+ \"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">
142
+ <ncx xmlns=\"http://www.daisy.org/z3986/2005/ncx/\" version=\"2005-1\">
143
+ <head>
144
+ <meta content=\"urn:uuid:${attrs.id}\" name=\"dtb:uid\"/>
145
+ <meta content=\"2\" name=\"dtb:depth\"/>
146
+ <meta content=\"0\" name=\"dtb:totalPageCount\"/>
147
+ <meta content=\"0\" name=\"dtb:maxPageNumber\"/>
148
+ </head>
149
+ <docTitle>
150
+ <text>#{attrs.title}</text>
151
+ </docTitle>
152
+ <navMap>"
153
+
154
+
155
+ attrs.sections.each do |section|
156
+ xml += "<navPoint id=\"navPoint-#{section.position}\" playOrder=\"#{section.position}\">
157
+ <navLabel>
158
+ <text>#{section.title}</text>
159
+ </navLabel>
160
+ <content src=\"Text/Section#{section.position}.html\"/>
161
+ </navPoint>"
162
+ end
163
+
164
+ xml += "</navMap>
165
+ </ncx>"
166
+
167
+ toc_path = path + "/toc.ncx"
168
+
169
+ File.open(toc_path, "w+") do |f|
170
+ f.write(xml)
171
+ end
172
+
173
+ FileUtils.chmod 0755, toc_path
174
+ end
175
+
176
+ def self.remove_tmp_dir(directory)
177
+ FileUtils.remove_dir(directory, true)
178
+ end
179
+
180
+ def self.generate_ebook(ebook_id)
181
+
182
+ # create tmp directory based on UUID
183
+ path = Rails.root.join "tmp/#{ebook_id}"
184
+ make_dir(path.to_s)
185
+
186
+ # set up required files and dirs
187
+ content_path = initialise_files(path.to_s)
188
+
189
+ # loop through each section loading the reference header and saving as it's own section
190
+ attrs = Ebook.find(ebook_id)
191
+ generate_sections(content_path + "/Text", attrs)
192
+
193
+ # generate toc based on the number of sections generated
194
+ generate_content_opf(content_path, attrs)
195
+ generate_toc_ncx(content_path, attrs)
196
+
197
+ # zip all files
198
+ zipfile_name = Rails.root.to_s + "/tmp/" + attrs.slug + ".epub"
199
+
200
+ zf = ZipFileProcessor.new(path.to_s, zipfile_name)
201
+ zf.write
202
+
203
+ # Clean up the tmp dir
204
+ remove_tmp_dir(path.to_s + "/")
205
+
206
+ end
207
+
208
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+ require "rails/generators/active_record"
3
+
4
+ class EbookGeneratorGenerator < ActiveRecord::Generators::Base
5
+ argument :name, type: :string, default: 'random_name'
6
+
7
+ source_root File.expand_path('../../ebook_generator', __FILE__)
8
+
9
+ # Copies the migration template to db/migrate.
10
+ def copy_files
11
+ migration_template 'migration.rb', 'db/migrate/create_ebook_generator_tables.rb'
12
+ end
13
+
14
+ def create_initializer
15
+ copy_file 'initializer.rb', 'config/initializers/ebook_generator.rb'
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ebook_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Kris Quigley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-18 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple eBook (ePub) generator gem
14
+ email: kris@krisquigley.co.uk
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - .gitignore
20
+ - Changelog.md
21
+ - Gemfile
22
+ - LICENSE.txt
23
+ - README.md
24
+ - Rakefile
25
+ - ebook_generator.gemspec
26
+ - lib/ebook_generator.rb
27
+ - lib/ebook_generator/initializer.rb
28
+ - lib/ebook_generator/migration.rb
29
+ - lib/ebook_generator/version.rb
30
+ - lib/generators/ebook_generator_generator.rb
31
+ homepage: https://github.com/krisquigley/ebook_generator
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.1.11
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Generates eBooks
55
+ test_files: []