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 CHANGED
@@ -19,6 +19,7 @@ rdoc
19
19
  pkg
20
20
  doc
21
21
  .yardoc
22
+ *.gemspec
22
23
 
23
24
  ## PROJECT::SPECIFIC
24
25
  credentials.rb
@@ -1,6 +1,34 @@
1
1
  = librarything-api
2
2
 
3
- Description goes here.
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.0
1
+ 0.1.1
@@ -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
- # LT-specific hack to simplify access to lists. Ill-advised?
29
- if child.name =~ /^[\w]*List$/
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
 
@@ -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'].content.should == 'http://www.librarything.com/author/216'
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'].content.should == 'Susanna Clarke'
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'].content.should == 'http://www.librarything.com/work/1060'
47
+ work['url'].should == 'http://www.librarything.com/work/1060'
48
48
 
49
49
  author = work['author']
50
50
  author.should_not be_nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librarything-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Wadsworth