kindle 0.1.3 → 0.7.0.beta2
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 +1 -0
- data/CHANGELOG.adoc +44 -0
- data/CODE_OF_CONDUCT.adoc +73 -0
- data/Gemfile +14 -2
- data/LICENSE +1 -1
- data/README.adoc +180 -0
- data/bin/kindle +2 -19
- data/features/highlights.feature +117 -0
- data/features/support/aruba.rb +1 -0
- data/features/support/highlight_steps.rb +13 -0
- data/kindle.gemspec +11 -7
- data/lib/kindle.rb +18 -17
- data/lib/kindle/cli.rb +115 -0
- data/lib/kindle/exports/csv.rb +15 -0
- data/lib/kindle/exports/json.rb +12 -0
- data/lib/kindle/exports/markdown.rb +18 -0
- data/lib/kindle/migrations/base_migration.rb +22 -0
- data/lib/kindle/migrations/initializer.rb +13 -0
- data/lib/kindle/models/book.rb +26 -0
- data/lib/kindle/models/highlight.rb +24 -0
- data/lib/kindle/parser/agent.rb +13 -0
- data/lib/kindle/parser/annotations.rb +130 -0
- data/lib/kindle/remote/book.rb +14 -0
- data/lib/kindle/remote/highlight.rb +12 -0
- data/lib/kindle/settings.rb +51 -0
- data/templates/database.yml +11 -0
- data/test/cli_test.rb +0 -0
- data/test/highlights_test.rb +13 -0
- data/test/kindle_test.rb +17 -0
- metadata +98 -17
- data/.rvmrc +0 -1
- data/Changelog +0 -24
- data/README.md +0 -19
- data/lib/kindle/highlight.rb +0 -13
- data/lib/kindle/highlights_parser.rb +0 -105
- data/lib/kindle/version.rb +0 -3
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kindle
|
2
|
+
module Remote
|
3
|
+
class Book
|
4
|
+
attr_accessor :asin, :title, :author, :highlight_count, :highlights
|
5
|
+
def initialize(asin, options = {})
|
6
|
+
@asin = asin
|
7
|
+
@title = options[:title]
|
8
|
+
@author = options[:author]
|
9
|
+
@highlight_count = options[:highlight_count]
|
10
|
+
@highlights = []
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Kindle
|
2
|
+
class Settings
|
3
|
+
|
4
|
+
KINDLE_SETTINGS_DIRECTORY = "#{ENV["HOME"]}/.kindle"
|
5
|
+
KINDLE_SETTINGS_FILENAME = "#{KINDLE_SETTINGS_DIRECTORY}/kindlerc.yml"
|
6
|
+
KINDLE_DATABASE_FILENAME = "#{KINDLE_SETTINGS_DIRECTORY}/database.yml"
|
7
|
+
|
8
|
+
attr_reader :settings
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
create_default_settings_directory unless Dir.exists?(KINDLE_SETTINGS_DIRECTORY)
|
12
|
+
create_default_files unless File.exists?(KINDLE_SETTINGS_FILENAME)
|
13
|
+
@settings = YAML.load(File.open(KINDLE_SETTINGS_FILENAME).read) || {}
|
14
|
+
settings.each do |name, value|
|
15
|
+
set_variable(name.to_s, value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def url
|
20
|
+
if domain.blank?
|
21
|
+
raise "Please set :domain: in your settings file!"
|
22
|
+
else
|
23
|
+
"https://kindle.#{domain}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def create_default_settings_directory
|
30
|
+
Dir.mkdir KINDLE_SETTINGS_DIRECTORY
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_default_files
|
34
|
+
create_default_database_settings
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_default_database_settings
|
38
|
+
File.open(KINDLE_SETTINGS_FILENAME, "w") {|f| f << default_database_settings }
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_database_settings
|
42
|
+
File.open("templates/database.yml").read
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_variable(name, value)
|
46
|
+
instance_variable_set("@#{name}", value)
|
47
|
+
self.class.class_eval { attr_accessor name.intern }
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/test/cli_test.rb
ADDED
File without changes
|
data/test/kindle_test.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative "../lib/kindle"
|
2
|
+
|
3
|
+
describe "Kindle" do
|
4
|
+
|
5
|
+
def login; "jo@nx.is"; end
|
6
|
+
def password; "seekrut1"; end
|
7
|
+
|
8
|
+
it "should be doing generally okay" do
|
9
|
+
expect { Kindle::HighlightsParser.new(login: login, password: password) }.not_to raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'does something' do
|
13
|
+
khp = Kindle::HighlightsParser.new(login: login, password: password)
|
14
|
+
expect { khp.get_highlights }.to_not raise_error
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kindle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Petty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: gli
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
@@ -25,7 +39,21 @@ dependencies:
|
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
42
|
+
name: activerecord
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - ">="
|
@@ -52,7 +80,36 @@ dependencies:
|
|
52
80
|
- - ">="
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '0'
|
55
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rainbow
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: 'Manage your Amazon Kindle highlights: Sync and cache to an ActiveRecord
|
112
|
+
database and output in various formats'
|
56
113
|
email:
|
57
114
|
- matt@kizmeta.com
|
58
115
|
executables:
|
@@ -61,19 +118,36 @@ extensions: []
|
|
61
118
|
extra_rdoc_files: []
|
62
119
|
files:
|
63
120
|
- ".gitignore"
|
64
|
-
-
|
65
|
-
-
|
121
|
+
- CHANGELOG.adoc
|
122
|
+
- CODE_OF_CONDUCT.adoc
|
66
123
|
- Gemfile
|
67
124
|
- LICENSE
|
68
|
-
- README.
|
125
|
+
- README.adoc
|
69
126
|
- Rakefile
|
70
127
|
- bin/kindle
|
128
|
+
- features/highlights.feature
|
129
|
+
- features/support/aruba.rb
|
130
|
+
- features/support/highlight_steps.rb
|
71
131
|
- kindle.gemspec
|
72
132
|
- lib/kindle.rb
|
73
|
-
- lib/kindle/
|
74
|
-
- lib/kindle/
|
75
|
-
- lib/kindle/
|
76
|
-
|
133
|
+
- lib/kindle/cli.rb
|
134
|
+
- lib/kindle/exports/csv.rb
|
135
|
+
- lib/kindle/exports/json.rb
|
136
|
+
- lib/kindle/exports/markdown.rb
|
137
|
+
- lib/kindle/migrations/base_migration.rb
|
138
|
+
- lib/kindle/migrations/initializer.rb
|
139
|
+
- lib/kindle/models/book.rb
|
140
|
+
- lib/kindle/models/highlight.rb
|
141
|
+
- lib/kindle/parser/agent.rb
|
142
|
+
- lib/kindle/parser/annotations.rb
|
143
|
+
- lib/kindle/remote/book.rb
|
144
|
+
- lib/kindle/remote/highlight.rb
|
145
|
+
- lib/kindle/settings.rb
|
146
|
+
- templates/database.yml
|
147
|
+
- test/cli_test.rb
|
148
|
+
- test/highlights_test.rb
|
149
|
+
- test/kindle_test.rb
|
150
|
+
homepage: https://github.com/lodestone/kindle
|
77
151
|
licenses: []
|
78
152
|
metadata: {}
|
79
153
|
post_install_message:
|
@@ -87,13 +161,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
87
161
|
version: '0'
|
88
162
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
163
|
requirements:
|
90
|
-
- - "
|
164
|
+
- - ">"
|
91
165
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
166
|
+
version: 1.3.1
|
93
167
|
requirements: []
|
94
168
|
rubyforge_project: kindle
|
95
|
-
rubygems_version: 2.
|
169
|
+
rubygems_version: 2.6.6
|
96
170
|
signing_key:
|
97
171
|
specification_version: 4
|
98
|
-
summary: Manage your kindle highlights with ruby
|
99
|
-
|
172
|
+
summary: Manage your kindle highlights with ruby, output in JSON, Markdown, and CSV
|
173
|
+
formats
|
174
|
+
test_files:
|
175
|
+
- features/highlights.feature
|
176
|
+
- features/support/aruba.rb
|
177
|
+
- features/support/highlight_steps.rb
|
178
|
+
- test/cli_test.rb
|
179
|
+
- test/highlights_test.rb
|
180
|
+
- test/kindle_test.rb
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm gemset use kindle
|
data/Changelog
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# Version 0.1.2
|
2
|
-
|
3
|
-
* Also retrieve the highlight annotation_id
|
4
|
-
|
5
|
-
# Version 0.1.1
|
6
|
-
|
7
|
-
* Fix renamed file require
|
8
|
-
|
9
|
-
# Version 0.1.0
|
10
|
-
|
11
|
-
* Confirm the script still works as of 2014-04-10
|
12
|
-
* Make the default command line output semi-colon delimited
|
13
|
-
|
14
|
-
# Version 0.0.3
|
15
|
-
|
16
|
-
* Update headers in requests to get pages of highlights
|
17
|
-
|
18
|
-
# Version 0.0.2
|
19
|
-
|
20
|
-
* Use highline to read command line information
|
21
|
-
|
22
|
-
# Version 0.0.1
|
23
|
-
|
24
|
-
* Initial working version
|
data/README.md
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# Kindle Highlights Fetcher
|
2
|
-
|
3
|
-
This little application will fetch a list of all your highlights from your kindle ebooks.
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
gem install kindle
|
8
|
-
|
9
|
-
## Usage
|
10
|
-
|
11
|
-
kindle # Will prompt you for your login info. Don't worry it isn't stored.
|
12
|
-
|
13
|
-
## Other usage and license
|
14
|
-
|
15
|
-
Hastily thrown together but incredibly useful since Amazon does not provide an API for kindle highlights. Please use this however you would like. This is licensed under MIT license.
|
16
|
-
|
17
|
-
|
18
|
-
© 2012 Matt Petty
|
19
|
-
[@lodestone](http://about.me/lodestone)
|
data/lib/kindle/highlight.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
module Kindle
|
2
|
-
|
3
|
-
class HighlightsParser
|
4
|
-
|
5
|
-
include Nokogiri
|
6
|
-
|
7
|
-
KINDLE_URL = 'http://kindle.amazon.com'
|
8
|
-
|
9
|
-
def initialize(options = {:login => nil, :password => nil})
|
10
|
-
options.each_pair { |k,v| instance_variable_set("@#{k}", v) }
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_highlights
|
14
|
-
state = {
|
15
|
-
current_offset: 25,
|
16
|
-
current_upcoming: []
|
17
|
-
}
|
18
|
-
|
19
|
-
page = login
|
20
|
-
fetch_highlights(page, state)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def agent
|
26
|
-
return @agent if @agent
|
27
|
-
@agent = Mechanize.new
|
28
|
-
@agent.redirect_ok = true
|
29
|
-
@agent.user_agent_alias = 'Windows IE 9'
|
30
|
-
@agent
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_login_page
|
34
|
-
page = agent.get(KINDLE_URL)
|
35
|
-
page.link_with(href: "https://kindle.amazon.com/login").click
|
36
|
-
end
|
37
|
-
|
38
|
-
def login
|
39
|
-
login_form = get_login_page.forms.first
|
40
|
-
login_form.email = @login
|
41
|
-
login_form.password = @password
|
42
|
-
|
43
|
-
page = login_form.submit
|
44
|
-
page.forms.first.submit
|
45
|
-
end
|
46
|
-
|
47
|
-
def fetch_highlights(page, state)
|
48
|
-
page = get_the_first_highlight_page_from(page, state)
|
49
|
-
|
50
|
-
highlights = []
|
51
|
-
|
52
|
-
new_highlights = extract_highlights_from(page, state)
|
53
|
-
|
54
|
-
until new_highlights.length == 0 do
|
55
|
-
highlights << new_highlights
|
56
|
-
page = get_the_next_page(state, highlights.flatten)
|
57
|
-
new_highlights = extract_highlights_from(page, state)
|
58
|
-
end
|
59
|
-
|
60
|
-
highlights.flatten
|
61
|
-
end
|
62
|
-
|
63
|
-
def get_the_first_highlight_page_from(page, state)
|
64
|
-
page = page.link_with(:text => 'Your Highlights').click
|
65
|
-
initialize_state_with_page state, page
|
66
|
-
page
|
67
|
-
end
|
68
|
-
|
69
|
-
def extract_highlights_from(page, state)
|
70
|
-
return [] if (page/".yourHighlight").length == 0
|
71
|
-
(page/".yourHighlight").map { |hl| parse_highlight(hl, state) }
|
72
|
-
end
|
73
|
-
|
74
|
-
def initialize_state_with_page(state, page)
|
75
|
-
return if (page/".yourHighlight").length == 0
|
76
|
-
state[:current_upcoming] = (page/".upcoming").first.text.split(',') rescue []
|
77
|
-
state[:title] = (page/".yourHighlightsHeader .title").text.to_s.strip
|
78
|
-
state[:author] = (page/".yourHighlightsHeader .author").text.to_s.strip
|
79
|
-
state[:current_offset] = ((page/".yourHighlightsHeader").collect{|h| h.attributes['id'].value }).first.split('_').last
|
80
|
-
end
|
81
|
-
|
82
|
-
def get_the_next_page(state, previously_extracted_highlights = [])
|
83
|
-
asins = previously_extracted_highlights.map(&:asin).uniq
|
84
|
-
asins_string = asins.collect { |asin| "used_asins[]=#{asin}" } * '&'
|
85
|
-
upcoming_string = state[:current_upcoming].map { |l| "upcoming_asins[]=#{l}" } * '&'
|
86
|
-
url = "https://kindle.amazon.com/your_highlights/next_book?#{asins_string}¤t_offset=#{state[:current_offset]}&#{upcoming_string}"
|
87
|
-
ajax_headers = { 'X-Requested-With' => 'XMLHttpRequest', 'Host' => 'kindle.amazon.com' }
|
88
|
-
page = agent.get(url,[],'https://kindle.amazon.com/your_highlight', ajax_headers)
|
89
|
-
|
90
|
-
initialize_state_with_page state, page
|
91
|
-
|
92
|
-
page
|
93
|
-
end
|
94
|
-
|
95
|
-
def parse_highlight(hl, state)
|
96
|
-
highlight_id = hl.xpath('//*[@id="annotation_id"]').first["value"]
|
97
|
-
highlight = (hl/".highlight").text
|
98
|
-
asin = (hl/".asin").text
|
99
|
-
Highlight.new(highlight_id, highlight, asin, state[:title], state[:author])
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
end
|
105
|
-
|