klipbook 2.1.3 → 3.0.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.
- checksums.yaml +4 -4
- data/.gitignore +9 -0
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/CHANGELOG.txt +11 -0
- data/Gemfile +2 -15
- data/Gemfile.lock +73 -113
- data/LICENSE.txt +18 -17
- data/README.md +63 -69
- data/Rakefile +3 -30
- data/bin/klipbook +3 -221
- data/klipbook.gemspec +32 -118
- data/lib/klipbook/cli.rb +69 -0
- data/lib/klipbook/commands/command.rb +39 -0
- data/lib/klipbook/commands/export.rb +50 -0
- data/lib/klipbook/commands/exporters/exporter.rb +49 -0
- data/lib/klipbook/{tohtml → commands/exporters}/html_book_summary.erb +1 -1
- data/lib/klipbook/commands/exporters/html_exporter.rb +25 -0
- data/lib/klipbook/commands/exporters/json_exporter.rb +17 -0
- data/lib/klipbook/commands/exporters/markdown_book_summary.erb +12 -0
- data/lib/klipbook/commands/exporters/markdown_exporter.rb +19 -0
- data/lib/klipbook/commands/list.rb +17 -0
- data/lib/klipbook/config.rb +18 -10
- data/lib/klipbook/logger.rb +15 -0
- data/lib/klipbook/sources/amazon_site/book_scraper.rb +0 -2
- data/lib/klipbook/sources/book.rb +36 -21
- data/lib/klipbook/sources/clipping.rb +10 -8
- data/lib/klipbook/sources/kindle_device/entry.rb +8 -6
- data/lib/klipbook/sources/kindle_device/entry_parser.rb +66 -64
- data/lib/klipbook/sources/kindle_device/file.rb +45 -43
- data/lib/klipbook/sources/kindle_device/file_parser.rb +23 -21
- data/lib/klipbook/sources/source.rb +30 -0
- data/lib/klipbook/version.rb +1 -1
- data/lib/klipbook.rb +11 -11
- metadata +56 -113
- data/.document +0 -5
- data/.yardopts +0 -1
- data/Guardfile +0 -19
- data/features/fixtures/clippings-for-three-books.txt +0 -105
- data/features/list.feature +0 -31
- data/features/step_definitions/list_steps.rb +0 -15
- data/features/step_definitions/tohtml_steps.rb +0 -61
- data/features/step_definitions/tojson_steps.rb +0 -17
- data/features/support/env.rb +0 -16
- data/features/tohtml.feature +0 -51
- data/features/tojson.feature +0 -11
- data/lib/klipbook/colours.rb +0 -16
- data/lib/klipbook/commands/list_books.rb +0 -19
- data/lib/klipbook/commands/tohtml.rb +0 -17
- data/lib/klipbook/commands/tojson.rb +0 -18
- data/lib/klipbook/sources/invalid_source_error.rb +0 -12
- data/lib/klipbook/tohtml/html_printer.rb +0 -39
- data/lib/klipbook/tojson/book_file.rb +0 -58
- data/spec/lib/klipbook/commands/list_books_spec.rb +0 -43
- data/spec/lib/klipbook/commands/tohtml_spec.rb +0 -36
- data/spec/lib/klipbook/sources/book_spec.rb +0 -33
- data/spec/lib/klipbook/sources/kindle_device/entry_parser_spec.rb +0 -339
- data/spec/lib/klipbook/sources/kindle_device/file_parser_spec.rb +0 -68
- data/spec/lib/klipbook/sources/kindle_device/file_spec.rb +0 -163
- data/spec/lib/klipbook/tohtml/html_printer_spec.rb +0 -88
- data/spec/lib/klipbook/tojson/book_file_spec.rb +0 -76
- data/spec/spec_helper.rb +0 -7
data/bin/klipbook
CHANGED
@@ -1,224 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'klipbook'
|
6
|
-
require 'slop'
|
7
|
-
|
8
|
-
##########
|
9
|
-
# Helpers
|
10
|
-
##########
|
11
|
-
|
12
|
-
def get_book_source(opts)
|
13
|
-
exit_unless_valid_source(opts)
|
14
|
-
|
15
|
-
max_books = opts[:number].to_i
|
16
|
-
|
17
|
-
unless max_books > 0
|
18
|
-
$stderr.puts "Error: Specify a number of books greater than 0"
|
19
|
-
exit 127
|
20
|
-
end
|
21
|
-
|
22
|
-
get_file_source(infile(opts), max_books) || get_site_source(credentials(opts), max_books)
|
23
|
-
end
|
24
|
-
|
25
|
-
def exit_unless_valid_source(opts)
|
26
|
-
unless opts[:infile] || opts[:credentials] || CONFIG[:credentials]
|
27
|
-
$stderr.puts "Error: #{SOURCE_HELP}"
|
28
|
-
exit 127
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def get_site_source(creds, max_books)
|
33
|
-
return nil unless creds
|
34
|
-
|
35
|
-
unless creds =~ /(.+):(.+)/
|
36
|
-
$stderr.puts "Error: your credentials need to be in username:password format."
|
37
|
-
exit 127
|
38
|
-
end
|
39
|
-
|
40
|
-
username = $1
|
41
|
-
password = $2
|
42
|
-
Klipbook::Sources::AmazonSite::SiteScraper.new(username, password, max_books)
|
43
|
-
end
|
44
|
-
|
45
|
-
def get_file_source(file, max_books)
|
46
|
-
return nil unless file
|
47
|
-
|
48
|
-
Klipbook::Sources::KindleDevice::File.new(file, max_books)
|
49
|
-
end
|
50
|
-
|
51
|
-
def fetch_books(opts)
|
52
|
-
get_book_source(opts).books
|
53
|
-
end
|
54
|
-
|
55
|
-
def open_infile(file_path)
|
56
|
-
return nil unless file_path
|
57
|
-
|
58
|
-
unless File.exists? file_path
|
59
|
-
$stderr.puts "Error: could not open #{file_path}"
|
60
|
-
exit 127
|
61
|
-
end
|
62
|
-
|
63
|
-
File.open(file_path, "r")
|
64
|
-
end
|
65
|
-
|
66
|
-
def raw_json_from_file(file_path)
|
67
|
-
File.open(file_path, 'r') do |f|
|
68
|
-
f.read
|
69
|
-
end
|
70
|
-
rescue
|
71
|
-
""
|
72
|
-
end
|
73
|
-
|
74
|
-
def book_file(file_path)
|
75
|
-
Klipbook::ToJson::BookFile.from_json(raw_json_from_file(file_path))
|
76
|
-
end
|
77
|
-
|
78
|
-
#########
|
79
|
-
# Params
|
80
|
-
#########
|
81
|
-
|
82
|
-
def infile(opts)
|
83
|
-
open_infile(opts[:infile])
|
84
|
-
end
|
85
|
-
|
86
|
-
def credentials(opts)
|
87
|
-
puts "Using credentials from ~/.klipbookrc" if !opts[:credentials] && CONFIG[:credentials]
|
88
|
-
|
89
|
-
opts[:credentials] || CONFIG[:credentials]
|
90
|
-
end
|
91
|
-
|
92
|
-
def ensure_outfile(opts)
|
93
|
-
unless opts[:outfile] || CONFIG[:outfile]
|
94
|
-
$stderr.puts("Error: Please specify an outfile.")
|
95
|
-
exit(127)
|
96
|
-
end
|
97
|
-
|
98
|
-
outfile_path(opts)
|
99
|
-
end
|
100
|
-
|
101
|
-
def outfile_path(opts)
|
102
|
-
puts "Using outfile from ~/.klipbookrc" if !opts[:outfile] && CONFIG[:outfile]
|
103
|
-
|
104
|
-
opts[:outfile] || CONFIG[:outfile]
|
105
|
-
end
|
106
|
-
|
107
|
-
def ensure_outdir(opts)
|
108
|
-
unless opts[:outdir] || CONFIG[:outdir]
|
109
|
-
$stderr.puts("Error: Please specify an outdir.")
|
110
|
-
exit(127)
|
111
|
-
end
|
112
|
-
|
113
|
-
outdir = outdir_path(opts)
|
114
|
-
|
115
|
-
unless File.exists?(outdir)
|
116
|
-
$stderr.puts("Error: Outdir does not exist.")
|
117
|
-
exit(127)
|
118
|
-
end
|
119
|
-
|
120
|
-
outdir
|
121
|
-
end
|
122
|
-
|
123
|
-
def outdir_path(opts)
|
124
|
-
puts "Using outdir from ~/.klipbookrc" if !opts[:outdir] && CONFIG[:outdir]
|
125
|
-
|
126
|
-
opts[:outdir] || CONFIG[:outdir] || Dir.pwd
|
127
|
-
end
|
128
|
-
|
129
|
-
##########
|
130
|
-
# Go time
|
131
|
-
##########
|
132
|
-
|
133
|
-
CONFIG = Klipbook::Config.new.read
|
134
|
-
|
135
|
-
DEFAULT_MAXBOOKS=5
|
136
|
-
SOURCE_HELP = "You must specify either `--credentials` or `--infile` as an input."
|
137
|
-
|
138
|
-
CONFIG_HELP = "Note that credentials, outdir, and outfile defaults can be stored in a file called ~/.klipbookrc\n\n" +
|
139
|
-
"This file is YAML formatted e.g.\n\n" +
|
140
|
-
":credentials: my-kindle-user@blah.com:my-kindle-password\n" +
|
141
|
-
":outdir: my/default/output/directory\n" +
|
142
|
-
":outfile: my/default/output/file.json\n"
|
143
|
-
|
144
|
-
def banner_for_command(command, description)
|
145
|
-
"Usage: klipbook #{command} [options]\n\n#{description}\n\n#{SOURCE_HELP}\n"
|
146
|
-
end
|
147
|
-
|
148
|
-
opts = Slop.parse(help: true) do
|
149
|
-
banner "Usage: klipbook <command> [options]\n\n" +
|
150
|
-
"Klipbook writes the clippings you've saved on your Kindle into JSON or pretty html.\n\n" +
|
151
|
-
CONFIG_HELP + "\n"
|
152
|
-
|
153
|
-
on :v, :version, "Print the version." do
|
154
|
-
puts "Klipbook version #{Klipbook::VERSION}"
|
155
|
-
exit 0
|
156
|
-
end
|
157
|
-
|
158
|
-
command "list" do
|
159
|
-
desc = "List the books on the site or in the clippings file."
|
160
|
-
|
161
|
-
banner banner_for_command("list", desc)
|
162
|
-
|
163
|
-
description desc
|
164
|
-
|
165
|
-
on :c, :credentials=, "<username>:<password> for Kindle site"
|
166
|
-
on :i, :infile=, "Input file (default STDIN)"
|
167
|
-
on :n, :number=, "Maximum number of books to list (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
168
|
-
|
169
|
-
run do |opts, args|
|
170
|
-
books = fetch_books(opts)
|
171
|
-
Klipbook::Commands::ListBooks.new(books).call
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
command "tojson" do
|
176
|
-
desc = "Print book highlights as JSON. Note that this will update an existing JSON file in place with new entries."
|
177
|
-
|
178
|
-
banner banner_for_command("tojson", desc)
|
179
|
-
|
180
|
-
description desc
|
181
|
-
|
182
|
-
on :c, :credentials=, "<username>:<password> for Kindle site"
|
183
|
-
on :i, :infile=, "Input file (default STDIN)"
|
184
|
-
on :n, :number=, "Maximum number of books to print as json (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
185
|
-
on :o, :outfile=, "Output JSON file (default STDOUT)"
|
186
|
-
on :f, :force, "Force overwrite of any existing book entries within the output file"
|
187
|
-
|
188
|
-
run do |opts, args|
|
189
|
-
outfile_path = ensure_outfile(opts)
|
190
|
-
|
191
|
-
books = fetch_books(opts)
|
192
|
-
|
193
|
-
Klipbook::Commands::ToJson.new(books, book_file(outfile_path)).call(outfile_path, opts[:force])
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
command "tohtml" do
|
198
|
-
desc = "Print book highlights as HTML."
|
199
|
-
|
200
|
-
banner banner_for_command("tohtml", desc)
|
201
|
-
|
202
|
-
description desc
|
203
|
-
|
204
|
-
on :c, :credentials=, "<username>:<password> for Kindle site"
|
205
|
-
on :i, :infile=, "Input file (default STDIN)"
|
206
|
-
on :n, :number=, "Maximum number of books to print as html (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
207
|
-
on :o, :outdir=, "Directory to write HTML files to (default pwd)"
|
208
|
-
on :f, :force, "Force overwrite of existing files"
|
209
|
-
|
210
|
-
run do |opts, args|
|
211
|
-
books = fetch_books(opts)
|
212
|
-
|
213
|
-
outdir_path = ensure_outdir(opts)
|
214
|
-
|
215
|
-
Klipbook::Commands::ToHtml.new(books).call(outdir_path, opts[:force])
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
# Default action is to output help
|
220
|
-
run do |opts, args|
|
221
|
-
puts opts.help
|
222
|
-
end
|
223
|
-
end
|
3
|
+
require "bundler/setup"
|
4
|
+
require "klipbook"
|
224
5
|
|
6
|
+
Klipbook::CLI.new.execute!
|
data/klipbook.gemspec
CHANGED
@@ -1,124 +1,38 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
# stub: klipbook 2.1.3 ruby lib
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'klipbook/version'
|
6
5
|
|
7
|
-
Gem::Specification.new do |
|
8
|
-
|
9
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "klipbook"
|
8
|
+
spec.version = Klipbook::VERSION
|
9
|
+
spec.authors = ["Ray Grasso"]
|
10
|
+
spec.email = ["ray.grasso@gmail.com"]
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
s.description = "Process your Kindle clippings file to generate a nicely formatted compilation of the clippings of the books you've read"
|
16
|
-
s.email = "ray.grasso@gmail.com"
|
17
|
-
s.executables = ["klipbook"]
|
18
|
-
s.extra_rdoc_files = [
|
19
|
-
"LICENSE.txt",
|
20
|
-
"README.md"
|
21
|
-
]
|
22
|
-
s.files = [
|
23
|
-
".document",
|
24
|
-
".rspec",
|
25
|
-
".ruby-version",
|
26
|
-
".travis.yml",
|
27
|
-
".yardopts",
|
28
|
-
"CHANGELOG.txt",
|
29
|
-
"Gemfile",
|
30
|
-
"Gemfile.lock",
|
31
|
-
"Guardfile",
|
32
|
-
"LICENSE.txt",
|
33
|
-
"README.md",
|
34
|
-
"Rakefile",
|
35
|
-
"bin/klipbook",
|
36
|
-
"example.png",
|
37
|
-
"features/fixtures/clippings-for-three-books.txt",
|
38
|
-
"features/list.feature",
|
39
|
-
"features/step_definitions/list_steps.rb",
|
40
|
-
"features/step_definitions/tohtml_steps.rb",
|
41
|
-
"features/step_definitions/tojson_steps.rb",
|
42
|
-
"features/support/env.rb",
|
43
|
-
"features/tohtml.feature",
|
44
|
-
"features/tojson.feature",
|
45
|
-
"klipbook.gemspec",
|
46
|
-
"lib/klipbook.rb",
|
47
|
-
"lib/klipbook/colours.rb",
|
48
|
-
"lib/klipbook/commands/list_books.rb",
|
49
|
-
"lib/klipbook/commands/tohtml.rb",
|
50
|
-
"lib/klipbook/commands/tojson.rb",
|
51
|
-
"lib/klipbook/config.rb",
|
52
|
-
"lib/klipbook/sources/amazon_site/book_scraper.rb",
|
53
|
-
"lib/klipbook/sources/amazon_site/site_scraper.rb",
|
54
|
-
"lib/klipbook/sources/book.rb",
|
55
|
-
"lib/klipbook/sources/clipping.rb",
|
56
|
-
"lib/klipbook/sources/invalid_source_error.rb",
|
57
|
-
"lib/klipbook/sources/kindle_device/entry.rb",
|
58
|
-
"lib/klipbook/sources/kindle_device/entry_parser.rb",
|
59
|
-
"lib/klipbook/sources/kindle_device/file.rb",
|
60
|
-
"lib/klipbook/sources/kindle_device/file_parser.rb",
|
61
|
-
"lib/klipbook/tohtml/html_book_summary.erb",
|
62
|
-
"lib/klipbook/tohtml/html_printer.rb",
|
63
|
-
"lib/klipbook/tojson/book_file.rb",
|
64
|
-
"lib/klipbook/util/blank.rb",
|
65
|
-
"lib/klipbook/util/struct_to_json.rb",
|
66
|
-
"lib/klipbook/version.rb",
|
67
|
-
"spec/lib/klipbook/commands/list_books_spec.rb",
|
68
|
-
"spec/lib/klipbook/commands/tohtml_spec.rb",
|
69
|
-
"spec/lib/klipbook/sources/book_spec.rb",
|
70
|
-
"spec/lib/klipbook/sources/kindle_device/entry_parser_spec.rb",
|
71
|
-
"spec/lib/klipbook/sources/kindle_device/file_parser_spec.rb",
|
72
|
-
"spec/lib/klipbook/sources/kindle_device/file_spec.rb",
|
73
|
-
"spec/lib/klipbook/tohtml/html_printer_spec.rb",
|
74
|
-
"spec/lib/klipbook/tojson/book_file_spec.rb",
|
75
|
-
"spec/spec_helper.rb"
|
76
|
-
]
|
77
|
-
s.homepage = "https://github.com/grassdog/klipbook"
|
78
|
-
s.licenses = ["MIT"]
|
79
|
-
s.rubygems_version = "2.2.2"
|
80
|
-
s.summary = "Klipbook creates a nice html summary of the clippings you've created on your Kindle."
|
12
|
+
spec.summary = "Klipbook creates a nice html summary of the clippings you've created on your Kindle."
|
13
|
+
spec.description = "Process your Kindle clippings file to generate a nicely formatted compilation of the clippings of the books you've read"
|
14
|
+
spec.homepage = "https://github.com/grassdog/klipbook"
|
15
|
+
spec.license = "MIT"
|
81
16
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
s.add_runtime_dependency(%q<slop>, ["~> 3.6"])
|
87
|
-
s.add_runtime_dependency(%q<mechanize>, ["~> 2.7"])
|
88
|
-
s.add_development_dependency(%q<rspec>, ["~> 3.0"])
|
89
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
90
|
-
s.add_development_dependency(%q<pry-byebug>, ["~> 1.3"])
|
91
|
-
s.add_development_dependency(%q<cucumber>, ["~> 1.3"])
|
92
|
-
s.add_development_dependency(%q<aruba>, ["~> 0.6"])
|
93
|
-
s.add_development_dependency(%q<guard>, [">= 0"])
|
94
|
-
s.add_development_dependency(%q<guard-rspec>, ["~> 4.3"])
|
95
|
-
s.add_development_dependency(%q<guard-cucumber>, ["~> 1.4"])
|
96
|
-
s.add_development_dependency(%q<terminal-notifier-guard>, ["~> 1.5"])
|
97
|
-
else
|
98
|
-
s.add_dependency(%q<slop>, ["~> 3.6"])
|
99
|
-
s.add_dependency(%q<mechanize>, ["~> 2.7"])
|
100
|
-
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
101
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
102
|
-
s.add_dependency(%q<pry-byebug>, ["~> 1.3"])
|
103
|
-
s.add_dependency(%q<cucumber>, ["~> 1.3"])
|
104
|
-
s.add_dependency(%q<aruba>, ["~> 0.6"])
|
105
|
-
s.add_dependency(%q<guard>, [">= 0"])
|
106
|
-
s.add_dependency(%q<guard-rspec>, ["~> 4.3"])
|
107
|
-
s.add_dependency(%q<guard-cucumber>, ["~> 1.4"])
|
108
|
-
s.add_dependency(%q<terminal-notifier-guard>, ["~> 1.5"])
|
109
|
-
end
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
110
21
|
else
|
111
|
-
|
112
|
-
s.add_dependency(%q<mechanize>, ["~> 2.7"])
|
113
|
-
s.add_dependency(%q<rspec>, ["~> 3.0"])
|
114
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
115
|
-
s.add_dependency(%q<pry-byebug>, ["~> 1.3"])
|
116
|
-
s.add_dependency(%q<cucumber>, ["~> 1.3"])
|
117
|
-
s.add_dependency(%q<aruba>, ["~> 0.6"])
|
118
|
-
s.add_dependency(%q<guard>, [">= 0"])
|
119
|
-
s.add_dependency(%q<guard-rspec>, ["~> 4.3"])
|
120
|
-
s.add_dependency(%q<guard-cucumber>, ["~> 1.4"])
|
121
|
-
s.add_dependency(%q<terminal-notifier-guard>, ["~> 1.5"])
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
122
23
|
end
|
123
|
-
end
|
124
24
|
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = "bin"
|
27
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_dependency "commander"
|
31
|
+
spec.add_dependency "mechanize"
|
32
|
+
spec.add_development_dependency "bundler"
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
spec.add_development_dependency "rspec"
|
35
|
+
spec.add_development_dependency "pry-byebug"
|
36
|
+
spec.add_development_dependency "cucumber"
|
37
|
+
spec.add_development_dependency "aruba"
|
38
|
+
end
|
data/lib/klipbook/cli.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require "commander"
|
2
|
+
|
3
|
+
module Klipbook
|
4
|
+
class CLI
|
5
|
+
include Commander::Methods
|
6
|
+
|
7
|
+
def initialize(config=Klipbook::Config.new)
|
8
|
+
@config = config.read
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
program :name, 'Klipbook'
|
13
|
+
program :version, Klipbook::VERSION
|
14
|
+
program :description, "Klipbook exports the clippings you've saved on your Kindle into JSON, Markdown, or pretty HTML"
|
15
|
+
|
16
|
+
program :help, 'Source', "You must specify either `--from-file` or `--from-site` as an input."
|
17
|
+
program :help, 'Config', "Note that command options can be stored in a file called ~/.klipbookrc. This file is YAML formatted and options should be snake case e.g.\n\n" +
|
18
|
+
":from_site: my-kindle-user@blah.com:my-kindle-password\n" +
|
19
|
+
":output_dir: ~/my/default/output/directory\n"
|
20
|
+
|
21
|
+
default_command :help
|
22
|
+
|
23
|
+
command :list do |c|
|
24
|
+
c.syntax = "klipbook list"
|
25
|
+
c.description = "List the books on the site or in the clippings file"
|
26
|
+
|
27
|
+
c.option '--from-file FILE', String, "Input clippings file"
|
28
|
+
c.option '--from-site username:password', String, "Credentials for Kindle highlights site"
|
29
|
+
c.option '-c', '--count COUNT', Integer, "Maximum number of books to list (default is #{Config::DEFAULT_MAXBOOKS})"
|
30
|
+
|
31
|
+
c.action do |_args, options|
|
32
|
+
merge_config(options, @config)
|
33
|
+
|
34
|
+
Klipbook::Commands::List.new.run!(options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
command :export do |c|
|
39
|
+
c.syntax = 'klipbook export'
|
40
|
+
c.description = 'Export book clippings'
|
41
|
+
|
42
|
+
c.option '--from-file FILE', String, "Input clippings file"
|
43
|
+
c.option '--from-site username:password', String, "Credentials for Kindle highlights site"
|
44
|
+
c.option '-c', '--count COUNT', Integer, "Maximum number of books to list (default is #{Config::DEFAULT_MAXBOOKS})"
|
45
|
+
c.option '--format FORMAT', "Format to export in [html, markdown, or json]"
|
46
|
+
c.option '--output-dir DIRECTORY', "Directory to export files to (default pwd)"
|
47
|
+
c.option '-f', '--force', "Force overwrite of existing files"
|
48
|
+
|
49
|
+
c.action do |_args, options|
|
50
|
+
merge_config(options, @config)
|
51
|
+
|
52
|
+
Klipbook::Commands::Export.new.run!(options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
run!
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def merge_config(options, config)
|
62
|
+
if options.from_site || options.from_file
|
63
|
+
[:from_site, :from_file].each { |key| config.delete(key) }
|
64
|
+
end
|
65
|
+
|
66
|
+
options.default config
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Klipbook
|
2
|
+
module Commands
|
3
|
+
class Command
|
4
|
+
def initialize(logger=Logger.new)
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
def run!(options)
|
9
|
+
run_command!(book_source(options), options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_command!
|
13
|
+
raise "Implement me"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :logger
|
19
|
+
|
20
|
+
def book_source(options)
|
21
|
+
Klipbook::Sources::Source.build(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def exit_unless_valid_source(options)
|
25
|
+
unless options.from_file || options.from_site
|
26
|
+
logger.error "Error: You must specify either `--from-file` or `--from-site` as an input."
|
27
|
+
exit 127
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def exit_unless_valid_count(options)
|
32
|
+
unless options.count > 0
|
33
|
+
logger.error "Error: Specify a maximum book count greater than 0."
|
34
|
+
exit 127
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Klipbook
|
2
|
+
module Commands
|
3
|
+
class Export < Command
|
4
|
+
def run_command!(book_source, options)
|
5
|
+
exit_unless_valid_format(options)
|
6
|
+
exit_unless_valid_output_dir(options)
|
7
|
+
|
8
|
+
exporter(options).run!(
|
9
|
+
books: book_source.books,
|
10
|
+
force: options.force,
|
11
|
+
output_dir: options.output_dir
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def exporter(options)
|
18
|
+
case options.format
|
19
|
+
when "markdown"
|
20
|
+
Exporters::MarkdownExporter.new(logger)
|
21
|
+
when "html"
|
22
|
+
Exporters::HTMLExporter.new(logger)
|
23
|
+
when "json"
|
24
|
+
Exporters::JSONExporter.new(logger)
|
25
|
+
else
|
26
|
+
raise "Unexpected format"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def exit_unless_valid_format(options)
|
31
|
+
unless ["markdown", "html", "json"].include?(options.format)
|
32
|
+
logger.error "Error: You must specify a valid format."
|
33
|
+
exit 127
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def exit_unless_valid_output_dir(options)
|
38
|
+
unless options.output_dir
|
39
|
+
logger.error "Error: Please specify an outdir."
|
40
|
+
exit 127
|
41
|
+
end
|
42
|
+
|
43
|
+
unless File.directory?(options.output_dir)
|
44
|
+
logger.error "Error: Output directory '#{options.output_dir}' does not exist."
|
45
|
+
exit 127
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Klipbook
|
2
|
+
module Commands
|
3
|
+
module Exporters
|
4
|
+
class Exporter
|
5
|
+
def initialize(logger=Logger.new)
|
6
|
+
@logger = logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def run!(books:, force:, output_dir:)
|
10
|
+
@logger.info "Using output directory: #{output_dir}"
|
11
|
+
|
12
|
+
books.each do |book|
|
13
|
+
export_book(book, output_dir, force)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def export_book(book, output_dir, force)
|
20
|
+
filename = filename_for_book(book)
|
21
|
+
filepath = File.join(output_dir, filename)
|
22
|
+
|
23
|
+
if !force && File.exist?(filepath)
|
24
|
+
@logger.info "- Skipping #{filename}"
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
@logger.info "+ Writing #{filename}"
|
29
|
+
|
30
|
+
File.open(filepath, 'w') do |f|
|
31
|
+
f.write render_contents(book)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_contents(book)
|
36
|
+
raise "Implement me"
|
37
|
+
end
|
38
|
+
|
39
|
+
def extension
|
40
|
+
raise "Implement me"
|
41
|
+
end
|
42
|
+
|
43
|
+
def filename_for_book(book)
|
44
|
+
"#{book.title.gsub(/[:,\/!?]/, "")}.#{extension}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Klipbook
|
2
|
+
module Commands
|
3
|
+
module Exporters
|
4
|
+
class HTMLExporter < Exporter
|
5
|
+
def initialize(pretty_printer=Html::Printer.new, logger=Logger.new)
|
6
|
+
super(logger)
|
7
|
+
@pretty_printer = pretty_printer
|
8
|
+
end
|
9
|
+
|
10
|
+
def render_contents(book)
|
11
|
+
ERB.new(template, 0, '%<>').result(book.get_binding)
|
12
|
+
end
|
13
|
+
|
14
|
+
def extension
|
15
|
+
"html"
|
16
|
+
end
|
17
|
+
|
18
|
+
def template
|
19
|
+
@template ||= File.read(File.join(File.dirname(__FILE__), 'html_book_summary.erb'))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Klipbook
|
2
|
+
module Commands
|
3
|
+
module Exporters
|
4
|
+
class MarkdownExporter < Exporter
|
5
|
+
def render_contents(book)
|
6
|
+
ERB.new(template, 0, '%<>').result(book.get_binding)
|
7
|
+
end
|
8
|
+
|
9
|
+
def extension
|
10
|
+
"md"
|
11
|
+
end
|
12
|
+
|
13
|
+
def template
|
14
|
+
@template ||= File.read(File.join(File.dirname(__FILE__), 'markdown_book_summary.erb'))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|