kindle_highlights_api 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +16 -0
- data/kindle_highlights_api.gemspec +23 -0
- data/lib/kindle_highlights_api/book.rb +19 -0
- data/lib/kindle_highlights_api/fetcher.rb +51 -0
- data/lib/kindle_highlights_api/version.rb +3 -0
- data/lib/kindle_highlights_api.rb +8 -0
- data/test/book_test.rb +26 -0
- data/test/fetcher_test.rb +23 -0
- data/test/fixtures/html/highlights_page_1.html +1054 -0
- data/test/fixtures/html/highlights_page_2.html +362 -0
- data/test/fixtures/html/highlights_page_3.html +1972 -0
- data/test/fixtures/html/highlights_page_4.html +1995 -0
- data/test/fixtures/html/highlights_page_5.html +1397 -0
- data/test/fixtures/html/highlights_page_6.html +385 -0
- data/test/fixtures/html/highlights_page_7.html +174 -0
- data/test/fixtures/html/kindle_home_page.html +588 -0
- data/test/fixtures/html/login_page.html +758 -0
- data/test/fixtures/html/signin_post_response.txt +10 -0
- data/test/test_helper.rb +42 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 206ac339e94e87fb4382f489e9b1eb77dfe67ce2
|
4
|
+
data.tar.gz: df1ef9cd9913b727e96b34108ec603c9efb41138
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4890d220d0a605c901f53ac30a1b158a62c2b7236771f39e6c7b612e6630a310e526d1b840569699b77608bb41a5b234567de7c3c5f5347d96c5a6568377b98
|
7
|
+
data.tar.gz: b1f7b3ecb0eb6624bcb61caab10902da5ffbab8b1e71cc8b16e1f3e40a3869f764887cbb639c41277c2c52c8ab2e3aab7a19d6b021a161f8120c7a49ec0544ef
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
vendor/bundle
|
24
|
+
.DS_Store
|
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in kindle_highlights_api.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'mocha'
|
8
|
+
gem 'fakeweb'
|
9
|
+
gem 'pry'
|
10
|
+
gem 'pry-debugger'
|
11
|
+
gem 'pry-rescue'
|
12
|
+
gem 'pry-stack_explorer'
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Gaurav Chande
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Kindle Highlights API
|
2
|
+
|
3
|
+
A wrapper that helps fetch highlights from Amazon Kindle and play around with them.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'kindle_highlights_api'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install kindle_highlights_api
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'kindle_highlights_api'
|
23
|
+
|
24
|
+
fetcher = KindleHighlightsAPI::Fetcher.new("yourusername@gmail.com", "somepassword")
|
25
|
+
|
26
|
+
books = fetcher.fetch
|
27
|
+
|
28
|
+
books.count # =>
|
29
|
+
19
|
30
|
+
|
31
|
+
books.map(&:title) # =>
|
32
|
+
[
|
33
|
+
"Smalltalk Best Practice Patterns",
|
34
|
+
"Drawing on the Right Side of the Brain: The Definitive, 4th Edition",
|
35
|
+
"Benjamin Franklin: An American Life",
|
36
|
+
"Mucusless Diet Healing System",
|
37
|
+
"Crucial Conversations Tools for Talking When Stakes Are High, Second Edition",
|
38
|
+
"The War of Art",
|
39
|
+
"A Short History of Nearly Everything",
|
40
|
+
"Einstein: His Life and Universe",
|
41
|
+
"Turn the Ship Around!: A True Story of Turning Followers into Leaders",
|
42
|
+
"The 5 Elements of Effective Thinking",
|
43
|
+
...
|
44
|
+
]
|
45
|
+
|
46
|
+
books.first.title # =>
|
47
|
+
"Smalltalk Best Practice Patterns"
|
48
|
+
|
49
|
+
books.first.highlights # =>
|
50
|
+
[
|
51
|
+
"If you are trying to explain why code should be different, it is much more satisfying for you and the learner to be able to discuss the pattern and how it applies to the particular situation.",
|
52
|
+
"I’m constantly amazed at how even a little help cleaning up small problems reveals the source and solution of much bigger problems.",
|
53
|
+
"If you’re programming along, doing nicely, and all of a sudden your program gets balky, makes things hard for you, it’s talking. It’s telling you there is something important missing.",
|
54
|
+
"The problems in the construction of objects are universal. You have to name classes, relate classes via inheritance and delegation, relate methods in the same class and different classes, name variables, and so on. Patterns record these problems and how to approach solving them.",
|
55
|
+
"Keep all of the operations in a method at the same level of abstraction.",
|
56
|
+
"Any time you are sending two or more messages from one object to another in a single method, you may be able to create a Composed Method in the receiver that combines those messages.",
|
57
|
+
"There is probably no coding decision with more effect on the quality of your code than names you give your classes.",
|
58
|
+
"The first thing readers will look at when they look at your code is the names of the classes. Those names will go beyond your code. Insidiously, they leak into everyday conversation—and not just for developers. Ten years down the road, you will hear users who know nothing about programming using the class names you chose.",
|
59
|
+
"Unfortunately, many people get all formal when they go to name a superclass. Just calling it what it is isn’t enough. They have to tack on a flowery, computer science-y, impressive sounding, but ultimately meaningless word, like Object, Thing, Component, Part, Manager, Entity, or Item. You’re creating a vocabulary, not writing a program. Be a poet for a moment. The simple, the punchy, the easily remembered will be far more effective in the long run than some long name that says it all, but in such a way that no one wants to say it at all.",
|
60
|
+
"Name a superclass with a single word that conveys its purpose in the design.",
|
61
|
+
"if I am using inheritance strictly for code sharing, but the role of the subclass is different than the role of the superclass, I go back to Simple Superclass Name."
|
62
|
+
...
|
63
|
+
]
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
1. Fork it ( https://github.com/gauravmc/kindle_highlights_api/fork )
|
70
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
71
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
72
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
73
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
desc 'run all tests'
|
5
|
+
Rake::TestTask.new(:test) do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
t.verbose = true
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'run kindle_highlights_api console'
|
12
|
+
task :console do
|
13
|
+
exec 'pry -I lib -r kindle_highlights_api'
|
14
|
+
end
|
15
|
+
|
16
|
+
task default: :test
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kindle_highlights_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "kindle_highlights_api"
|
8
|
+
spec.version = KindleHighlightsAPI::VERSION
|
9
|
+
spec.authors = ["Gaurav Chande"]
|
10
|
+
spec.email = ["gmail@gauravchande.com"]
|
11
|
+
spec.summary = %q{A wrapper that helps fetch Kindle highlights and play around with them.}
|
12
|
+
spec.homepage = "https://github.com/gauravmc/kindle_highlights_api"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake", "~> 0"
|
22
|
+
spec.add_development_dependency "mechanize", "~> 0"
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module KindleHighlightsAPI
|
2
|
+
class Book
|
3
|
+
def initialize(page)
|
4
|
+
@page = page
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.from_page(page)
|
8
|
+
Book.new(page)
|
9
|
+
end
|
10
|
+
|
11
|
+
def title
|
12
|
+
@title ||= @page.search("span[class=title] a text()").first.content
|
13
|
+
end
|
14
|
+
|
15
|
+
def highlights
|
16
|
+
@highlights ||= @page.search("span[class=highlight] text()").map(&:content)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
|
3
|
+
module KindleHighlightsAPI
|
4
|
+
class Fetcher
|
5
|
+
def initialize(email, password)
|
6
|
+
@email, @password = email, password
|
7
|
+
end
|
8
|
+
|
9
|
+
def fetch
|
10
|
+
fetch_all_books
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def fetch_all_books
|
16
|
+
page = get_highlights_page
|
17
|
+
|
18
|
+
Array.new.tap do |books|
|
19
|
+
while next_book_link = page.link(id: 'nextBookLink') do
|
20
|
+
books << Book.from_page(page)
|
21
|
+
page = next_book_link.click
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_highlights_page
|
27
|
+
kindle_home_page = login_to_amazon_kindle
|
28
|
+
kindle_home_page.link(href: "/your_highlights").click
|
29
|
+
end
|
30
|
+
|
31
|
+
def login_to_amazon_kindle
|
32
|
+
login_page = agent.get("https://kindle.amazon.com/login")
|
33
|
+
|
34
|
+
login_page.form_with(name: 'signIn') do |form|
|
35
|
+
form['email'] = @email
|
36
|
+
form['password'] = @password
|
37
|
+
end.submit
|
38
|
+
end
|
39
|
+
|
40
|
+
def agent
|
41
|
+
@agent ||= Mechanize.new do |a|
|
42
|
+
a.user_agent = 'Individueller User-Agent'
|
43
|
+
a.user_agent_alias = 'Mac Safari'
|
44
|
+
a.open_timeout = 10
|
45
|
+
a.read_timeout = 10
|
46
|
+
a.ssl_version = 'SSLv3'
|
47
|
+
a.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/test/book_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module KindleHighlightsAPI
|
4
|
+
class BookTest < MiniTest::Unit::TestCase
|
5
|
+
def test_from_page_creates_a_book_from_the_page
|
6
|
+
expectation = {
|
7
|
+
title: "Drawing on the Right Side of the Brain: The Definitive, 4th Edition",
|
8
|
+
highlight: "learning to draw, without doubt, causes new connections in the brain that can be useful over a lifetime for general thinking. Learning to see in a different way requires that you use your brain differently."
|
9
|
+
}
|
10
|
+
|
11
|
+
page = create_page_from_fixture(:highlights_page_1)
|
12
|
+
book = Book.from_page(page)
|
13
|
+
|
14
|
+
assert_equal expectation[:title], book.title
|
15
|
+
assert book.highlights.include?(expectation[:highlight])
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def create_page_from_fixture(filename)
|
21
|
+
body = File.open("#{TEST_ROOT}/fixtures/html/#{filename.to_s}.html").read
|
22
|
+
mech = Mechanize.new
|
23
|
+
Mechanize::Page.new(nil, nil, body, nil, mech)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module KindleHighlightsAPI
|
4
|
+
class FetcherTest < MiniTest::Unit::TestCase
|
5
|
+
def test_fetch_returns_an_array_of_all_the_books
|
6
|
+
fetcher = Fetcher.new('some@email.com', 'password')
|
7
|
+
|
8
|
+
books = fetcher.fetch
|
9
|
+
|
10
|
+
expected_books = [
|
11
|
+
"Drawing on the Right Side of the Brain: The Definitive, 4th Edition",
|
12
|
+
"Mucusless Diet Healing System",
|
13
|
+
"Crucial Conversations Tools for Talking When Stakes Are High, Second Edition",
|
14
|
+
"The War of Art",
|
15
|
+
"Smalltalk Best Practice Patterns",
|
16
|
+
"A Short History of Nearly Everything"
|
17
|
+
]
|
18
|
+
|
19
|
+
assert_equal expected_books, books.map(&:title)
|
20
|
+
assert_equal 6, books.size
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|