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 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
@@ -0,0 +1,3 @@
1
+ module KindleHighlightsAPI
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,8 @@
1
+ require "kindle_highlights_api/version"
2
+ require "logger"
3
+
4
+ module KindleHighlightsAPI
5
+ end
6
+
7
+ require_relative 'kindle_highlights_api/book'
8
+ require_relative 'kindle_highlights_api/fetcher'
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