bookle 0.0.1

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.
@@ -0,0 +1,26 @@
1
+ require 'bookle/google_books_epub'
2
+ require 'bookle/google_books_pdf'
3
+
4
+ module Google
5
+ module Books
6
+ class AccessInfo
7
+ attr_reader :access_country, :viewability, :embeddable, :public_domain, :text_to_speech_permission, :epub, :pdf, :web_reader_link,
8
+ :access_view_status
9
+
10
+ def initialize(access_info)
11
+ if access_info
12
+ @access_country = access_info["country"]
13
+ @viewability = access_info["viewability"]
14
+ @embeddable = access_info["embeddable"]
15
+ @public_domain = access_info["publicDomain"]
16
+ @text_to_speech_permission = access_info["textToSpeechPermission"]
17
+ @epub = Google::Books::Epub.new(access_info["epub"])
18
+ @pdf = Google::Books::Pdf.new(access_info["pdf"])
19
+ @web_reader_link = access_info["webReaderLink"]
20
+ @access_view_status = access_info["accessViewStatus"]
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,155 @@
1
+ # OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
2
+ # Solution to SSL problem on Windows:
3
+ # https://gist.github.com/867550
4
+ # https://www.googleapis.com/books/v1/volumes?key=AIzaSyAUJ0psGl0udam2kFzT29L2YWAhCF748ik&q=inauthor:keyes&maxResults=40&startIndex=40
5
+
6
+ require 'net/https'
7
+ require 'bookle/google_books_items'
8
+
9
+ module Google
10
+ module Books
11
+ class API
12
+
13
+ GOOGLE_OPTIONAL_PARAMETERS = {
14
+ 'start_index_at' => 'startIndex', # starts at 0 (default)
15
+ 'maximum_results' => 'maxResults' # [0..40], default=10
16
+ }
17
+
18
+ # Prefixed some of the keywords with 'in_' to convey the Google meaning that the value is found *in* the content.
19
+ # Google differentiates between *in* content and *is* content.
20
+ GOOGLE_QUERY_KEYWORDS = {
21
+ 'title' => 'intitle',
22
+ 'author' => 'inauthor',
23
+ 'publisher' => 'inpublisher',
24
+ 'subject' => 'subject', # *in* subject
25
+ 'isbn' => 'isbn', # ISBN
26
+ 'lccn' => 'lccn', # Library of Congress Control Number
27
+ 'oclc' => 'oclc' # Online Computer Library Center number
28
+ }
29
+
30
+ attr_reader :total_volumes, :volumes, :volume, :raw_response
31
+
32
+ attr_accessor *(GOOGLE_QUERY_KEYWORDS.keys + GOOGLE_OPTIONAL_PARAMETERS.keys).map{|method_name| method_name.to_sym} << :google_books_api_key
33
+
34
+ def initialize(google_books_api_key)
35
+ @google_books_api_key = google_books_api_key
36
+ @total_volumes = 0
37
+ @volumes = []
38
+ end
39
+
40
+ def search_accessors
41
+ GOOGLE_QUERY_KEYWORDS.keys + GOOGLE_OPTIONAL_PARAMETERS.keys
42
+ end
43
+
44
+ def clear_search_options
45
+ search_accessors.each do |method_name|
46
+ __send__ "#{method_name}=".to_sym, nil
47
+ end
48
+
49
+ nil
50
+ end
51
+
52
+ # Build and also let the user query the string.
53
+ # schema = https
54
+ # host = www.googleapis.com`
55
+ # path = books/v1/volumes
56
+ # key marker = key
57
+ # query marker = q
58
+ # keyword separator = + (used in build_query_options())
59
+ def uri_string
60
+ "https://www.googleapis.com/books/v1/volumes?key=#{@google_books_api_key}#{build_optional_parameters}&q=#{build_query_options}"
61
+ end
62
+
63
+ # The Google Books API builds its query using 'OR', not 'AND'. That means that the more keywords used during the search
64
+ # the wider the range of results.
65
+ # When search options are passed to this method prior search options set with the set_search_option method will be disregarded.
66
+ # def search(isbn='9780140196092')
67
+ def search
68
+ google_response = nil
69
+ uri = URI(uri_string)
70
+ http = Net::HTTP.new(uri.host, uri.port)
71
+ http.use_ssl = uri.scheme == 'https'
72
+ http.ca_file = cacert_path
73
+
74
+ http.start {http.request_get("#{uri.path}?#{uri.query}") {|response| @raw_response = response.body}}
75
+
76
+ items = Google::Books::Items.new(@raw_response)
77
+
78
+ @total_volumes = items.total_items || 0
79
+ @volumes = items.items || []
80
+ @volume = volumes.first
81
+
82
+ items
83
+ end
84
+
85
+
86
+ # cacert = certification authority certificates
87
+ def update_cacert_file
88
+ file_path = cacert_path
89
+
90
+ Net::HTTP.start("curl.haxx.se") do |http|
91
+ resp = http.get("/ca/cacert.pem")
92
+
93
+ if resp.code == "200"
94
+ File.delete("#{file_path}_old") if File.exists?("#{file_path}_old")
95
+ File.rename(file_path, "#{file_path}_old")
96
+ File.open(file_path, "w") {|file| file.write(resp.body)}
97
+
98
+ puts "\n\nAn updated version of the file with the certfication authority certificates has been installed to"
99
+ puts "#{cacert_path}\n\n"
100
+ else
101
+ puts "\n\nUnable to download a new version of the certification authority certificates.\n"
102
+ end
103
+ end
104
+ rescue => e
105
+ puts "\n\nErrors were encountered while updating the certification authority certificates file.\n"
106
+
107
+ unless File.exists?(file_path)
108
+ if File.exists?("#{file_path}_old")
109
+ File.rename("#{file_path}_old", file_path)
110
+ else
111
+ puts "\nThe certification authority certificates file could not be found nor restored.\n"
112
+ end
113
+ end
114
+
115
+ puts "\nError information:\n"
116
+ puts e.message
117
+ end
118
+
119
+
120
+ private
121
+
122
+ def build_optional_parameters
123
+ string = ''
124
+
125
+ GOOGLE_OPTIONAL_PARAMETERS.each do |method_name, query_parameter|
126
+ unless __send__(method_name.to_sym).nil?
127
+ # Need to escape values or search might fail due to spaces, etc.
128
+ string += "&#{query_parameter}=#{URI.escape(__send__(method_name.to_sym).to_s)}"
129
+ end
130
+ end
131
+
132
+ string
133
+ end
134
+
135
+ def build_query_options
136
+ string = ''
137
+
138
+ GOOGLE_QUERY_KEYWORDS.each do |method_name, query_keyword|
139
+ unless __send__(method_name.to_sym).nil?
140
+ # Need to escape values or search might fail due to spaces, etc.
141
+ string += "#{query_keyword}:#{URI.escape(__send__(method_name.to_sym).to_s)}+"
142
+ end
143
+ end
144
+
145
+ # Return string except for last keyword separator.
146
+ string.chop
147
+ end
148
+
149
+ def cacert_path
150
+ File.dirname(`gem which bookle`.chomp) + '/cacert/cacert.pem'
151
+ end
152
+
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,18 @@
1
+ module Google
2
+ module Books
3
+ class Epub
4
+ attr_reader :is_available
5
+
6
+ def initialize(epub)
7
+ if epub
8
+ @is_available = epub["isAvailable"]
9
+ end
10
+ end
11
+
12
+ def to_hash
13
+ {"is_epub_available" => self.is_available}
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Google
2
+ module Books
3
+ class ImageLinks
4
+ attr_reader :small_thumbnail, :thumbnail
5
+
6
+ def initialize(image_links)
7
+ if image_links
8
+ @small_thumbnail = image_links["smallThumbnail"]
9
+ @thumbnail = image_links["thumbnail"]
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Google
2
+ module Books
3
+ class IndustryIdentifier
4
+ attr_reader :type, :identifier
5
+
6
+ def initialize(identifier)
7
+ @type = identifier["type"]
8
+ @identifier = identifier["identifier"]
9
+ end
10
+
11
+ def to_hash
12
+ {self.type.downcase => self.identifier}
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ require 'hasherizer'
2
+ require 'bookle/google_books_volume_info'
3
+ require 'bookle/google_books_sale_info'
4
+ require 'bookle/google_books_access_info'
5
+ require 'bookle/google_books_search_info'
6
+
7
+ module Google
8
+ module Books
9
+ class Item
10
+ attr_reader :kind, :id, :etag, :self_link, :volume_info, :sale_info, :access_info, :search_info
11
+
12
+ def initialize(item)
13
+ @kind = item["kind"]
14
+ @id = item["id"]
15
+ @etag = item["etag"]
16
+ @self_link = item["selfLink"]
17
+ @volume_info = Google::Books::VolumeInfo.new(item["volumeInfo"])
18
+ @sale_info = Google::Books::SaleInfo.new(item["saleInfo"])
19
+ @access_info = Google::Books::AccessInfo.new(item["accessInfo"])
20
+ @search_info = Google::Books::SearchInfo.new(item["searchInfo"])
21
+ end
22
+
23
+ def hash
24
+ Hasherizer.to_hash(self)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+ require 'bookle/google_books_item'
3
+
4
+ module Google
5
+ module Books
6
+ class Items
7
+ attr_reader :kind, :total_items, :items
8
+
9
+ def initialize(google_response)
10
+ books_info = JSON.parse(google_response)
11
+
12
+ @kind = books_info["kind"]
13
+ @total_items = books_info["totalItems"] || 0
14
+
15
+ if books_info["items"]
16
+ @items = books_info["items"].collect {|item| Google::Books::Item.new(item)}
17
+ else
18
+ @items = []
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require 'bookle/google_books_price'
2
+
3
+ module Google
4
+ module Books
5
+ class ListPrice < Google::Books::Price
6
+
7
+ def to_hash
8
+ {"list_price_amount" => self.amount, "list_price_currency_code" => self.currency_code}
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Google
2
+ module Books
3
+ class Pdf
4
+ attr_reader :is_available
5
+
6
+ def initialize(pdf)
7
+ if pdf
8
+ @is_available = pdf["isAvailable"]
9
+ end
10
+ end
11
+
12
+ def to_hash
13
+ {"is_pdf_available" => self.is_available}
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Google
2
+ module Books
3
+ class Price
4
+ attr_reader :amount, :currency_code
5
+
6
+ def initialize(price)
7
+ if price
8
+ @amount = price["amount"]
9
+ @currency_code = price["currencyCode"]
10
+ end
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require 'bookle/google_books_price'
2
+
3
+ module Google
4
+ module Books
5
+ class RetailPrice < Google::Books::Price
6
+
7
+ def to_hash
8
+ {"retail_price_amount" => self.amount, "retail_price_currency_code" => self.currency_code}
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ require 'bookle/google_books_list_price'
2
+ require 'bookle/google_books_retail_price'
3
+
4
+ module Google
5
+ module Books
6
+ class SaleInfo
7
+ attr_reader :sale_country, :saleability, :is_ebook, :list_price, :retail_price, :buy_link
8
+
9
+ def initialize(sale_info)
10
+ if sale_info
11
+ @sale_country = sale_info["country"]
12
+ @saleability = sale_info["saleability"]
13
+ @is_ebook = sale_info["isEbook"]
14
+ @list_price = Google::Books::ListPrice.new(sale_info["listPrice"])
15
+ @retail_price = Google::Books::RetailPrice.new(sale_info["retailPrice"])
16
+ @buy_link = sale_info["buyLink"]
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ module Google
2
+ module Books
3
+ class SearchInfo
4
+ attr_reader :text_snippet
5
+
6
+ def initialize(search_info)
7
+ if search_info
8
+ @text_snippet = search_info["textSnippet"]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ require 'bookle/google_books_industry_identifier'
2
+ require 'bookle/google_books_image_links'
3
+
4
+ module Google
5
+ module Books
6
+ class VolumeInfo
7
+ attr_reader :title, :subtitle, :authors, :publisher, :published_date, :description, :industry_identifiers, :page_count,
8
+ :print_type, :categories, :average_rating, :ratings_count, :content_version, :image_links, :language, :preview_link,
9
+ :info_link, :canonical_volume_link
10
+
11
+ def initialize(volume_info)
12
+ if volume_info
13
+ @title = volume_info["title"]
14
+ @subtitle = volume_info["subtitle"]
15
+ @authors = volume_info["authors"]
16
+ @publisher = volume_info["publisher"]
17
+ @published_date = volume_info["published_date"]
18
+ @description = volume_info["description"]
19
+ @industry_identifiers = volume_info["industryIdentifiers"].collect do
20
+ |i| Google::Books::IndustryIdentifier.new(i)
21
+ end if volume_info["industryIdentifiers"]
22
+ @page_count = volume_info["pageCount"]
23
+ @print_type = volume_info["printType"]
24
+ @categories = volume_info["categories"]
25
+ @average_rating = volume_info["averageRating"]
26
+ @ratings_count = volume_info["ratingsCount"]
27
+ @content_version = volume_info["contentVersion"]
28
+ @image_links = Google::Books::ImageLinks.new(volume_info["imageLinks"])
29
+ @language = volume_info["language"]
30
+ @preview_link = volume_info["previewLink"]
31
+ @info_link = volume_info["infoLink"]
32
+ @canonical_volume_link = volume_info["canonicalVolumeLink"]
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
data/lib/bookle.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'bookle/google_books_api'
2
+
3
+ class Bookle
4
+ # def self.api(google_books_api_key=nil)
5
+ def self.api(google_books_api_key='AIzaSyAUJ0psGl0udam2kFzT29L2YWAhCF748ik')
6
+ Google::Books::API.new(google_books_api_key)
7
+ end
8
+ end