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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.txt +11 -0
  6. data/Gemfile +2 -15
  7. data/Gemfile.lock +73 -113
  8. data/LICENSE.txt +18 -17
  9. data/README.md +63 -69
  10. data/Rakefile +3 -30
  11. data/bin/klipbook +3 -221
  12. data/klipbook.gemspec +32 -118
  13. data/lib/klipbook/cli.rb +69 -0
  14. data/lib/klipbook/commands/command.rb +39 -0
  15. data/lib/klipbook/commands/export.rb +50 -0
  16. data/lib/klipbook/commands/exporters/exporter.rb +49 -0
  17. data/lib/klipbook/{tohtml → commands/exporters}/html_book_summary.erb +1 -1
  18. data/lib/klipbook/commands/exporters/html_exporter.rb +25 -0
  19. data/lib/klipbook/commands/exporters/json_exporter.rb +17 -0
  20. data/lib/klipbook/commands/exporters/markdown_book_summary.erb +12 -0
  21. data/lib/klipbook/commands/exporters/markdown_exporter.rb +19 -0
  22. data/lib/klipbook/commands/list.rb +17 -0
  23. data/lib/klipbook/config.rb +18 -10
  24. data/lib/klipbook/logger.rb +15 -0
  25. data/lib/klipbook/sources/amazon_site/book_scraper.rb +0 -2
  26. data/lib/klipbook/sources/book.rb +36 -21
  27. data/lib/klipbook/sources/clipping.rb +10 -8
  28. data/lib/klipbook/sources/kindle_device/entry.rb +8 -6
  29. data/lib/klipbook/sources/kindle_device/entry_parser.rb +66 -64
  30. data/lib/klipbook/sources/kindle_device/file.rb +45 -43
  31. data/lib/klipbook/sources/kindle_device/file_parser.rb +23 -21
  32. data/lib/klipbook/sources/source.rb +30 -0
  33. data/lib/klipbook/version.rb +1 -1
  34. data/lib/klipbook.rb +11 -11
  35. metadata +56 -113
  36. data/.document +0 -5
  37. data/.yardopts +0 -1
  38. data/Guardfile +0 -19
  39. data/features/fixtures/clippings-for-three-books.txt +0 -105
  40. data/features/list.feature +0 -31
  41. data/features/step_definitions/list_steps.rb +0 -15
  42. data/features/step_definitions/tohtml_steps.rb +0 -61
  43. data/features/step_definitions/tojson_steps.rb +0 -17
  44. data/features/support/env.rb +0 -16
  45. data/features/tohtml.feature +0 -51
  46. data/features/tojson.feature +0 -11
  47. data/lib/klipbook/colours.rb +0 -16
  48. data/lib/klipbook/commands/list_books.rb +0 -19
  49. data/lib/klipbook/commands/tohtml.rb +0 -17
  50. data/lib/klipbook/commands/tojson.rb +0 -18
  51. data/lib/klipbook/sources/invalid_source_error.rb +0 -12
  52. data/lib/klipbook/tohtml/html_printer.rb +0 -39
  53. data/lib/klipbook/tojson/book_file.rb +0 -58
  54. data/spec/lib/klipbook/commands/list_books_spec.rb +0 -43
  55. data/spec/lib/klipbook/commands/tohtml_spec.rb +0 -36
  56. data/spec/lib/klipbook/sources/book_spec.rb +0 -33
  57. data/spec/lib/klipbook/sources/kindle_device/entry_parser_spec.rb +0 -339
  58. data/spec/lib/klipbook/sources/kindle_device/file_parser_spec.rb +0 -68
  59. data/spec/lib/klipbook/sources/kindle_device/file_spec.rb +0 -163
  60. data/spec/lib/klipbook/tohtml/html_printer_spec.rb +0 -88
  61. data/spec/lib/klipbook/tojson/book_file_spec.rb +0 -76
  62. data/spec/spec_helper.rb +0 -7
data/bin/klipbook CHANGED
@@ -1,224 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH << File.expand_path('../../lib', __FILE__)
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
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
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 |s|
8
- s.name = "klipbook"
9
- s.version = "2.1.3"
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
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib"]
13
- s.authors = ["Ray Grasso"]
14
- s.date = "2014-07-25"
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
- if s.respond_to? :specification_version then
83
- s.specification_version = 4
84
-
85
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
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
- s.add_dependency(%q<slop>, ["~> 3.6"])
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
@@ -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
@@ -132,7 +132,7 @@
132
132
  <div class="clearfix"></div>
133
133
 
134
134
  <ul>
135
- <% clippings.each do |clipping| %>
135
+ <% sorted_clippings.each do |clipping| %>
136
136
  <% unless clipping.text.blank? %>
137
137
  <li class="<%= clipping.type %>">
138
138
  <p>
@@ -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,17 @@
1
+ require 'json'
2
+
3
+ module Klipbook
4
+ module Commands
5
+ module Exporters
6
+ class JSONExporter < Exporter
7
+ def render_contents(book)
8
+ JSON.pretty_generate(book)
9
+ end
10
+
11
+ def extension
12
+ "json"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # <%= title %>
2
+
3
+ <% unless author.blank? %>
4
+ *by <%= author %>*
5
+ <% end %>
6
+
7
+ <% sorted_clippings.each do |clipping| %>
8
+ <% unless clipping.text.blank? %>
9
+ <%= clipping.text %> <%= location_markdown(clipping.location) %>
10
+
11
+ <% end %>
12
+ <% end %>
@@ -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