kindler 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,19 @@
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
+ kindler_generated*
19
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :development, :test do
4
+ gem 'rspec'
5
+ # Testing infrastructure
6
+ gem 'guard'
7
+ gem 'guard-rspec'
8
+
9
+ if RUBY_PLATFORM =~ /darwin/
10
+ # OS X integration
11
+ gem "ruby_gntp"
12
+ gem "rb-fsevent", "~> 0.4.3.1"
13
+ end
14
+ end
15
+
16
+ gem "ruby-readability",:git=>'https://github.com/iterationlabs/ruby-readability.git', :require => 'readability'
17
+ gem 'mini_magick'
18
+
19
+ # Specify your gem's dependencies in kindler.gemspec
20
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+ guard 'rspec', :version => 2 do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ end
8
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/Readme.md ADDED
@@ -0,0 +1,26 @@
1
+ ### Todo
2
+ 1.show images within page
3
+ 2.support magzine like format
4
+
5
+ ### A kindle mobi book generator
6
+ which receive a couple of urls then output one mobi file
7
+
8
+ ### Command Line Use [Todo]
9
+ kindler url1 url2 url3 url4 -o test.mobi
10
+
11
+ outputs : test.mobi
12
+
13
+ ### Api use
14
+ ```ruby
15
+ # generate my book
16
+ book = Kindler::Book.new ({:urls=>["http://blog.farmostwood.net/643.html",
17
+ "http://www.ifanr.com/69878","http://www.oneplus.info/archives/455"],
18
+ :title=>'Test_book',:author=>'mike'})
19
+ # you will get my_book.mobi file
20
+ book.generate 'my_book'
21
+ ```
22
+
23
+
24
+ Hope you love it !
25
+
26
+
data/kindler.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/kindler/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["dongbin.li"]
6
+ gem.email = ["mike.d.1984@gmail.com"]
7
+ gem.description = %q{a simple gem to generate kindle mobi book}
8
+ gem.summary = %q{a simple gem to generate kindle mobi book}
9
+ gem.homepage = "https://github.com/29decibel/kindler"
10
+
11
+ gem.rubyforge_project = "kindler"
12
+ gem.add_dependency 'mini_magick'
13
+ gem.add_dependency 'ruby-readability'
14
+
15
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ gem.files = `git ls-files`.split("\n")
17
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ gem.name = "kindler"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = Kindler::VERSION
21
+ end
@@ -0,0 +1,7 @@
1
+ module Kindler
2
+ module HtmlGenerator
3
+ def g_html
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Kindler
2
+ class Railtie < Rails::Railtie
3
+ config.after_initialize do
4
+ # do nothing
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Kindler
2
+ module TocGenerator
3
+ def g_toc
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Kindler
2
+ VERSION = "0.0.1"
3
+ end
data/lib/kindler.rb ADDED
@@ -0,0 +1,254 @@
1
+ require "kindler/version"
2
+ require "readability"
3
+ require "open-uri"
4
+ # require 'mini_magick'
5
+ require 'kindler/railtie' if defined?(Rails)
6
+
7
+ module Kindler
8
+ class Book
9
+ class KindlerError < StandardError;end
10
+ attr_accessor :urls,:title,:author
11
+ TMP_DIR = 'kindler_generated_mobi'
12
+
13
+ # availabel options
14
+ # @param options [Hash]
15
+ # @option urls [Array] urls to generate
16
+ # @option title [String] book title
17
+ # @option output_dir [String] directory want to generate
18
+ def initialize(options={})
19
+ @urls = options[:urls] || {}
20
+ @title = options[:title] || ''
21
+ @output_dir = options[:output_dir] || './'
22
+ raise KindlerError.new("urls option could not be empty") if @urls.empty?
23
+ @author = options[:author] || ''
24
+ @doc_infos = {}
25
+ # init doc infos by url
26
+ @urls.each {|url| @doc_infos[url]= {} }
27
+ end
28
+
29
+ # add url to book
30
+ # @param url [String] url to add to book
31
+ # @param options [Hash]
32
+ # @option section [Symbol] indicate which section the url belongs to,if not empty the book will be generated with magzine style
33
+ def add_url(url,options={})
34
+ return if @doc_infos[url]
35
+ @urls << url
36
+ @doc_infos[url] = {}
37
+ end
38
+
39
+ # generate books by given urls
40
+ def generate(title='')
41
+ make_generated_dirs
42
+ # generate
43
+ generate_html
44
+ generate_toc
45
+ generate_opf
46
+ generate_ncx
47
+ kindlegen
48
+ # clear
49
+ end
50
+
51
+ # check mobi file is generated already
52
+ def mobi_generated?
53
+ File.exist? "#{tmp_dir}/#{@title}.mobi"
54
+ end
55
+
56
+ private
57
+ # make sure kindlegen is installed
58
+ # you can use "sudo brew install " to install it
59
+ def kindlegen
60
+ puts 'begin generate mobi'
61
+ system("kindlegen #{tmp_dir}/#{@title}.opf ")
62
+ end
63
+
64
+ def generate_toc
65
+ contents = <<-CODE
66
+ <html>
67
+ <head>
68
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
69
+ <title>Table of Contents</title>
70
+ </head>
71
+ <body>
72
+ <h1>Contents</h1>
73
+ <h4>Main section</h4>
74
+ <ul>
75
+ CODE
76
+ files_count = 1
77
+ @doc_infos.each do |url,infos|
78
+ contents << "<li><a href='#{files_count.to_s.rjust(3,'0')}.html'>#{infos[:title]}</a></li>"
79
+ files_count += 1
80
+ end
81
+ # append footer
82
+ contents << "</ul></body></html>"
83
+ File.open(file_path('contents'),'w') do |f|
84
+ f.puts contents
85
+ end
86
+ end
87
+
88
+ # generate ncx , which is navigation
89
+ def generate_ncx
90
+ contents = <<-NCX
91
+ <?xml version="1.0" encoding="UTF-8"?>
92
+ <!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">
93
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en-US">
94
+ <head>
95
+ <meta name="dtb:uid" content="#{@title}"/>
96
+ <meta name="dtb:depth" content="1"/>
97
+ <meta name="dtb:totalPageCount" content="0"/>
98
+ <meta name="dtb:maxPageNumber" content="0"/>
99
+ </head>
100
+ <docTitle>
101
+ <text>#{@title}</text>
102
+ </docTitle>
103
+ <docAuthor>
104
+ <text>#{@author}</text>
105
+ </docAuthor>
106
+ <navMap>
107
+ NCX
108
+ # this navPoint seems not useful
109
+ # contents << <<-NAV
110
+ # <navPoint id="navpoint-1" playOrder="1">
111
+ # <navLabel><text>Table Of Contents</text></navLabel>
112
+ # <content src="contents.html"/>
113
+ # </navPoint>
114
+ # NAV
115
+ ####################### periodocal , magzine like format #########################
116
+ # <navPoint playOrder="0" class="periodical" id="periodical">
117
+ # <mbp:meta-img src="masthead.gif" name="mastheadImage"/>
118
+ # <navLabel>
119
+ # <text>Table of Contents</text>
120
+ # </navLabel>
121
+ # <content src="contents.html"/>
122
+ # <navPoint playOrder="1" class="section" id="Main-section">
123
+ # <navLabel>
124
+ # <text>Main section</text>
125
+ # </navLabel>
126
+ # <content src="001.html"/>
127
+ # <navPoint playOrder="2" class="article" id="item-001">
128
+ # <navLabel>
129
+ # <text>Nick Clegg and David Cameron agree key changes on NHS plans</text>
130
+ # </navLabel>
131
+ # <content src="001.html"/>
132
+ # <mbp:meta name="description">Deputy PM tells Andrew Marr show that GPs should not be forced to sign up to new commissioning consortiums</mbp:meta>
133
+ # <mbp:meta name="author">Nicholas Watt and Denis Campbell</mbp:meta>
134
+ # </navPoint>
135
+ # ####################################################################################
136
+ files_count = 2
137
+ @doc_infos.each do |url,infos|
138
+ nav_point = <<-NAV
139
+ <navPoint id="navpoint-#{files_count}" playOrder="#{files_count}">
140
+ <navLabel><text>#{infos[:title]}</text></navLabel>
141
+ <content src="#{(files_count-1).to_s.rjust(3,'0')}.html"/>
142
+ </navPoint>
143
+ NAV
144
+ contents << nav_point
145
+ files_count += 1
146
+ end
147
+ contents << "</navMap></ncx>"
148
+ File.open("#{tmp_dir}/nav-contents.ncx",'w') { |f| f.puts contents }
149
+ end
150
+
151
+ # generate the opf, manifest of book,including all articles and images and css
152
+ def generate_opf
153
+ # mark mobi as magzine format
154
+ # <x-metadata>
155
+ # <output content-type="application/x-mobipocket-subscription-magazine" encoding="utf-8"/>
156
+ # </x-metadata>
157
+ contents = <<-HTML
158
+ <?xml version='1.0' encoding='utf-8'?>
159
+ <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="#{@title}">
160
+ <metadata>
161
+ <dc-metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
162
+ <dc:title>#{@title}</dc:title>
163
+ <dc:language>en-gb</dc:language>
164
+ <meta content="cover-image" name="cover"/>
165
+ <dc:creator>Kindler- 29decibel</dc:creator>
166
+ <dc:publisher>Kindler- 29decibel</dc:publisher>
167
+ <dc:subject>News</dc:subject>
168
+ <dc:identifier id="#{@title}">#{@title}</dc:identifier>
169
+ <dc:date>#{Time.now.to_date}/dc:date>
170
+ <dc:description>Kindler generated book</dc:description>
171
+ </dc-metadata>
172
+ </metadata>
173
+ <manifest>
174
+ HTML
175
+ files_count = 1
176
+ @doc_infos.each do |url,infos|
177
+ doc_id = files_count.to_s.rjust(3,'0')
178
+ contents << "<item href='#{doc_id}.html' media-type='application/xhtml+xml' id='#{doc_id}'/>"
179
+ files_count += 1
180
+ end
181
+ contents << "<item href='contents.html' media-type='application/xhtml+xml' id='contents'/>"
182
+ contents << "<item href='nav-contents.ncx' media-type='application/x-dtbncx+xml' id='nav-contents'/>"
183
+ contents << "</manifest>"
184
+ contents << "<spine toc='nav-contents'>"
185
+ contents << "<itemref idref='contents'/>"
186
+ files_count = 1
187
+ @doc_infos.each do |url,infos|
188
+ contents << "<itemref idref='#{files_count.to_s.rjust(3,'0')}'/>"
189
+ files_count += 1
190
+ end
191
+ contents << "</spine><guide><reference href='contents.html' type='toc' title='Table of Contents'/></guide></package>"
192
+ File.open("#{tmp_dir}/#{@title}.opf",'w') {|f| f.puts contents}
193
+ end
194
+
195
+ # generate every url to article in readable format
196
+ def generate_html
197
+ @doc_infos.each do |url,infos|
198
+ article = readable_article(url)
199
+ # puts article.images
200
+ infos[:content] = html_wrap(article.title,article.content)
201
+ infos[:title] = article.title
202
+ end
203
+ # make html files
204
+ files_count = 1
205
+ @doc_infos.each do |url,infos|
206
+ File.open(file_path(files_count.to_s.rjust(3,'0')),'w') do |f|
207
+ f.puts infos[:content]
208
+ end
209
+ files_count += 1
210
+ end
211
+ end
212
+
213
+ # html file path
214
+ def file_path(file_name)
215
+ "#{tmp_dir}/#{file_name}.html"
216
+ end
217
+
218
+ # wrap readable contents with in html format
219
+ def html_wrap(title,content)
220
+ result = ''
221
+ result << '<html><head>'
222
+ result << "<meta content='text/html; charset=utf-8' http-equiv='Content-Type'/>"
223
+ result << '</head><body>'
224
+ result << "<h3>#{title}</h3>"
225
+ result << content
226
+ result << '</body></html>'
227
+ end
228
+
229
+ # get readable document by url, using ruby-readability here
230
+ def readable_article(url)
231
+ puts "begin fetch url : #{url}"
232
+ source = open(url).read
233
+ Readability::Document.new(source)
234
+ end
235
+
236
+ # the dir path to generated files
237
+ def tmp_dir
238
+ File.join @output_dir,"#{TMP_DIR}_#{@title.gsub(' ','_')}"
239
+ end
240
+
241
+ # create dirs of generated files
242
+ def make_generated_dirs
243
+ FileUtils.rm_rf tmp_dir if File.exist?(tmp_dir)
244
+ FileUtils.mkdir_p tmp_dir unless File.exist?(tmp_dir)
245
+ end
246
+
247
+ # exist to clear tmp files such as ncx,opf or html other than mobi file
248
+ # keep them right now
249
+ def clear_tmp_dirs
250
+
251
+ end
252
+
253
+ end
254
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ describe "Mobi html file generator" do
3
+
4
+ it "should generate html files by urls" do
5
+ title = "Test_book"
6
+ book = Kindler::Book.new ({:urls=>["http://blog.farmostwood.net/643.html",
7
+ "http://www.ifanr.com/69878","http://www.oneplus.info/archives/455"],
8
+ :title=>title,:author=>'mike'})
9
+ book.generate
10
+ File.exist?(mobi_book_path(title)).should == true
11
+ end
12
+
13
+
14
+ it "should generate hacker news book" do
15
+ title = 'haker_news'
16
+ urls = []
17
+ urls << "http://jseliger.com/2010/09/26/how-universities-work-or-what-i-wish-i%E2%80%99d-known-freshman-year-a-guide-to-american-university-life-for-the-uninitiated/"
18
+ urls << "http://randykepple.com/photoblog/2010/10/8-bad-habits-that-crush-your-creativity-and-stifle-your-success/"
19
+ urls << "http://nathanmarz.com/blog/how-to-get-a-job-at-a-kick-ass-startup-for-programmers.html"
20
+ urls << "http://tumblr.intranation.com/post/766290565/how-set-up-your-own-private-git-server-linux"
21
+ urls << "http://antirez.com/post/what-is-wrong-with-2006-programming.html"
22
+ urls << "http://fak3r.com/2009/09/14/howto-build-your-own-open-source-dropbox-clone/"
23
+ book = Kindler::Book.new :urls=>urls,:title=>title,:author=>'mike'
24
+ book.generate
25
+ File.exist?(mobi_book_path(title)).should == true
26
+ end
27
+
28
+ it "should generate book and infos on output_dir" do
29
+ title = 'my_dir_book'
30
+ urls = []
31
+ urls << "http://www.wowsai.com/home/space.php?uid=1&do=blog&id=4362&classid=2"
32
+ urls << "http://www.honeykennedy.com/2012/01/miss-moss-love-letters/"
33
+ urls << "http://www.mysenz.com/?p=3692"
34
+ book = Kindler::Book.new :urls=>urls,:title=>title,:author=>'mike',:output_dir=>'/Users/lidongbin/projects'
35
+ book.generate
36
+ File.exist?(mobi_book_path(title,'/Users/lidongbin/projects')).should == true
37
+ end
38
+
39
+ def mobi_book_path(title,output_dir='.')
40
+ File.join(output_dir,"kindler_generated_mobi_#{title}/#{title}.mobi")
41
+ end
42
+
43
+ end
@@ -0,0 +1,7 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'Although not required, bundler is recommended for running the tests.'
5
+ end
6
+
7
+ require 'kindler'
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kindler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - dongbin.li
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mini_magick
16
+ requirement: &2162549440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2162549440
25
+ - !ruby/object:Gem::Dependency
26
+ name: ruby-readability
27
+ requirement: &2162549020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2162549020
36
+ description: a simple gem to generate kindle mobi book
37
+ email:
38
+ - mike.d.1984@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - Guardfile
46
+ - Rakefile
47
+ - Readme.md
48
+ - kindler.gemspec
49
+ - lib/kindler.rb
50
+ - lib/kindler/html_generator.rb
51
+ - lib/kindler/railtie.rb
52
+ - lib/kindler/toc_generator.rb
53
+ - lib/kindler/version.rb
54
+ - spec/cases/generator_spec.rb
55
+ - spec/spec_helper.rb
56
+ homepage: https://github.com/29decibel/kindler
57
+ licenses: []
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project: kindler
76
+ rubygems_version: 1.8.11
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: a simple gem to generate kindle mobi book
80
+ test_files:
81
+ - spec/cases/generator_spec.rb
82
+ - spec/spec_helper.rb
83
+ has_rdoc: