klipbook 2.1.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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