grobi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ *.swp
4
+ secret.rb
5
+ Gemfile.lock
6
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in grobi.gemspec
4
+ gemspec
@@ -0,0 +1,4 @@
1
+ It try to support google api:
2
+ https://developers.google.com/apis-explorer/#p/
3
+
4
+ and others.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ # Maintain your gem's version:
4
+ require "grobi/version"
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |s|
8
+ s.name = "grobi"
9
+ s.version = Grobi::VERSION
10
+ s.authors = ["Yen-Ju Chen"]
11
+ s.email = ["yjchenx@gmail.com"]
12
+ s.homepage = ""
13
+ s.summary = "Ruby wrapper on google-api-ruby-client and other service"
14
+ s.description = s.summary
15
+
16
+ s.rubyforge_project = "grobi"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_dependency "google-api-client"
24
+ s.add_dependency "nokogiri"
25
+ s.add_development_dependency "rspec"
26
+ s.add_development_dependency "json_spec"
27
+ end
@@ -0,0 +1,10 @@
1
+ require "grobi/version"
2
+ require 'google/api_client'
3
+
4
+ module Grobi
5
+ end
6
+
7
+ require 'grobi/client'
8
+ require 'grobi/books'
9
+ require 'grobi/maps'
10
+ require 'grobi/places'
@@ -0,0 +1,78 @@
1
+ module Grobi
2
+ class Books
3
+ def initialize(client)
4
+ @client = client
5
+ begin
6
+ @book = @client.google.discovered_api('books') if @client
7
+ rescue => the_error
8
+ @error = the_error.message
9
+ puts "Error #{the_error.message}"
10
+ return nil
11
+ end
12
+ end
13
+
14
+ def search(string)
15
+ return nil if @client.nil? || @client.simple_api_key.nil?
16
+ # disable OAuth2
17
+ @client.google.authorization = nil if @client.simple_api_key
18
+ response = @client.google.execute(@book.volumes.list, {:q => string, :key => @client.simple_api_key})
19
+ parse(response.body)
20
+ end
21
+
22
+ def retrieve(string_or_book)
23
+ if string_or_book.is_a?(String)
24
+ identifier = string_or_book
25
+ book = Book.new
26
+ elsif string_or_book.is_a?(Book)
27
+ identifier = string_or_book.id
28
+ book = string_or_book
29
+ else
30
+ return nil
31
+ end
32
+ response = @client.google.execute(@book.volumes.get, {:volumeId => identifier, :key => @client.simple_api_key})
33
+ book.update(JSON.parse(response.body))
34
+ book
35
+ end
36
+
37
+ def parse(s)
38
+ volumes = JSON.parse(s)
39
+ volumes['items'].collect { |v| Book.new(v) } if volumes['items']
40
+ end
41
+ end
42
+
43
+ class Book
44
+ attr_accessor :title, :authors, :id, :publisher, :published_date
45
+
46
+ def initialize(json)
47
+ super()
48
+ update(json)
49
+ self
50
+ end
51
+
52
+ def update(json)
53
+ @id = json['id']
54
+ volumeInfo = json['volumeInfo']
55
+ @title = volumeInfo['title']
56
+ @authors = volumeInfo['authors']
57
+ @publisher = volumeInfo['publisher']
58
+ @published_date = volumeInfo['publishedDate']
59
+ identifiers = volumeInfo['industryIdentifiers']
60
+ if (identifiers)
61
+ identifiers.each do |isbn|
62
+ self.add_isbn({isbn['type'] => isbn['identifier']})
63
+ end
64
+ end
65
+ self
66
+ end
67
+
68
+ # hash in form of {'type'=>'ISBN_10', 'identifier'=>'123455667'}
69
+ def add_isbn(hash)
70
+ @isbns ||= Hash.new
71
+ @isbns.merge!(hash)
72
+ end
73
+
74
+ def isbn(type = 'ISBN_10')
75
+ @isbns.nil? ? nil : @isbns[type]
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,12 @@
1
+ module Grobi
2
+ class Client
3
+ attr_accessor :simple_api_key #simple api key
4
+ def initialize
5
+ @client = ::Google::APIClient.new
6
+ end
7
+
8
+ def google
9
+ @client
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,65 @@
1
+ require 'json'
2
+
3
+ module Grobi
4
+ class Maps
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # options
10
+ # :language (en, zh-TW, etc.)
11
+ def search(address, ops={})
12
+ href='http://maps.googleapis.com/maps/api/geocode/json'
13
+ conn = Faraday.new
14
+ response = conn.get href do |req|
15
+ req.params['address'] = address
16
+ req.params['sensor'] = 'false'
17
+ req.params['language'] = ops[:language] if ops[:language]
18
+ end
19
+ parse(response.body)
20
+ end
21
+
22
+ def parse(s)
23
+ j = JSON.parse(s)
24
+ if (j['status'] == "OK")
25
+ placemarks = j['results']
26
+ placemarks.collect { |p| Placemark.new(p) } if placemarks
27
+ else
28
+ nil
29
+ end
30
+ end
31
+
32
+ def google
33
+ return @client
34
+ end
35
+ end
36
+
37
+ class Placemark
38
+ attr_accessor :formatted_address, :longitude, :latitude, :country, :city, :locality, :route, :number, :postal_code, :establishment
39
+
40
+ def initialize(json)
41
+ super()
42
+ update(json)
43
+ self
44
+ end
45
+
46
+ def update(json)
47
+ @formatted_address = json['formatted_address']
48
+ if json['geometry']
49
+ @longitude = json['geometry']['location']['lng']
50
+ @latitude = json['geometry']['location']['lat']
51
+ end
52
+ if json['address_components']
53
+ components = json['address_components'].each do |component|
54
+ @establishment = component['long_name'] if component['types'].include?('establishment')
55
+ @country = component['short_name'] if component['types'].include?('country')
56
+ @city = component['long_name'] if component['types'].include?('administrative_area_level_2')
57
+ @locality = component['long_name'] if component['types'].include?('locality')
58
+ @route = component['long_name'] if component['types'].include?('route')
59
+ @number = component['long_name'] if component['types'].include?('street_number')
60
+ @postal_code = component['long_name'] if component['types'].include?('postal_code')
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,81 @@
1
+ module Grobi
2
+ class Places
3
+ attr_accessor :html
4
+ def initialize(client)
5
+ @client = client
6
+ end
7
+
8
+ def search(latitude_or_placemark, longitude = nil, options={})
9
+ if latitude_or_placemark.is_a?(Placemark)
10
+ latitude = latitude_or_placemark.latitude
11
+ longitude = latitude_or_placemark.longitude
12
+ else
13
+ latitude = latitude_or_placemark
14
+ longitude = longitude
15
+ end
16
+ href='https://maps.googleapis.com/maps/api/place/search/json?'
17
+ conn = Faraday.new
18
+ response = conn.get href do |req|
19
+ req.params['key'] = @client.simple_api_key
20
+ req.params['location'] = "#{latitude},#{longitude}"
21
+ req.params['radius'] = 100 # in memter
22
+ req.params['sensor'] = 'false'
23
+ end
24
+ parse(response.body)
25
+ end
26
+
27
+ def retrieve(string_or_place, options={})
28
+ if string_or_place.is_a?(String)
29
+ reference = string_or_place
30
+ place = Place.new
31
+ elsif string_or_place.is_a?(Place)
32
+ reference = string_or_place.reference
33
+ place = string_or_place
34
+ else
35
+ return nil
36
+ end
37
+ href='https://maps.googleapis.com/maps/api/place/details/json?'
38
+ conn = Faraday.new
39
+ response = conn.get href do |req|
40
+ req.params['key'] = @client.simple_api_key
41
+ req.params['sensor'] = 'false'
42
+ req.params['reference'] = reference
43
+ req.params['language'] = options[:language] if options[:language]
44
+ end
45
+ j = JSON.parse(response.body)
46
+ @html = j['html_attributions']
47
+ if (j['status'] == 'OK')
48
+ place.update(j['result'])
49
+ place
50
+ end
51
+ end
52
+
53
+ def parse(s)
54
+ j = JSON.parse(s)
55
+ @html = j['html_attributions']
56
+ if (j['status'] == "OK")
57
+ places = j['results']
58
+ places.collect { |p| Place.new(p) } if places
59
+ else
60
+ nil
61
+ end
62
+ end
63
+
64
+ def google
65
+ return @client
66
+ end
67
+ end
68
+
69
+ class Place < Placemark
70
+ attr_accessor :name, :reference
71
+ def initialize(json)
72
+ super
73
+ end
74
+
75
+ def update(json)
76
+ super
77
+ @name = json['name']
78
+ @reference = json['reference']
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ module Grobi
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'grobi'
3
+ require 'grobi/client'
4
+ require 'grobi/books'
5
+ require 'secret' # create your own lib/secret.rb
6
+
7
+ describe Grobi::Books do
8
+ context 'retrive_from_google' do
9
+ it 'search volumes' do
10
+ client = Grobi::Client.new
11
+ client.simple_api_key = SIMPLE_API_KEY
12
+ google_books = Grobi::Books.new(client)
13
+ books = google_books.search("\u5929\u9F8D\u516B\u90E8")
14
+ books.count.should == 10
15
+ book = books.first
16
+ book.title.should == "\u5929\u9F8D\u516B\u90E8"
17
+ book.publisher.should be_nil
18
+ google_books.retrieve(book)
19
+ book.publisher.should_not be_nil
20
+ end
21
+ end
22
+
23
+ context 'load_json_file' do
24
+ it "raises an error when no directory is set" do
25
+ expect { load_json('books1.json') }.to raise_error(JsonSpec::MissingDirectory)
26
+ end
27
+
28
+ it "returns JSON when the file exists" do
29
+ JsonSpec.directory = files_path
30
+ load_json("books1.json").should include_json(%("books#volumes"))
31
+ end
32
+
33
+ it 'parse JSON from Google Books' do
34
+ JsonSpec.directory = files_path
35
+ google_books = Grobi::Books.new(nil)
36
+ books = google_books.parse(load_json('books1.json'))
37
+ books.count.should == 10
38
+ book = books.first
39
+ book.title.should == "\u5929\u9F8D\u516B\u90E8"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'grobi'
3
+ require 'grobi/maps'
4
+
5
+ describe Grobi::Maps do
6
+ context 'retrive_from_google' do
7
+ it 'search volumes' do
8
+ client = Grobi::Client.new
9
+ google_maps = Grobi::Maps.new(client)
10
+ placemarks = google_maps.search("\u53F0\u5317\u5E02\u4E2D\u6B63\u5340\u91CD\u6176\u5357\u8DEF\u4E00\u6BB5122\u865F")
11
+ placemarks.count.should == 1
12
+ placemark = placemarks.first
13
+ placemark.longitude.should == 121.5128120
14
+ placemark.number.should == '122'
15
+ end
16
+ end
17
+
18
+ context 'load_json_file' do
19
+ it 'parse JSON from Google Maps' do
20
+ JsonSpec.directory = files_path
21
+ google_maps = Grobi::Maps.new(nil)
22
+ maps = google_maps.parse(load_json('maps1.json'))
23
+ maps.count.should == 4
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'grobi'
3
+ require 'grobi/places'
4
+
5
+ describe Grobi::Places do
6
+ context 'load_json_file' do
7
+ it 'parse JSON from Google Places' do
8
+ JsonSpec.directory = files_path
9
+ google_places = Grobi::Places.new(nil)
10
+ places = google_places.parse(load_json('places1.json'))
11
+ places.count.should == 2
12
+ place = places.first
13
+ place.name.should =~ /.*Zaaffran.*/
14
+ place.reference.should_not be_nil
15
+ end
16
+
17
+ it 'parse JSON from Google Places' do
18
+ JsonSpec.directory = files_path
19
+ j = JSON.parse(load_json('place1.json'))
20
+ place = Grobi::Place.new(j['result'])
21
+ place.name.should =~ /.*Sydney.*/
22
+ place.route.should == 'Pirrama Road'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ require 'json_spec'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+ config.include JsonSpec::Helpers
14
+ end
15
+
16
+ def files_path
17
+ File.expand_path("../support/files", __FILE__)
18
+ end
@@ -0,0 +1,496 @@
1
+ {
2
+ "kind": "books#volumes",
3
+ "totalItems": 695,
4
+ "items": [
5
+ {
6
+ "kind": "books#volume",
7
+ "id": "abALAQAAMAAJ",
8
+ "etag": "mPBCV03PVhw",
9
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/abALAQAAMAAJ",
10
+ "volumeInfo": {
11
+ "title": "天龍八部",
12
+ "authors": [
13
+ "金庸"
14
+ ],
15
+ "publishedDate": "1997",
16
+ "industryIdentifiers": [
17
+ {
18
+ "type": "ISBN_10",
19
+ "identifier": "9573229374"
20
+ },
21
+ {
22
+ "type": "ISBN_13",
23
+ "identifier": "9789573229377"
24
+ }
25
+ ],
26
+ "pageCount": 2130,
27
+ "printType": "BOOK",
28
+ "contentVersion": "0.0.1.0.preview.0",
29
+ "imageLinks": {
30
+ "smallThumbnail": "http://bks3.books.google.com/books?id=abALAQAAMAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
31
+ "thumbnail": "http://bks3.books.google.com/books?id=abALAQAAMAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
32
+ },
33
+ "language": "zh-CN",
34
+ "previewLink": "http://books.google.com/books?id=abALAQAAMAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=1&source=gbs_api",
35
+ "infoLink": "http://books.google.com/books?id=abALAQAAMAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
36
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=abALAQAAMAAJ"
37
+ },
38
+ "saleInfo": {
39
+ "country": "TW",
40
+ "saleability": "NOT_FOR_SALE",
41
+ "isEbook": false
42
+ },
43
+ "accessInfo": {
44
+ "country": "TW",
45
+ "viewability": "NO_PAGES",
46
+ "embeddable": false,
47
+ "publicDomain": false,
48
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
49
+ "epub": {
50
+ "isAvailable": false
51
+ },
52
+ "pdf": {
53
+ "isAvailable": false
54
+ },
55
+ "webReaderLink": "http://books.google.com/books/reader?id=abALAQAAMAAJ&printsec=frontcover&output=reader&source=gbs_api",
56
+ "accessViewStatus": "NONE"
57
+ }
58
+ },
59
+ {
60
+ "kind": "books#volume",
61
+ "id": "CHUyAAAAMAAJ",
62
+ "etag": "9LmGDuaJmoY",
63
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/CHUyAAAAMAAJ",
64
+ "volumeInfo": {
65
+ "title": "天龍八部",
66
+ "authors": [
67
+ "金庸"
68
+ ],
69
+ "publishedDate": "1996",
70
+ "description": "Translation of title: The semi-gods and the semi-devils.",
71
+ "industryIdentifiers": [
72
+ {
73
+ "type": "OTHER",
74
+ "identifier": "UOM:39015051531351"
75
+ }
76
+ ],
77
+ "pageCount": 2130,
78
+ "printType": "BOOK",
79
+ "categories": [
80
+ "Sports & Recreation"
81
+ ],
82
+ "contentVersion": "preview-1.0.0",
83
+ "language": "zh-CN",
84
+ "previewLink": "http://books.google.com/books?id=CHUyAAAAMAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=2&source=gbs_api",
85
+ "infoLink": "http://books.google.com/books?id=CHUyAAAAMAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
86
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=CHUyAAAAMAAJ"
87
+ },
88
+ "saleInfo": {
89
+ "country": "TW",
90
+ "saleability": "NOT_FOR_SALE",
91
+ "isEbook": false
92
+ },
93
+ "accessInfo": {
94
+ "country": "TW",
95
+ "viewability": "NO_PAGES",
96
+ "embeddable": false,
97
+ "publicDomain": false,
98
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
99
+ "epub": {
100
+ "isAvailable": false
101
+ },
102
+ "pdf": {
103
+ "isAvailable": false
104
+ },
105
+ "webReaderLink": "http://books.google.com/books/reader?id=CHUyAAAAMAAJ&printsec=frontcover&output=reader&source=gbs_api",
106
+ "accessViewStatus": "NONE"
107
+ },
108
+ "searchInfo": {
109
+ "textSnippet": "Translation of title: The semi-gods and the semi-devils."
110
+ }
111
+ },
112
+ {
113
+ "kind": "books#volume",
114
+ "id": "N7QZAQAAIAAJ",
115
+ "etag": "dwi78WtG08o",
116
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/N7QZAQAAIAAJ",
117
+ "volumeInfo": {
118
+ "title": "天龍八部",
119
+ "authors": [
120
+ "金庸"
121
+ ],
122
+ "publishedDate": "1979",
123
+ "industryIdentifiers": [
124
+ {
125
+ "type": "OTHER",
126
+ "identifier": "UCSC:32106013653826"
127
+ }
128
+ ],
129
+ "pageCount": 2130,
130
+ "printType": "BOOK",
131
+ "contentVersion": "1.1.1.0.preview.0",
132
+ "imageLinks": {
133
+ "smallThumbnail": "http://bks1.books.google.com/books?id=N7QZAQAAIAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
134
+ "thumbnail": "http://bks1.books.google.com/books?id=N7QZAQAAIAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
135
+ },
136
+ "language": "zh-CN",
137
+ "previewLink": "http://books.google.com/books?id=N7QZAQAAIAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=3&source=gbs_api",
138
+ "infoLink": "http://books.google.com/books?id=N7QZAQAAIAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
139
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=N7QZAQAAIAAJ"
140
+ },
141
+ "saleInfo": {
142
+ "country": "TW",
143
+ "saleability": "NOT_FOR_SALE",
144
+ "isEbook": false
145
+ },
146
+ "accessInfo": {
147
+ "country": "TW",
148
+ "viewability": "NO_PAGES",
149
+ "embeddable": false,
150
+ "publicDomain": false,
151
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
152
+ "epub": {
153
+ "isAvailable": false
154
+ },
155
+ "pdf": {
156
+ "isAvailable": false
157
+ },
158
+ "webReaderLink": "http://books.google.com/books/reader?id=N7QZAQAAIAAJ&printsec=frontcover&output=reader&source=gbs_api",
159
+ "accessViewStatus": "NONE"
160
+ }
161
+ },
162
+ {
163
+ "kind": "books#volume",
164
+ "id": "u2plAAAAIAAJ",
165
+ "etag": "EHEQmOt7to4",
166
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/u2plAAAAIAAJ",
167
+ "volumeInfo": {
168
+ "title": "天龍八部",
169
+ "authors": [
170
+ "全佛文化出版社編輯部"
171
+ ],
172
+ "publishedDate": "2000",
173
+ "industryIdentifiers": [
174
+ {
175
+ "type": "ISBN_10",
176
+ "identifier": "957825475X"
177
+ },
178
+ {
179
+ "type": "ISBN_13",
180
+ "identifier": "9789578254756"
181
+ }
182
+ ],
183
+ "pageCount": 365,
184
+ "printType": "BOOK",
185
+ "contentVersion": "0.0.1.0.preview.0",
186
+ "language": "zh-CN",
187
+ "previewLink": "http://books.google.com/books?id=u2plAAAAIAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=4&source=gbs_api",
188
+ "infoLink": "http://books.google.com/books?id=u2plAAAAIAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
189
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=u2plAAAAIAAJ"
190
+ },
191
+ "saleInfo": {
192
+ "country": "TW",
193
+ "saleability": "NOT_FOR_SALE",
194
+ "isEbook": false
195
+ },
196
+ "accessInfo": {
197
+ "country": "TW",
198
+ "viewability": "NO_PAGES",
199
+ "embeddable": false,
200
+ "publicDomain": false,
201
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
202
+ "epub": {
203
+ "isAvailable": false
204
+ },
205
+ "pdf": {
206
+ "isAvailable": false
207
+ },
208
+ "webReaderLink": "http://books.google.com/books/reader?id=u2plAAAAIAAJ&printsec=frontcover&output=reader&source=gbs_api",
209
+ "accessViewStatus": "NONE"
210
+ }
211
+ },
212
+ {
213
+ "kind": "books#volume",
214
+ "id": "IstlpwAACAAJ",
215
+ "etag": "u53aoujBNd4",
216
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/IstlpwAACAAJ",
217
+ "volumeInfo": {
218
+ "title": "天龍八部",
219
+ "authors": [
220
+ "黃玉郎"
221
+ ],
222
+ "industryIdentifiers": [
223
+ {
224
+ "type": "ISBN_10",
225
+ "identifier": "9573462877"
226
+ },
227
+ {
228
+ "type": "ISBN_13",
229
+ "identifier": "9789573462873"
230
+ }
231
+ ],
232
+ "printType": "BOOK",
233
+ "contentVersion": "preview-1.0.0",
234
+ "language": "zh-CN",
235
+ "previewLink": "http://books.google.com/books?id=IstlpwAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=5&source=gbs_api",
236
+ "infoLink": "http://books.google.com/books?id=IstlpwAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
237
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=IstlpwAACAAJ"
238
+ },
239
+ "saleInfo": {
240
+ "country": "TW",
241
+ "saleability": "NOT_FOR_SALE",
242
+ "isEbook": false
243
+ },
244
+ "accessInfo": {
245
+ "country": "TW",
246
+ "viewability": "NO_PAGES",
247
+ "embeddable": false,
248
+ "publicDomain": false,
249
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
250
+ "epub": {
251
+ "isAvailable": false
252
+ },
253
+ "pdf": {
254
+ "isAvailable": false
255
+ },
256
+ "webReaderLink": "http://books.google.com/books/reader?id=IstlpwAACAAJ&printsec=frontcover&output=reader&source=gbs_api",
257
+ "accessViewStatus": "NONE"
258
+ }
259
+ },
260
+ {
261
+ "kind": "books#volume",
262
+ "id": "Y2YSAQAAMAAJ",
263
+ "etag": "aQMT3EMpw2k",
264
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/Y2YSAQAAMAAJ",
265
+ "volumeInfo": {
266
+ "title": "金庸作品集: 天龙八部",
267
+ "authors": [
268
+ "金庸"
269
+ ],
270
+ "publishedDate": "2002",
271
+ "industryIdentifiers": [
272
+ {
273
+ "type": "OTHER",
274
+ "identifier": "UCLA:L0088214812"
275
+ }
276
+ ],
277
+ "printType": "BOOK",
278
+ "contentVersion": "preview-1.0.0",
279
+ "imageLinks": {
280
+ "smallThumbnail": "http://bks0.books.google.com/books?id=Y2YSAQAAMAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
281
+ "thumbnail": "http://bks0.books.google.com/books?id=Y2YSAQAAMAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
282
+ },
283
+ "language": "zh-CN",
284
+ "previewLink": "http://books.google.com/books?id=Y2YSAQAAMAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=6&source=gbs_api",
285
+ "infoLink": "http://books.google.com/books?id=Y2YSAQAAMAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
286
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E9%87%91%E5%BA%B8%E4%BD%9C%E5%93%81%E9%9B%86_%E5%A4%A9%E9%BE%99%E5%85%AB%E9%83%A8.html?id=Y2YSAQAAMAAJ"
287
+ },
288
+ "saleInfo": {
289
+ "country": "TW",
290
+ "saleability": "NOT_FOR_SALE",
291
+ "isEbook": false
292
+ },
293
+ "accessInfo": {
294
+ "country": "TW",
295
+ "viewability": "NO_PAGES",
296
+ "embeddable": false,
297
+ "publicDomain": false,
298
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
299
+ "epub": {
300
+ "isAvailable": false
301
+ },
302
+ "pdf": {
303
+ "isAvailable": false
304
+ },
305
+ "webReaderLink": "http://books.google.com/books/reader?id=Y2YSAQAAMAAJ&printsec=frontcover&output=reader&source=gbs_api",
306
+ "accessViewStatus": "NONE"
307
+ }
308
+ },
309
+ {
310
+ "kind": "books#volume",
311
+ "id": "1GMSAQAAMAAJ",
312
+ "etag": "VMFVbkojsCY",
313
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/1GMSAQAAMAAJ",
314
+ "volumeInfo": {
315
+ "title": "金庸作品集: 天龍八部",
316
+ "authors": [
317
+ "金庸"
318
+ ],
319
+ "publishedDate": "1995",
320
+ "industryIdentifiers": [
321
+ {
322
+ "type": "OTHER",
323
+ "identifier": "UCLA:L0090718339"
324
+ }
325
+ ],
326
+ "printType": "BOOK",
327
+ "contentVersion": "preview-1.0.0",
328
+ "language": "zh-CN",
329
+ "previewLink": "http://books.google.com/books?id=1GMSAQAAMAAJ&q=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=7&source=gbs_api",
330
+ "infoLink": "http://books.google.com/books?id=1GMSAQAAMAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
331
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E9%87%91%E5%BA%B8%E4%BD%9C%E5%93%81%E9%9B%86_%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8.html?id=1GMSAQAAMAAJ"
332
+ },
333
+ "saleInfo": {
334
+ "country": "TW",
335
+ "saleability": "NOT_FOR_SALE",
336
+ "isEbook": false
337
+ },
338
+ "accessInfo": {
339
+ "country": "TW",
340
+ "viewability": "NO_PAGES",
341
+ "embeddable": false,
342
+ "publicDomain": false,
343
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
344
+ "epub": {
345
+ "isAvailable": false
346
+ },
347
+ "pdf": {
348
+ "isAvailable": false
349
+ },
350
+ "webReaderLink": "http://books.google.com/books/reader?id=1GMSAQAAMAAJ&printsec=frontcover&output=reader&source=gbs_api",
351
+ "accessViewStatus": "NONE"
352
+ }
353
+ },
354
+ {
355
+ "kind": "books#volume",
356
+ "id": "mIRczgAACAAJ",
357
+ "etag": "WmlvYwZ/lhM",
358
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/mIRczgAACAAJ",
359
+ "volumeInfo": {
360
+ "title": "天龙八部",
361
+ "contentVersion": "full-1.0.0",
362
+ "language": "zh-CN",
363
+ "previewLink": "http://books.google.com/books?id=mIRczgAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=8&source=gbs_api",
364
+ "infoLink": "http://books.google.com/books?id=mIRczgAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
365
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%99%E5%85%AB%E9%83%A8.html?id=mIRczgAACAAJ"
366
+ },
367
+ "saleInfo": {
368
+ "country": "TW",
369
+ "saleability": "FREE",
370
+ "isEbook": true
371
+ },
372
+ "accessInfo": {
373
+ "country": "TW",
374
+ "viewability": "NO_PAGES",
375
+ "embeddable": false,
376
+ "publicDomain": false,
377
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
378
+ "epub": {
379
+ "isAvailable": false
380
+ },
381
+ "pdf": {
382
+ "isAvailable": false
383
+ },
384
+ "webReaderLink": "http://books.google.com/books/reader?id=mIRczgAACAAJ&printsec=frontcover&output=reader&source=gbs_api",
385
+ "accessViewStatus": "NONE"
386
+ }
387
+ },
388
+ {
389
+ "kind": "books#volume",
390
+ "id": "rADqSAAACAAJ",
391
+ "etag": "QBpjS6iENmY",
392
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/rADqSAAACAAJ",
393
+ "volumeInfo": {
394
+ "title": "图解天龙八部",
395
+ "authors": [
396
+ "诺布旺典"
397
+ ],
398
+ "publishedDate": "2009",
399
+ "industryIdentifiers": [
400
+ {
401
+ "type": "ISBN_10",
402
+ "identifier": "7561348185"
403
+ },
404
+ {
405
+ "type": "ISBN_13",
406
+ "identifier": "9787561348185"
407
+ }
408
+ ],
409
+ "printType": "BOOK",
410
+ "contentVersion": "preview-1.0.0",
411
+ "language": "zh-CN",
412
+ "previewLink": "http://books.google.com/books?id=rADqSAAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=9&source=gbs_api",
413
+ "infoLink": "http://books.google.com/books?id=rADqSAAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
414
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%9B%BE%E8%A7%A3%E5%A4%A9%E9%BE%99%E5%85%AB%E9%83%A8.html?id=rADqSAAACAAJ"
415
+ },
416
+ "saleInfo": {
417
+ "country": "TW",
418
+ "saleability": "NOT_FOR_SALE",
419
+ "isEbook": false
420
+ },
421
+ "accessInfo": {
422
+ "country": "TW",
423
+ "viewability": "NO_PAGES",
424
+ "embeddable": false,
425
+ "publicDomain": false,
426
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
427
+ "epub": {
428
+ "isAvailable": false
429
+ },
430
+ "pdf": {
431
+ "isAvailable": false
432
+ },
433
+ "webReaderLink": "http://books.google.com/books/reader?id=rADqSAAACAAJ&printsec=frontcover&output=reader&source=gbs_api",
434
+ "accessViewStatus": "NONE"
435
+ }
436
+ },
437
+ {
438
+ "kind": "books#volume",
439
+ "id": "oKPqQwAACAAJ",
440
+ "etag": "dEE9gWYvbL8",
441
+ "selfLink": "https://www.googleapis.com/books/v1/volumes/oKPqQwAACAAJ",
442
+ "volumeInfo": {
443
+ "title": "天龙八部漫画/第二册",
444
+ "authors": [
445
+ "金庸"
446
+ ],
447
+ "publishedDate": "1999",
448
+ "description": "恶贯满盈段延庆原乃段氏一脉,施卑污奸计,图令段誉与木婉清兄妹乱伦败德,同室操戈只因帝位之争。为求六脉剑谱,大轮明王独挑天龙奇,威迫利诱。保卫祖传绝学,天龙寺众僧合展六脉神剑,力拒明王火焰刀进犯......",
449
+ "industryIdentifiers": [
450
+ {
451
+ "type": "ISBN_10",
452
+ "identifier": "7108012456"
453
+ },
454
+ {
455
+ "type": "ISBN_13",
456
+ "identifier": "9787108012456"
457
+ }
458
+ ],
459
+ "pageCount": 184,
460
+ "printType": "BOOK",
461
+ "contentVersion": "preview-1.0.0",
462
+ "imageLinks": {
463
+ "smallThumbnail": "http://bks3.books.google.com/books?id=oKPqQwAACAAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
464
+ "thumbnail": "http://bks3.books.google.com/books?id=oKPqQwAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
465
+ },
466
+ "language": "zh-CN",
467
+ "previewLink": "http://books.google.com/books?id=oKPqQwAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&cd=10&source=gbs_api",
468
+ "infoLink": "http://books.google.com/books?id=oKPqQwAACAAJ&dq=%E5%A4%A9%E9%BE%8D%E5%85%AB%E9%83%A8&source=gbs_api",
469
+ "canonicalVolumeLink": "http://books.google.com/books/about/%E5%A4%A9%E9%BE%99%E5%85%AB%E9%83%A8%E6%BC%AB%E7%94%BB_%E7%AC%AC%E4%BA%8C%E5%86%8C.html?id=oKPqQwAACAAJ"
470
+ },
471
+ "saleInfo": {
472
+ "country": "TW",
473
+ "saleability": "NOT_FOR_SALE",
474
+ "isEbook": false
475
+ },
476
+ "accessInfo": {
477
+ "country": "TW",
478
+ "viewability": "NO_PAGES",
479
+ "embeddable": false,
480
+ "publicDomain": false,
481
+ "textToSpeechPermission": "ALLOWED_FOR_ACCESSIBILITY",
482
+ "epub": {
483
+ "isAvailable": false
484
+ },
485
+ "pdf": {
486
+ "isAvailable": false
487
+ },
488
+ "webReaderLink": "http://books.google.com/books/reader?id=oKPqQwAACAAJ&printsec=frontcover&output=reader&source=gbs_api",
489
+ "accessViewStatus": "NONE"
490
+ },
491
+ "searchInfo": {
492
+ "textSnippet": "恶贯满盈段延庆原乃段氏一脉,施卑污奸计,图令段誉与木婉清兄妹乱伦败德,同室操戈只因帝位之争。为求六脉剑谱,大轮明王独挑天龙奇,威迫利诱。保卫祖传绝学 ..."
493
+ }
494
+ }
495
+ ]
496
+ }