klipbook 2.0.0 → 2.1.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 +7 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -3
- data/Gemfile.lock +112 -74
- data/README.md +18 -18
- data/Rakefile +0 -6
- data/bin/klipbook +180 -84
- data/features/step_definitions/list_steps.rb +2 -2
- data/features/step_definitions/{pretty_print_steps.rb → tohtml_steps.rb} +9 -9
- data/features/step_definitions/tojson_steps.rb +17 -0
- data/features/{pretty_print.feature → tohtml.feature} +12 -12
- data/features/{collate.feature → tojson.feature} +2 -2
- data/klipbook.gemspec +15 -22
- data/lib/klipbook/collate/book_file.rb +8 -3
- data/lib/klipbook/sources/kindle_device/file.rb +4 -3
- data/lib/klipbook/version.rb +1 -1
- data/lib/klipbook.rb +0 -1
- data/spec/lib/klipbook/sources/kindle_device/file_spec.rb +1 -15
- metadata +39 -103
- data/features/step_definitions/collate_steps.rb +0 -17
- data/lib/klipbook/sources/book_source.rb +0 -26
- data/spec/lib/klipbook/sources/book_source_spec.rb +0 -81
data/bin/klipbook
CHANGED
@@ -2,126 +2,222 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH << File.expand_path('../../lib', __FILE__)
|
4
4
|
|
5
|
-
require 'gli'
|
6
5
|
require 'klipbook'
|
6
|
+
require 'slop'
|
7
7
|
|
8
|
-
|
8
|
+
##########
|
9
|
+
# Helpers
|
10
|
+
##########
|
9
11
|
|
10
|
-
|
12
|
+
def get_book_source(opts)
|
13
|
+
exit_unless_valid_source(opts)
|
11
14
|
|
12
|
-
|
13
|
-
"Example file formats:\n\n" +
|
14
|
-
" file:path/to/my-clippings-file.txt\n\n" +
|
15
|
-
" site:my-kindle-user@blah.com:my-kindle-password\n\n" +
|
16
|
-
"Note that source and output file defaults can be stored in a file called ~/.klipbookrc\n\n" +
|
17
|
-
"This file is YAML formatted e.g.\n\n" +
|
18
|
-
"source: site:my-kindle-user@blah.com:my-kindle-password\n\n" +
|
19
|
-
"output: my/default/output/directory"
|
20
|
-
|
21
|
-
version Klipbook::VERSION
|
15
|
+
max_books = opts[:number].to_i
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
unless max_books > 0
|
18
|
+
$stderr.puts "Error: Specify a number of books greater than 0"
|
19
|
+
exit 127
|
20
|
+
end
|
27
21
|
|
28
|
-
|
29
|
-
|
30
|
-
long_desc "Clippings are fetched from the specified source, collated, and written into a single json file.\n\n" +
|
31
|
-
SOURCE_HELP
|
32
|
-
command :collate do |c|
|
22
|
+
get_file_source(infile(opts), max_books) || get_site_source(credentials(opts), max_books)
|
23
|
+
end
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
37
31
|
|
38
|
-
|
39
|
-
|
32
|
+
def get_site_source(creds, max_books)
|
33
|
+
return nil unless creds
|
40
34
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
Klipbook::Commands::Collate.new(books, book_file(book_file_path)).call(book_file_path, options[:f])
|
35
|
+
unless creds =~ /(.+):(.+)/
|
36
|
+
$stderr.puts "Error: your credentials need to be in username:password format."
|
37
|
+
exit 127
|
45
38
|
end
|
46
|
-
end
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
command :pprint do |c|
|
40
|
+
username = $1
|
41
|
+
password = $2
|
42
|
+
Klipbook::Sources::AmazonSite::SiteScraper.new(username, password, max_books)
|
43
|
+
end
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
c.flag [:o, :'output-dir']
|
45
|
+
def get_file_source(file, max_books)
|
46
|
+
return nil unless file
|
57
47
|
|
58
|
-
|
59
|
-
|
48
|
+
Klipbook::Sources::KindleDevice::File.new(file, max_books)
|
49
|
+
end
|
60
50
|
|
61
|
-
|
62
|
-
|
63
|
-
Klipbook::Commands::PrettyPrint.new(books).call(output_dir(options), options[:f])
|
64
|
-
end
|
51
|
+
def fetch_books(opts)
|
52
|
+
get_book_source(opts).books
|
65
53
|
end
|
66
54
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
Klipbook::Commands::ListBooks.new(books).call
|
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
|
74
61
|
end
|
62
|
+
|
63
|
+
File.open(file_path, "r")
|
75
64
|
end
|
76
65
|
|
77
|
-
|
78
|
-
|
79
|
-
|
66
|
+
def raw_json_from_file(file_path)
|
67
|
+
File.open(file_path, 'r') do |f|
|
68
|
+
f.read
|
80
69
|
end
|
70
|
+
rescue
|
71
|
+
""
|
72
|
+
end
|
81
73
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
74
|
+
def book_file(file_path)
|
75
|
+
Klipbook::Collate::BookFile.from_json(raw_json_from_file(file_path))
|
76
|
+
end
|
86
77
|
|
87
|
-
|
88
|
-
|
89
|
-
|
78
|
+
#########
|
79
|
+
# Params
|
80
|
+
#########
|
90
81
|
|
91
|
-
|
82
|
+
def infile(opts)
|
83
|
+
open_infile(opts[:infile])
|
92
84
|
end
|
93
85
|
|
94
|
-
|
95
|
-
|
86
|
+
def credentials(opts)
|
87
|
+
puts "Using credentials from ~/.klipbookrc" if !opts[:credentials] && CONFIG[:credentials]
|
88
|
+
|
89
|
+
opts[:credentials] || CONFIG[:credentials]
|
96
90
|
end
|
97
91
|
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
else
|
104
|
-
''
|
105
|
-
end
|
92
|
+
def ensure_outfile(opts)
|
93
|
+
unless opts[:outfile] || CONFIG[:outfile]
|
94
|
+
$stderr.puts("Error: Please specify an outfile.")
|
95
|
+
exit(127)
|
96
|
+
end
|
106
97
|
|
107
|
-
|
98
|
+
outfile_path(opts)
|
108
99
|
end
|
109
100
|
|
110
|
-
def
|
111
|
-
|
101
|
+
def outfile_path(opts)
|
102
|
+
puts "Using outfile from ~/.klipbookrc" if !opts[:outfile] && CONFIG[:outfile]
|
103
|
+
|
104
|
+
opts[:outfile] || CONFIG[:outfile]
|
112
105
|
end
|
113
106
|
|
114
|
-
def
|
115
|
-
|
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
|
116
121
|
end
|
117
122
|
|
118
|
-
def
|
119
|
-
|
123
|
+
def outdir_path(opts)
|
124
|
+
puts "Using outdir from ~/.klipbookrc" if !opts[:outdir] && CONFIG[:outdir]
|
125
|
+
|
126
|
+
opts[:outdir] || CONFIG[:outdir] || Dir.pwd
|
120
127
|
end
|
121
128
|
|
122
|
-
|
123
|
-
|
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"
|
124
146
|
end
|
125
147
|
|
126
|
-
|
148
|
+
opts = Slop.parse(help: true) do
|
149
|
+
banner "Usage: klipbook <command> [options]\n\n" +
|
150
|
+
"Klipbook pretty prints 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
|
+
end
|
156
|
+
|
157
|
+
command "list" do
|
158
|
+
desc = "List the books on the site or in the clippings file."
|
159
|
+
|
160
|
+
banner banner_for_command("list", desc)
|
161
|
+
|
162
|
+
description desc
|
163
|
+
|
164
|
+
on :c, :credentials=, "<username>:<password> for Kindle site"
|
165
|
+
on :i, :infile=, "Input file (default STDIN)"
|
166
|
+
on :n, :number=, "Maximum number of books to list (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
167
|
+
|
168
|
+
run do |opts, args|
|
169
|
+
books = fetch_books(opts)
|
170
|
+
Klipbook::Commands::ListBooks.new(books).call
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
command "tojson" do
|
175
|
+
desc = "Print book highlights as JSON. Note that this will update an existing JSON file in place with new entries."
|
176
|
+
|
177
|
+
banner banner_for_command("tojson", desc)
|
178
|
+
|
179
|
+
description desc
|
180
|
+
|
181
|
+
on :c, :credentials=, "<username>:<password> for Kindle site"
|
182
|
+
on :i, :infile=, "Input file (default STDIN)"
|
183
|
+
on :n, :number=, "Maximum number of books to print as json (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
184
|
+
on :o, :outfile=, "Output JSON file (default STDOUT)"
|
185
|
+
on :f, :force, "Force overwrite of any existing book entries within the output file"
|
186
|
+
|
187
|
+
run do |opts, args|
|
188
|
+
outfile_path = ensure_outfile(opts)
|
189
|
+
|
190
|
+
books = fetch_books(opts)
|
191
|
+
|
192
|
+
Klipbook::Commands::Collate.new(books, book_file(outfile_path)).call(outfile_path, opts[:force])
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
command "tohtml" do
|
197
|
+
desc = "Print book highlights as HTML."
|
198
|
+
|
199
|
+
banner banner_for_command("tohtml", desc)
|
200
|
+
|
201
|
+
description desc
|
202
|
+
|
203
|
+
on :c, :credentials=, "<username>:<password> for Kindle site"
|
204
|
+
on :i, :infile=, "Input file (default STDIN)"
|
205
|
+
on :n, :number=, "Maximum number of books to print as html (default is #{DEFAULT_MAXBOOKS})", default: DEFAULT_MAXBOOKS
|
206
|
+
on :o, :outdir=, "Directory to write HTML files to (default pwd)"
|
207
|
+
on :f, :force, "Force overwrite of existing files"
|
208
|
+
|
209
|
+
run do |opts, args|
|
210
|
+
books = fetch_books(opts)
|
211
|
+
|
212
|
+
outdir_path = ensure_outdir(opts)
|
213
|
+
|
214
|
+
Klipbook::Commands::PrettyPrint.new(books).call(outdir_path, opts[:force])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Default action is to output help
|
219
|
+
run do |opts, args|
|
220
|
+
puts opts.help
|
221
|
+
end
|
222
|
+
end
|
127
223
|
|
@@ -6,10 +6,10 @@ Given /^I have a clippings file "([^"]*)" that contains no clippings$/ do |input
|
|
6
6
|
end
|
7
7
|
|
8
8
|
When /^I list "([^"]*)" books in the file "([^"]*)"$/ do |book_count, input_file|
|
9
|
-
run_simple(unescape("klipbook -n #{book_count}
|
9
|
+
run_simple(unescape("klipbook list -n #{book_count} -i #{input_file}"), false)
|
10
10
|
end
|
11
11
|
|
12
12
|
# FIXME This step currently assumes you have site: set up in your klipbookrc
|
13
13
|
When /^I list "([^"]*)" books from the kindle site$/ do |book_count|
|
14
|
-
run_simple(unescape("klipbook -n #{book_count}
|
14
|
+
run_simple(unescape("klipbook list -n #{book_count}"), false)
|
15
15
|
end
|
@@ -14,12 +14,12 @@ Given /^a file that contains clippings for 3 books called "([^"]*)"$/ do |file_n
|
|
14
14
|
in_current_dir { FileUtils.cp(CLIPPING_FILE, file_name) }
|
15
15
|
end
|
16
16
|
|
17
|
-
When /^I
|
18
|
-
|
17
|
+
When /^I tohtml clippings for "([^"]*)" books from the file "([^"]*)" to the output directory "([^"]*)"$/ do |book_count, input_file, output_dir|
|
18
|
+
run_tohtml_file(book_count, output_dir, input_file, false)
|
19
19
|
end
|
20
20
|
|
21
|
-
When /^I
|
22
|
-
|
21
|
+
When /^I tohtml clippings for "([^"]*)" books from the file "([^"]*)" to the output directory "([^"]*)" forcefully$/ do |book_count, input_file, output_dir|
|
22
|
+
run_tohtml_file(book_count, output_dir, input_file, true)
|
23
23
|
end
|
24
24
|
|
25
25
|
Then /^I should find a file in the folder "([^"]*)" named "([^"]*)" that contains "([^"]*)" clippings$/ do |output_folder, file_name, clipping_count|
|
@@ -33,11 +33,11 @@ Then /^I should find a file in the folder "([^"]*)" named "([^"]*)" that contain
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# FIXME This step currently assumes you have site: set up in your klipbookrc
|
36
|
-
When /^I
|
37
|
-
run_simple(unescape("klipbook -n #{book_count}
|
36
|
+
When /^I tohtml clippings for "([^"]*)" books from the kindle site to the output directory "([^"]*)"$/ do |book_count, output_dir|
|
37
|
+
run_simple(unescape("klipbook tohtml -n #{book_count} -o #{output_dir}"), false)
|
38
38
|
end
|
39
39
|
|
40
|
-
Then /^I should find "([^"]*)"
|
40
|
+
Then /^I should find "([^"]*)" html files containing clippings in the directory "([^"]*)"$/ do |file_count, output_dir|
|
41
41
|
in_current_dir do
|
42
42
|
files = Dir['output/*.html']
|
43
43
|
files.should have(file_count.to_i).items
|
@@ -49,13 +49,13 @@ Then /^I should find "([^"]*)" pretty printed files containing clippings in the
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
def
|
52
|
+
def run_tohtml_file(book_count, output, input, force=false)
|
53
53
|
force_str = if force
|
54
54
|
'-f'
|
55
55
|
else
|
56
56
|
''
|
57
57
|
end
|
58
58
|
|
59
|
-
run_simple(unescape("klipbook -n #{book_count}
|
59
|
+
run_simple(unescape("klipbook tohtml -n #{book_count} #{force_str} -o #{output} -i #{input}"), false)
|
60
60
|
end
|
61
61
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
When /^I tojson clippings for "([^"]*)" books from the file "([^"]*)" to the output file "([^"]*)"$/ do |book_count, input_file, output_file|
|
3
|
+
run_tojson(book_count, output_file, input_file)
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^I should find a file called "([^"]*)" that contains "([^"]*)"$/ do |output_file, expected_text|
|
7
|
+
in_current_dir do
|
8
|
+
File.exists?(output_file).should be_true
|
9
|
+
File.open(output_file, 'r') do |f|
|
10
|
+
f.read.should match(/#{expected_text}/m)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_tojson(book_count, output_file, input_file)
|
16
|
+
run_simple(unescape("klipbook tojson -n #{book_count} -o #{output_file} -i #{input_file}"), false)
|
17
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Feature: klipbook
|
1
|
+
Feature: klipbook outputs the clippings from a clippings file into a set of HTML files
|
2
2
|
As an avid reader and note taker
|
3
3
|
I want to see a pretty html summary for each of the books that I've read
|
4
4
|
So that I can refer to a nice summary of passages I enjoyed in the book
|
@@ -6,7 +6,7 @@ Feature: klipbook pretty prints the clippings from a clippings file
|
|
6
6
|
Scenario: File with clippings for a book
|
7
7
|
Given a directory named "output"
|
8
8
|
And a file that contains clippings for 3 books called "input.txt"
|
9
|
-
When I
|
9
|
+
When I tohtml clippings for "3" books from the file "input.txt" to the output directory "output"
|
10
10
|
Then I should find a file in the folder "output" named "Lean Software Development: An Agile Toolkit by Mary Poppendieck and Tom Poppendieck.html" that contains "13" clippings
|
11
11
|
Then I should find a file in the folder "output" named "Instapaper: Long Reads by Instapaper: Long Reads.html" that contains "4" clippings
|
12
12
|
Then I should find a file in the folder "output" named "Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.html" that contains "3" clippings
|
@@ -16,7 +16,7 @@ Feature: klipbook pretty prints the clippings from a clippings file
|
|
16
16
|
Given a directory named "output"
|
17
17
|
And a file in "output" named "Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.html"
|
18
18
|
And a file that contains clippings for 3 books called "input.txt"
|
19
|
-
When I
|
19
|
+
When I tohtml clippings for "3" books from the file "input.txt" to the output directory "output"
|
20
20
|
Then the output should contain "Skipping Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.html"
|
21
21
|
And the exit status should be 0
|
22
22
|
|
@@ -24,28 +24,28 @@ Feature: klipbook pretty prints the clippings from a clippings file
|
|
24
24
|
Given a directory named "output"
|
25
25
|
And a file in "output" named "Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.html"
|
26
26
|
And a file that contains clippings for 3 books called "input.txt"
|
27
|
-
When I
|
27
|
+
When I tohtml clippings for "3" books from the file "input.txt" to the output directory "output" forcefully
|
28
28
|
Then the output should contain "Writing Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.html"
|
29
29
|
And the exit status should be 0
|
30
30
|
|
31
31
|
Scenario: Attempt to write with a bad number of books
|
32
32
|
Given a directory named "output"
|
33
33
|
And a file that contains clippings for 3 books called "input.txt"
|
34
|
-
When I
|
35
|
-
Then the output should contain "
|
36
|
-
And the exit status should be
|
34
|
+
When I tohtml clippings for "notanumber" books from the file "input.txt" to the output directory "output"
|
35
|
+
Then the output should contain "Error: Specify a number of books greater than 0"
|
36
|
+
And the exit status should be 127
|
37
37
|
|
38
38
|
Scenario: Attempt to write to a non-existent directory
|
39
39
|
Given there is not a directory named "output"
|
40
40
|
And a file that contains clippings for 3 books called "input.txt"
|
41
|
-
When I
|
42
|
-
Then the output should contain "
|
43
|
-
And the exit status should be
|
41
|
+
When I tohtml clippings for "3" books from the file "input.txt" to the output directory "output"
|
42
|
+
Then the output should contain "Error: Outdir does not exist."
|
43
|
+
And the exit status should be 127
|
44
44
|
|
45
45
|
@slow
|
46
46
|
Scenario: Site with clippings for a book
|
47
47
|
Given a directory named "output"
|
48
|
-
When I
|
49
|
-
Then I should find "1"
|
48
|
+
When I tohtml clippings for "1" books from the kindle site to the output directory "output"
|
49
|
+
Then I should find "1" html files containing clippings in the directory "output"
|
50
50
|
And the exit status should be 0
|
51
51
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
Feature: klipbook
|
1
|
+
Feature: klipbook outputs clippings from a clippings file into a JSON file
|
2
2
|
As an avid reader and note taker
|
3
3
|
I want to see a single JSON file collating the clippings of the books that I've read
|
4
4
|
So that I can export them to other tools for my enjoyment
|
5
5
|
|
6
6
|
Scenario: File with clippings for a book
|
7
7
|
Given a file that contains clippings for 3 books called "input.txt"
|
8
|
-
When I
|
8
|
+
When I tojson clippings for "3" books from the file "input.txt" to the output file "books.json"
|
9
9
|
Then I should find a file called "books.json" that contains "Lean Software Development: An Agile Toolkit"
|
10
10
|
And the exit status should be 0
|
11
11
|
|
data/klipbook.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "klipbook"
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ray Grasso"]
|
12
|
-
s.date = "2013-
|
12
|
+
s.date = "2013-12-11"
|
13
13
|
s.description = "Process your Kindle clippings file to generate a nicely formatted compilation of the clippings of the books you've read"
|
14
14
|
s.email = "ray.grasso@gmail.com"
|
15
15
|
s.executables = ["klipbook"]
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.files = [
|
21
21
|
".document",
|
22
22
|
".rspec",
|
23
|
+
".ruby-version",
|
23
24
|
".yardopts",
|
24
25
|
"CHANGELOG.txt",
|
25
26
|
"Gemfile",
|
@@ -30,14 +31,14 @@ Gem::Specification.new do |s|
|
|
30
31
|
"Rakefile",
|
31
32
|
"bin/klipbook",
|
32
33
|
"example.png",
|
33
|
-
"features/collate.feature",
|
34
34
|
"features/fixtures/clippings-for-three-books.txt",
|
35
35
|
"features/list.feature",
|
36
|
-
"features/pretty_print.feature",
|
37
|
-
"features/step_definitions/collate_steps.rb",
|
38
36
|
"features/step_definitions/list_steps.rb",
|
39
|
-
"features/step_definitions/
|
37
|
+
"features/step_definitions/tohtml_steps.rb",
|
38
|
+
"features/step_definitions/tojson_steps.rb",
|
40
39
|
"features/support/env.rb",
|
40
|
+
"features/tohtml.feature",
|
41
|
+
"features/tojson.feature",
|
41
42
|
"klipbook.gemspec",
|
42
43
|
"lib/klipbook.rb",
|
43
44
|
"lib/klipbook/collate/book_file.rb",
|
@@ -50,7 +51,6 @@ Gem::Specification.new do |s|
|
|
50
51
|
"lib/klipbook/sources/amazon_site/book_scraper.rb",
|
51
52
|
"lib/klipbook/sources/amazon_site/site_scraper.rb",
|
52
53
|
"lib/klipbook/sources/book.rb",
|
53
|
-
"lib/klipbook/sources/book_source.rb",
|
54
54
|
"lib/klipbook/sources/clipping.rb",
|
55
55
|
"lib/klipbook/sources/invalid_source_error.rb",
|
56
56
|
"lib/klipbook/sources/kindle_device/entry.rb",
|
@@ -64,7 +64,6 @@ Gem::Specification.new do |s|
|
|
64
64
|
"spec/lib/klipbook/commands/list_books_spec.rb",
|
65
65
|
"spec/lib/klipbook/commands/pretty_print_spec.rb",
|
66
66
|
"spec/lib/klipbook/pretty_print/html_printer_spec.rb",
|
67
|
-
"spec/lib/klipbook/sources/book_source_spec.rb",
|
68
67
|
"spec/lib/klipbook/sources/book_spec.rb",
|
69
68
|
"spec/lib/klipbook/sources/kindle_device/entry_parser_spec.rb",
|
70
69
|
"spec/lib/klipbook/sources/kindle_device/file_parser_spec.rb",
|
@@ -76,61 +75,55 @@ Gem::Specification.new do |s|
|
|
76
75
|
s.homepage = "https://github.com/grassdog/klipbook"
|
77
76
|
s.licenses = ["MIT"]
|
78
77
|
s.require_paths = ["lib"]
|
79
|
-
s.rubygems_version = "
|
78
|
+
s.rubygems_version = "2.0.14"
|
80
79
|
s.summary = "Klipbook creates a nice html summary of the clippings you've created on your Kindle."
|
81
80
|
|
82
81
|
if s.respond_to? :specification_version then
|
83
|
-
s.specification_version =
|
82
|
+
s.specification_version = 4
|
84
83
|
|
85
84
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
86
|
-
s.add_runtime_dependency(%q<
|
85
|
+
s.add_runtime_dependency(%q<slop>, [">= 0"])
|
87
86
|
s.add_runtime_dependency(%q<mechanize>, [">= 0"])
|
88
87
|
s.add_runtime_dependency(%q<rainbow>, [">= 0"])
|
89
88
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
90
89
|
s.add_development_dependency(%q<rr>, [">= 0"])
|
91
90
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
92
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.
|
93
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
91
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.8"])
|
94
92
|
s.add_development_dependency(%q<pry-debugger>, [">= 0"])
|
95
93
|
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
96
94
|
s.add_development_dependency(%q<aruba>, [">= 0"])
|
97
95
|
s.add_development_dependency(%q<guard>, [">= 0"])
|
98
96
|
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
99
97
|
s.add_development_dependency(%q<guard-cucumber>, [">= 0"])
|
100
|
-
s.add_development_dependency(%q<terminal-notifier-guard>, [">= 0"])
|
101
98
|
else
|
102
|
-
s.add_dependency(%q<
|
99
|
+
s.add_dependency(%q<slop>, [">= 0"])
|
103
100
|
s.add_dependency(%q<mechanize>, [">= 0"])
|
104
101
|
s.add_dependency(%q<rainbow>, [">= 0"])
|
105
102
|
s.add_dependency(%q<rspec>, [">= 0"])
|
106
103
|
s.add_dependency(%q<rr>, [">= 0"])
|
107
104
|
s.add_dependency(%q<bundler>, [">= 0"])
|
108
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
109
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
105
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
110
106
|
s.add_dependency(%q<pry-debugger>, [">= 0"])
|
111
107
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
112
108
|
s.add_dependency(%q<aruba>, [">= 0"])
|
113
109
|
s.add_dependency(%q<guard>, [">= 0"])
|
114
110
|
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
115
111
|
s.add_dependency(%q<guard-cucumber>, [">= 0"])
|
116
|
-
s.add_dependency(%q<terminal-notifier-guard>, [">= 0"])
|
117
112
|
end
|
118
113
|
else
|
119
|
-
s.add_dependency(%q<
|
114
|
+
s.add_dependency(%q<slop>, [">= 0"])
|
120
115
|
s.add_dependency(%q<mechanize>, [">= 0"])
|
121
116
|
s.add_dependency(%q<rainbow>, [">= 0"])
|
122
117
|
s.add_dependency(%q<rspec>, [">= 0"])
|
123
118
|
s.add_dependency(%q<rr>, [">= 0"])
|
124
119
|
s.add_dependency(%q<bundler>, [">= 0"])
|
125
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
126
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
120
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
127
121
|
s.add_dependency(%q<pry-debugger>, [">= 0"])
|
128
122
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
129
123
|
s.add_dependency(%q<aruba>, [">= 0"])
|
130
124
|
s.add_dependency(%q<guard>, [">= 0"])
|
131
125
|
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
132
126
|
s.add_dependency(%q<guard-cucumber>, [">= 0"])
|
133
|
-
s.add_dependency(%q<terminal-notifier-guard>, [">= 0"])
|
134
127
|
end
|
135
128
|
end
|
136
129
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'rainbow'
|
2
3
|
|
3
4
|
module Klipbook::Collate
|
4
5
|
class BookFile
|
@@ -21,9 +22,13 @@ module Klipbook::Collate
|
|
21
22
|
def add_books(new_books, force, message_stream=$stdout)
|
22
23
|
new_books.each do |new_book|
|
23
24
|
if book_exists?(new_book)
|
24
|
-
|
25
|
+
if force
|
26
|
+
replace_book(new_book, message_stream)
|
27
|
+
else
|
28
|
+
message_stream.puts "Skipping: ".foreground(:yellow) + "#{new_book.title_and_author}"
|
29
|
+
end
|
25
30
|
else
|
26
|
-
message_stream.puts "Adding: #{new_book.title_and_author}"
|
31
|
+
message_stream.puts "Adding: ".foreground(:green) + "#{new_book.title_and_author}"
|
27
32
|
@books.push(new_book)
|
28
33
|
end
|
29
34
|
end
|
@@ -44,7 +49,7 @@ module Klipbook::Collate
|
|
44
49
|
end
|
45
50
|
|
46
51
|
def replace_book(new_book, message_stream)
|
47
|
-
message_stream.puts "Updating: #{new_book.title_and_author}"
|
52
|
+
message_stream.puts "Updating: ".foreground(:green) + "#{new_book.title_and_author}"
|
48
53
|
|
49
54
|
old_book = find_book(new_book)
|
50
55
|
@books.delete(old_book)
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Klipbook::Sources
|
2
2
|
module KindleDevice
|
3
3
|
class File
|
4
|
-
def initialize(
|
5
|
-
@file_text =
|
4
|
+
def initialize(infile, max_books, file_parser=FileParser.new)
|
5
|
+
@file_text = infile.read.strip
|
6
6
|
@file_parser = file_parser
|
7
7
|
@max_books = max_books
|
8
8
|
end
|
9
9
|
|
10
|
+
# TODO Shift max books here
|
10
11
|
def books
|
11
12
|
@books ||= build_books.take(@max_books)
|
12
13
|
end
|
@@ -25,7 +26,7 @@ module Klipbook::Sources
|
|
25
26
|
|
26
27
|
def build_sorted_book_list(sorted_entries)
|
27
28
|
books_from_entries(sorted_entries).sort do |book_a, book_b|
|
28
|
-
|
29
|
+
book_b.last_update <=> book_a.last_update
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
data/lib/klipbook/version.rb
CHANGED