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
@@ -1,19 +0,0 @@
|
|
1
|
-
module Klipbook::Commands
|
2
|
-
class ListBooks
|
3
|
-
def initialize(books)
|
4
|
-
@books = books
|
5
|
-
end
|
6
|
-
|
7
|
-
def call(output_stream=$stdout)
|
8
|
-
if @books.empty?
|
9
|
-
output_stream.puts 'No books available'
|
10
|
-
else
|
11
|
-
output_stream.puts 'Book list:'
|
12
|
-
@books.each_with_index do |book, index|
|
13
|
-
output_stream.puts "[#{index + 1}] #{book.title_and_author}"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Klipbook::Commands
|
2
|
-
class ToHtml
|
3
|
-
def initialize(books, pretty_printer=Klipbook::ToHtml::HtmlPrinter.new)
|
4
|
-
@books = books
|
5
|
-
@pretty_printer = pretty_printer
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(output_dir, force, message_stream=$stdout)
|
9
|
-
message_stream.puts "Using output directory: #{output_dir}"
|
10
|
-
|
11
|
-
@books.each do |book|
|
12
|
-
@pretty_printer.print_to_file(book, output_dir, force)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Klipbook::Commands
|
2
|
-
class ToJson
|
3
|
-
def initialize(books, book_file)
|
4
|
-
@books = books
|
5
|
-
@book_file = book_file
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(output_file_path, force, message_stream=$stdout)
|
9
|
-
message_stream.puts "\nWriting book json to file: #{output_file_path}"
|
10
|
-
|
11
|
-
@book_file.add_books(@books, force)
|
12
|
-
|
13
|
-
File.open(output_file_path, 'w') do |output_file|
|
14
|
-
output_file.puts @book_file.to_json
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
class InvalidSourceError < RuntimeError
|
2
|
-
|
3
|
-
DEFAULT_MESSAGE = "Please provide a valid source.\n" +
|
4
|
-
"e.g.\n" +
|
5
|
-
" file:path/to/my-clippings-file.txt\n" +
|
6
|
-
" site:my-kindle-user@blah.com:my-kindle-password"
|
7
|
-
|
8
|
-
def initialize(msg = DEFAULT_MESSAGE)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
module Klipbook::ToHtml
|
4
|
-
class HtmlPrinter
|
5
|
-
def initialize(message_stream=$stdout)
|
6
|
-
@message_stream = message_stream
|
7
|
-
end
|
8
|
-
|
9
|
-
def print_to_file(book, output_dir, force)
|
10
|
-
filename = filename_for_book(book)
|
11
|
-
filepath = File.join(output_dir, filename)
|
12
|
-
|
13
|
-
if !force && File.exists?(filepath)
|
14
|
-
@message_stream.puts(Colours.yellow("Skipping ") + filename)
|
15
|
-
return
|
16
|
-
end
|
17
|
-
|
18
|
-
@message_stream.puts(Colours.green("Writing ") + filename)
|
19
|
-
File.open(filepath, 'w') do |f|
|
20
|
-
f.write generate_html(book)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def filename_for_book(book)
|
27
|
-
"#{book.title_and_author}.html"
|
28
|
-
end
|
29
|
-
|
30
|
-
def generate_html(book)
|
31
|
-
ERB.new(template, 0, '%<>').result(book.get_binding)
|
32
|
-
end
|
33
|
-
|
34
|
-
def template
|
35
|
-
@template ||= File.read(File.join(File.dirname(__FILE__), 'html_book_summary.erb'))
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
module Klipbook::ToJson
|
4
|
-
class BookFile
|
5
|
-
attr_reader :books
|
6
|
-
|
7
|
-
def self.from_json(raw_json)
|
8
|
-
if raw_json.blank?
|
9
|
-
books = []
|
10
|
-
else
|
11
|
-
objs = JSON.parse(raw_json)
|
12
|
-
books = objs.map { |o| Klipbook::Book.from_hash(o) }
|
13
|
-
end
|
14
|
-
self.new(books)
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(books)
|
18
|
-
@books = books || []
|
19
|
-
end
|
20
|
-
|
21
|
-
def add_books(new_books, force, message_stream=$stdout)
|
22
|
-
new_books.each do |new_book|
|
23
|
-
if book_exists?(new_book)
|
24
|
-
if force
|
25
|
-
replace_book(new_book, message_stream)
|
26
|
-
else
|
27
|
-
message_stream.puts Colours.yellow("Skipping: ") + "#{new_book.title_and_author}"
|
28
|
-
end
|
29
|
-
else
|
30
|
-
message_stream.puts Colours.green("Adding: ") + "#{new_book.title_and_author}"
|
31
|
-
@books.push(new_book)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def to_json
|
37
|
-
JSON.pretty_generate(@books)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def book_exists?(new_book)
|
43
|
-
find_book(new_book)
|
44
|
-
end
|
45
|
-
|
46
|
-
def find_book(new_book)
|
47
|
-
@books.find { |existing_book| existing_book.title_and_author == new_book.title_and_author }
|
48
|
-
end
|
49
|
-
|
50
|
-
def replace_book(new_book, message_stream)
|
51
|
-
message_stream.puts Colours.green("Updating: ") + "#{new_book.title_and_author}"
|
52
|
-
|
53
|
-
old_book = find_book(new_book)
|
54
|
-
@books.delete(old_book)
|
55
|
-
@books.push(new_book)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Klipbook::Commands::ListBooks do
|
4
|
-
|
5
|
-
let (:output) do
|
6
|
-
double("output", puts: nil)
|
7
|
-
end
|
8
|
-
|
9
|
-
describe '#call' do
|
10
|
-
|
11
|
-
subject { Klipbook::Commands::ListBooks.new(books).call(output) }
|
12
|
-
|
13
|
-
context 'when created with no books' do
|
14
|
-
|
15
|
-
let (:books) { [] }
|
16
|
-
|
17
|
-
it 'displays a message saying that the clipping file contains no books' do
|
18
|
-
subject
|
19
|
-
expect(output).to have_received(:puts).with('No books available')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'when created with multiple books' do
|
24
|
-
let (:books) do
|
25
|
-
[
|
26
|
-
Klipbook::Book.new.tap { |b| b.title = 'My first fake title' },
|
27
|
-
Klipbook::Book.new.tap { |b| b.title = 'Another fake book'; b.author = 'Rock Riphard' }
|
28
|
-
]
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'displays a message describing the book list' do
|
32
|
-
subject
|
33
|
-
expect(output).to have_received(:puts).with('Book list:')
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'displays an indexed list of book titles including the author when available' do
|
37
|
-
subject
|
38
|
-
expect(output).to have_received(:puts).with('[1] My first fake title')
|
39
|
-
expect(output).to have_received(:puts).with('[2] Another fake book by Rock Riphard')
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Klipbook::Commands::ToHtml do
|
4
|
-
|
5
|
-
let (:it) { Klipbook::Commands::ToHtml.new(books, pretty_printer) }
|
6
|
-
|
7
|
-
let (:pretty_printer) do
|
8
|
-
double(print_to_file: nil)
|
9
|
-
end
|
10
|
-
|
11
|
-
let (:message_stream) do
|
12
|
-
double(puts: nil)
|
13
|
-
end
|
14
|
-
|
15
|
-
let (:book_one) { Klipbook::Book.new('book one') }
|
16
|
-
let (:book_two) { Klipbook::Book.new('book two') }
|
17
|
-
let (:books) { [ book_one, book_two ] }
|
18
|
-
|
19
|
-
let(:output_dir) { 'fake output dir' }
|
20
|
-
|
21
|
-
describe '#call' do
|
22
|
-
|
23
|
-
subject { it.call(output_dir, true, message_stream) }
|
24
|
-
|
25
|
-
it 'prints a message displaying the output directory' do
|
26
|
-
subject
|
27
|
-
expect(message_stream).to have_received(:puts).with('Using output directory: fake output dir')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'passes each book to the pretty printer' do
|
31
|
-
subject
|
32
|
-
expect(pretty_printer).to have_received(:print_to_file).with(book_one, output_dir, true)
|
33
|
-
expect(pretty_printer).to have_received(:print_to_file).with(book_two, output_dir, true)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Klipbook::Book do
|
4
|
-
describe '#title_and_author' do
|
5
|
-
|
6
|
-
subject { book.title_and_author }
|
7
|
-
|
8
|
-
context 'with no author' do
|
9
|
-
let(:book) do
|
10
|
-
Klipbook::Book.new.tap do |b|
|
11
|
-
b.title = 'Book title'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'only contains the title' do
|
16
|
-
expect(subject).to eq 'Book title'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'with an author' do
|
21
|
-
let(:book) do
|
22
|
-
Klipbook::Book.new.tap do |b|
|
23
|
-
b.title = 'Book title'
|
24
|
-
b.author = 'Rob Ripjaw'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'contains the title and author' do
|
29
|
-
expect(subject).to eq 'Book title by Rob Ripjaw'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,339 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Klipbook::Sources::KindleDevice::EntryParser do
|
4
|
-
|
5
|
-
describe '#build_entry' do
|
6
|
-
subject { Klipbook::Sources::KindleDevice::EntryParser.new.build_entry(entry_text) }
|
7
|
-
|
8
|
-
context 'passed an empty entry' do
|
9
|
-
let(:entry_text) { " " }
|
10
|
-
|
11
|
-
it 'returns nil' do
|
12
|
-
expect(subject).to be_nil
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'passed an incomplete entry' do
|
17
|
-
let(:entry_text) do
|
18
|
-
"Not long enough"
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'returns nil' do
|
22
|
-
expect(subject).to be_nil
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'passed an entry with the title line "Book title (Author\'s Name)"' do
|
27
|
-
let (:entry_text) do
|
28
|
-
"Book title (Author's Name)\n" +
|
29
|
-
"- Highlight Loc. 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
30
|
-
"\n" +
|
31
|
-
"Highlight text\n"
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'extracts the title' do
|
35
|
-
expect(subject.title).to eq 'Book title'
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'extracts the author' do
|
39
|
-
expect(subject.author).to eq "Author's Name"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'passed an entry with the title line "Book title (sub title) (Author\'s Name)"' do
|
44
|
-
let (:entry_text) do
|
45
|
-
"Book title (sub title) (Author's Name)\n" +
|
46
|
-
"- Highlight Loc. 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
47
|
-
"\n" +
|
48
|
-
"Highlight text\n"
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'extracts the title containing parens' do
|
52
|
-
expect(subject.title).to eq 'Book title (sub title)'
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'extracts the author' do
|
56
|
-
expect(subject.author).to eq "Author's Name"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'passed an entry with the title line "Book title"' do
|
61
|
-
let (:entry_text) do
|
62
|
-
"Book title\n" +
|
63
|
-
"- Highlight Loc. 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
64
|
-
"\n" +
|
65
|
-
"Highlight text\n"
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'extracts the title' do
|
69
|
-
expect(subject.title).to eq 'Book title'
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'sets author to nil' do
|
73
|
-
expect(subject.author).to be_nil
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'passed an entry that is a highlight' do
|
78
|
-
let (:entry_text) do
|
79
|
-
"Book title\n" +
|
80
|
-
"- Highlight Loc. 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
81
|
-
"\n" +
|
82
|
-
"The first line of the highlight\n" +
|
83
|
-
"The second line of the highlight"
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'returns a highlight' do
|
87
|
-
expect(subject.type).to eq :highlight
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'extracts the highlighted text' do
|
91
|
-
expect(subject.text).to eq "The first line of the highlight\nThe second line of the highlight"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'passed an entry that is a 4th-generation highlight' do
|
96
|
-
let (:entry_text) do
|
97
|
-
"Book title\n" +
|
98
|
-
"- Your Highlight Location 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
99
|
-
"\n" +
|
100
|
-
"The first line of the highlight\n" +
|
101
|
-
"The second line of the highlight"
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'returns a highlight' do
|
105
|
-
expect(subject.type).to eq :highlight
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'extracts the highlighted text' do
|
109
|
-
expect(subject.text).to eq "The first line of the highlight\nThe second line of the highlight"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'passed an entry that is a note' do
|
114
|
-
let (:entry_text) do
|
115
|
-
"Book title\n" +
|
116
|
-
"- Note Loc. 623 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
117
|
-
"\n" +
|
118
|
-
"The note text"
|
119
|
-
end
|
120
|
-
|
121
|
-
it 'returns a note' do
|
122
|
-
expect(subject.type).to eq :note
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'extracts the note text' do
|
126
|
-
expect(subject.text).to eq "The note text"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
context 'passed an entry that is a 4th-generation note' do
|
131
|
-
let (:entry_text) do
|
132
|
-
"Book title\n" +
|
133
|
-
"- Your Note Location 623 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
134
|
-
"\n" +
|
135
|
-
"The note text"
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'returns a note' do
|
139
|
-
expect(subject.type).to eq :note
|
140
|
-
end
|
141
|
-
|
142
|
-
it 'extracts the note text' do
|
143
|
-
expect(subject.text).to eq "The note text"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'passed an entry with a bookmark' do
|
148
|
-
let (:entry_text) do
|
149
|
-
"Book title\n" +
|
150
|
-
"- Bookmark on Page 1 | Loc. 406 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
151
|
-
"\n" +
|
152
|
-
"\n"
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'returns a bookmark' do
|
156
|
-
expect(subject.type).to eq :bookmark
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'extracts empty text' do
|
160
|
-
expect(subject.text).to eq ""
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context 'passed an entry with a 4th-generation bookmark' do
|
165
|
-
let (:entry_text) do
|
166
|
-
"Book title\n" +
|
167
|
-
"- Your Bookmark on Page 1 | Location 406 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
168
|
-
"\n" +
|
169
|
-
"\n"
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'returns a bookmark' do
|
173
|
-
expect(subject.type).to eq :bookmark
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'extracts empty text' do
|
177
|
-
expect(subject.text).to eq ""
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
context 'passed an entry with a single location value' do
|
182
|
-
let (:entry_text) do
|
183
|
-
"Book title\n" +
|
184
|
-
"- Highlight Loc. 465 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
185
|
-
"\n" +
|
186
|
-
"The first line of the highlight\n" +
|
187
|
-
"The second line of the highlight"
|
188
|
-
end
|
189
|
-
|
190
|
-
it 'returns the correct location' do
|
191
|
-
expect(subject.location).to eq 465
|
192
|
-
end
|
193
|
-
|
194
|
-
it 'returns the correct added date' do
|
195
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
context 'passed a 4th-generation entry with a single location value' do
|
200
|
-
let (:entry_text) do
|
201
|
-
"Book title\n" +
|
202
|
-
"- Your Highlight Location 465 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
203
|
-
"\n" +
|
204
|
-
"The first line of the highlight\n" +
|
205
|
-
"The second line of the highlight"
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'returns the correct location' do
|
209
|
-
expect(subject.location).to eq 465
|
210
|
-
end
|
211
|
-
|
212
|
-
it 'returns the correct added date' do
|
213
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
context 'passed an entry with a location range' do
|
218
|
-
let (:entry_text) do
|
219
|
-
"Book title\n" +
|
220
|
-
"- Highlight Loc. 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
221
|
-
"\n" +
|
222
|
-
"The first line of the highlight\n" +
|
223
|
-
"The second line of the highlight"
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'extracts the first element of the location range' do
|
227
|
-
expect(subject.location).to eq 466
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'returns the correct added date' do
|
231
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
context 'passed a 4th-generation entry with a location range' do
|
236
|
-
let (:entry_text) do
|
237
|
-
"Book title\n" +
|
238
|
-
"- Your Highlight Location 466-69 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
239
|
-
"\n" +
|
240
|
-
"The first line of the highlight\n" +
|
241
|
-
"The second line of the highlight"
|
242
|
-
end
|
243
|
-
|
244
|
-
it 'extracts the first element of the location range' do
|
245
|
-
expect(subject.location).to eq 466
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'returns the correct added date' do
|
249
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
context 'passed an entry with a page number and location range' do
|
254
|
-
let (:entry_text) do
|
255
|
-
"Book title\n" +
|
256
|
-
"- Highlight on Page 171 | Loc. 1858-59 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
257
|
-
"\n" +
|
258
|
-
"Some highlighted text\n" +
|
259
|
-
"\n"
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'extracts the first element of the location range' do
|
263
|
-
expect(subject.location).to eq 1858
|
264
|
-
end
|
265
|
-
|
266
|
-
it 'extracts the page number' do
|
267
|
-
expect(subject.page).to eq 171
|
268
|
-
end
|
269
|
-
|
270
|
-
it 'returns the correct added date' do
|
271
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
context 'passed a 4th-generation entry with a page number and location range' do
|
276
|
-
let (:entry_text) do
|
277
|
-
"Book title\n" +
|
278
|
-
"- Your Highlight on Page 171 | Location 1858-59 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
279
|
-
"\n" +
|
280
|
-
"Some highlighted text\n" +
|
281
|
-
"\n"
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'extracts the first element of the location range' do
|
285
|
-
expect(subject.location).to eq 1858
|
286
|
-
end
|
287
|
-
|
288
|
-
it 'extracts the page number' do
|
289
|
-
expect(subject.page).to eq 171
|
290
|
-
end
|
291
|
-
|
292
|
-
it 'returns the correct added date' do
|
293
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
context 'passed an entry with a page number and no location' do
|
298
|
-
let (:entry_text) do
|
299
|
-
"Book title\n" +
|
300
|
-
"- Highlight on Page 9 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
301
|
-
"\n" +
|
302
|
-
"Clipping"
|
303
|
-
end
|
304
|
-
|
305
|
-
it 'sets location to 0' do
|
306
|
-
expect(subject.location).to eq 0
|
307
|
-
end
|
308
|
-
|
309
|
-
it 'extracts the page number' do
|
310
|
-
expect(subject.page).to eq 9
|
311
|
-
end
|
312
|
-
|
313
|
-
it 'returns the correct added date' do
|
314
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
context 'passed a 4th-generation entry with a page number and no location' do
|
319
|
-
let (:entry_text) do
|
320
|
-
"Book title\n" +
|
321
|
-
"- Your Highlight on Page 9 | Added on Thursday, April 21, 2011, 07:31 AM\n" +
|
322
|
-
"\n" +
|
323
|
-
"Clipping"
|
324
|
-
end
|
325
|
-
|
326
|
-
it 'sets location to 0' do
|
327
|
-
expect(subject.location).to eq 0
|
328
|
-
end
|
329
|
-
|
330
|
-
it 'extracts the page number' do
|
331
|
-
expect(subject.page).to eq 9
|
332
|
-
end
|
333
|
-
|
334
|
-
it 'returns the correct added date' do
|
335
|
-
expect(subject.added_on).to eq DateTime.parse('Thursday, April 21, 2011, 07:31 AM')
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
339
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe Klipbook::Sources::KindleDevice::FileParser do
|
6
|
-
|
7
|
-
let(:parser) { Klipbook::Sources::KindleDevice::FileParser.new(entry_parser) }
|
8
|
-
|
9
|
-
let(:entry_parser) do
|
10
|
-
double('parser', build_entry: nil)
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#extract_entries' do
|
14
|
-
subject { parser.extract_entries(raw_text) }
|
15
|
-
|
16
|
-
context 'called with empty text' do
|
17
|
-
|
18
|
-
let(:raw_text) { '' }
|
19
|
-
|
20
|
-
it 'return an empty set of entries' do
|
21
|
-
expect(subject).to be_empty
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'called with text containing two entries' do
|
26
|
-
let(:raw_text) do
|
27
|
-
" entry one" +
|
28
|
-
"==========" +
|
29
|
-
" entry two" +
|
30
|
-
"=========="
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'builds two entries with the entries parser and returns them' do
|
34
|
-
entry_one = Object.new
|
35
|
-
entry_two = Object.new
|
36
|
-
|
37
|
-
allow(entry_parser).to receive(:build_entry).with(' entry one') { entry_one }
|
38
|
-
allow(entry_parser).to receive(:build_entry).with(' entry two') { entry_two }
|
39
|
-
|
40
|
-
expect(subject).to eq [ entry_one, entry_two ]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context 'called with text containing carriage return characters' do
|
45
|
-
let(:raw_text) do
|
46
|
-
"Example \r text\r" +
|
47
|
-
"=========="
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'strips carriage returns before calling the entry parser' do
|
51
|
-
subject
|
52
|
-
expect(entry_parser).to have_received(:build_entry).with('Example text')
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'called with text containing control characters' do
|
57
|
-
let(:raw_text) do
|
58
|
-
"Example \xef\xbb\xbf text\xef\xbb\xbf" +
|
59
|
-
"=========="
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'strips control characters before calling the entry parser' do
|
63
|
-
subject
|
64
|
-
expect(entry_parser).to have_received(:build_entry).with('Example text')
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|