librarything-api 0.1.0 → 0.1.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.
- data/.gitignore +1 -0
- data/README.rdoc +29 -1
- data/VERSION +1 -1
- data/lib/librarything/author.rb +11 -0
- data/lib/librarything/resource.rb +31 -6
- data/lib/librarything/work.rb +15 -0
- data/spec/librarything/author_spec.rb +2 -2
- data/spec/librarything/work_spec.rb +1 -1
- metadata +1 -1
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
= librarything-api
|
2
2
|
|
3
|
-
|
3
|
+
This is a Ruby wrapper for the LibraryThing API.
|
4
|
+
|
5
|
+
== Accessing LibraryThing APIs
|
6
|
+
In order to use the LT Web Services API (and this library), you need to register for a developer key on librarything.com
|
7
|
+
|
8
|
+
* Sign into your LT account at http://www.librarything.com
|
9
|
+
* Go to http://www.librarything.com/services/keys.php and fill out the form to receive a developer key
|
10
|
+
* Documentation for the LT Web Services API can be found at http://www.librarything.com/services/webservices.php
|
11
|
+
|
12
|
+
== Using the Library
|
13
|
+
The gem uses HTTParty and Nokogiri for fetching and processing responses. Both of the gems must be installed.
|
14
|
+
|
15
|
+
$ gem install httparty nokogiri
|
16
|
+
|
17
|
+
$ irb -r rubygems
|
18
|
+
require 'librarything'
|
19
|
+
LibraryThing::DEVELOPER_KEY = 'abcdef0123456789abcdef'
|
20
|
+
strange = LibraryThing::Work.get(:name => 'Jonathan Strange')
|
21
|
+
strange['url']
|
22
|
+
# "http://www.librarything.com/work/1060"
|
23
|
+
|
24
|
+
== To Do
|
25
|
+
* Improve code documentation
|
26
|
+
|
27
|
+
== Other LT APIs to Add
|
28
|
+
|
29
|
+
* Helpers for accessing LT JSON APIs (Books, Works) (No server-side fetching allowed.)
|
30
|
+
* Helper for generating LT Covers URLs
|
31
|
+
* See: http://www.librarything.com/wiki/index.php/LibraryThing_APIs
|
4
32
|
|
5
33
|
== Note on Patches/Pull Requests
|
6
34
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/lib/librarything/author.rb
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/shared_requires")
|
2
2
|
|
3
3
|
module LibraryThing
|
4
|
+
|
5
|
+
#
|
6
|
+
# Provides access to the LT Author API
|
7
|
+
# Authors can be loaded by id, authorcode, or name
|
8
|
+
#
|
9
|
+
# # author = LibraryThing::Author.get(:id => 216)
|
10
|
+
# # author = LibraryThing::Author.get(:authorcode => 'clarkesusanna')
|
11
|
+
# author = LibraryThing::Author.get(:name => 'Clarke, Susanna')
|
12
|
+
# author['url]
|
13
|
+
# => "http://www.librarything.com/author/216"
|
14
|
+
#
|
4
15
|
class Author < LibraryThing::Resource
|
5
16
|
get_method 'librarything.ck.getauthor'
|
6
17
|
end
|
@@ -1,19 +1,28 @@
|
|
1
|
-
require 'httparty'
|
2
|
-
|
3
1
|
module LibraryThing
|
4
2
|
|
3
|
+
# Helper class to wrap a Nokogiri node. It includes a simplified method for accessing DOM content.
|
5
4
|
class NodeWrapper
|
6
5
|
|
7
6
|
attr_reader :node
|
8
7
|
|
8
|
+
# Creates a new wrapped XML node
|
9
9
|
def initialize(node)
|
10
10
|
@node = node
|
11
11
|
end
|
12
12
|
|
13
|
+
# Returns the content of the node
|
13
14
|
def content
|
14
15
|
@node.content
|
15
16
|
end
|
16
17
|
|
18
|
+
# Extracts values from the node.
|
19
|
+
#
|
20
|
+
# * If the name matches the name of an attribute, the value of that attribute will be returned
|
21
|
+
# * If the name matches the name of a single child element, that element is returned.
|
22
|
+
# * If the matching child element only contains text data, the text data is returned.
|
23
|
+
# * If the matching child element is named xxxList, an array of the children of the element is returned
|
24
|
+
# * If there is more that one matching child element, they are returned as an array.
|
25
|
+
#
|
17
26
|
def [](name)
|
18
27
|
# Check for attributes first. Why? It works for the LT xml (for now).
|
19
28
|
if @node.attributes.has_key?(name)
|
@@ -21,12 +30,13 @@ module LibraryThing
|
|
21
30
|
end
|
22
31
|
|
23
32
|
# Find child elements with that name
|
24
|
-
children = @node.xpath("lt:#{name}")
|
33
|
+
children = @node.xpath("./lt:#{name}")
|
25
34
|
if children.size == 1
|
26
35
|
child = children.first
|
27
|
-
|
28
|
-
|
29
|
-
|
36
|
+
if self.text_element?(child)
|
37
|
+
return child.children.first.content
|
38
|
+
elsif child.name =~ /^[\w]*List$/
|
39
|
+
# LT-specific hack to simplify access to lists. Ill-advised?
|
30
40
|
return wrap_children(child.children)
|
31
41
|
else
|
32
42
|
return NodeWrapper.new(child)
|
@@ -40,11 +50,18 @@ module LibraryThing
|
|
40
50
|
|
41
51
|
protected
|
42
52
|
|
53
|
+
# Checks whether the node is an element with no attributes and a single text child
|
54
|
+
def text_element?(node)
|
55
|
+
node.element? && node.attributes.empty? && node.children.size == 1 && node.children.first.text?
|
56
|
+
end
|
57
|
+
|
58
|
+
# Creates and returns an array of wrapped nodes for each element in the NodeSet
|
43
59
|
def wrap_children(children)
|
44
60
|
children.map { |c| NodeWrapper.new(c) if c.element? }.compact
|
45
61
|
end
|
46
62
|
end
|
47
63
|
|
64
|
+
# Base class for fetching and parsing data from the LT WebServices APIs
|
48
65
|
class Resource
|
49
66
|
include HTTParty
|
50
67
|
base_uri 'http://www.librarything.com/services/rest/1.0'
|
@@ -53,12 +70,15 @@ module LibraryThing
|
|
53
70
|
attr_reader :document
|
54
71
|
attr_reader :item_node
|
55
72
|
|
73
|
+
# Accepts xml from an LT API request and creates a wrapper object. If there is a problem with the format of the
|
74
|
+
# xml, a LibraryThing::Error will be raised.
|
56
75
|
def initialize(xml)
|
57
76
|
@xml = xml
|
58
77
|
@document = self.parse_response(@xml)
|
59
78
|
@item_node = self.find_item_node(@document)
|
60
79
|
end
|
61
80
|
|
81
|
+
# See: LibraryThing::NodeWrapper#[](name)
|
62
82
|
def [](name)
|
63
83
|
@item_node[name]
|
64
84
|
end
|
@@ -95,6 +115,9 @@ module LibraryThing
|
|
95
115
|
end
|
96
116
|
|
97
117
|
class << self
|
118
|
+
|
119
|
+
# Gets or sets the method name that will be passed to the LT web service.
|
120
|
+
# Generally, this will be specified in a sub-class.
|
98
121
|
def get_method(method_name = nil)
|
99
122
|
if method_name
|
100
123
|
@get_method = method_name
|
@@ -105,6 +128,8 @@ module LibraryThing
|
|
105
128
|
end
|
106
129
|
end
|
107
130
|
|
131
|
+
# Accepts a hash of query params, and generates a request to the LT API. Returns a wrapped response object. If
|
132
|
+
# there is a problem with the request, a LibraryThing::Error will be raised.
|
108
133
|
def get(query)
|
109
134
|
raise LibraryThing::Error.new("Missing developer key. Please define LibraryThing::DEVELOPER_KEY") unless defined?(LibraryThing::DEVELOPER_KEY)
|
110
135
|
|
data/lib/librarything/work.rb
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/shared_requires")
|
2
2
|
|
3
3
|
module LibraryThing
|
4
|
+
|
5
|
+
#
|
6
|
+
# Provides access to the LT Work API
|
7
|
+
# Works can be loaded by id, isbn, lccn, oclc or name
|
8
|
+
#
|
9
|
+
# # work = LibraryThing::Work.get(:id => 1060)
|
10
|
+
# # work = LibraryThing::Work.get(:isbn => '0765356155')
|
11
|
+
# # work = LibraryThing::Work.get(:lccn => 'PR6103.L375J65')
|
12
|
+
# # work = LibraryThing::Work.get(:oclc => '185392674')
|
13
|
+
# work = LibraryThing::Work.get(:name => 'Jonathon Strange')
|
14
|
+
# work['url]
|
15
|
+
# => "http://www.librarything.com/work/1060"
|
16
|
+
#
|
17
|
+
# Note: lccn amd oclc access wasn't working while I was testing. (13-Mar-2010)
|
18
|
+
#
|
4
19
|
class Work < LibraryThing::Resource
|
5
20
|
get_method 'librarything.ck.getwork'
|
6
21
|
end
|
@@ -44,13 +44,13 @@ describe LibraryThing::Author do
|
|
44
44
|
def check_author_response(author)
|
45
45
|
author.should_not be_nil
|
46
46
|
author['id'].should == '216'
|
47
|
-
author['url'].
|
47
|
+
author['url'].should == 'http://www.librarything.com/author/216'
|
48
48
|
|
49
49
|
author_element = author['author']
|
50
50
|
author_element.should_not be_nil
|
51
51
|
author_element['id'].should == '216'
|
52
52
|
author_element['authorcode'].should == 'clarkesusanna'
|
53
|
-
author_element['name'].
|
53
|
+
author_element['name'].should == 'Susanna Clarke'
|
54
54
|
|
55
55
|
field_list = author['commonknowledge']['fieldList']
|
56
56
|
field_list.size.should == 8
|
@@ -44,7 +44,7 @@ describe LibraryThing::Work do
|
|
44
44
|
def check_work_response(work)
|
45
45
|
work.should_not be_nil
|
46
46
|
work['id'].should == '1060'
|
47
|
-
work['url'].
|
47
|
+
work['url'].should == 'http://www.librarything.com/work/1060'
|
48
48
|
|
49
49
|
author = work['author']
|
50
50
|
author.should_not be_nil
|