librarything-api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ doc
21
+ .yardoc
22
+
23
+ ## PROJECT::SPECIFIC
24
+ credentials.rb
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jason Wadsworth
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = librarything-api
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Jason Wadsworth. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "librarything-api"
8
+ gem.summary = %Q{Gem for accessing the LibraryThing API}
9
+ gem.description = %Q{Gem for accessing the LibraryThing API}
10
+ gem.email = "jdwadsworth@gmail.com"
11
+ gem.homepage = "http://github.com/subakva/librarything-api"
12
+ gem.authors = ["Jason Wadsworth"]
13
+ gem.add_development_dependency "rspec", ">= 1.3.0"
14
+ gem.add_development_dependency "fakeweb", ">= 1.2.8"
15
+ gem.add_development_dependency "yard", ">= 0"
16
+ gem.add_dependency "httparty", ">= 0.5.2"
17
+ gem.add_dependency "nokogiri", ">= 1.4.1"
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.ruby_opts << ['-r rubygems']
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.spec_files = FileList['spec/**/*_spec.rb']
29
+ end
30
+
31
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
32
+ spec.libs << 'lib' << 'spec'
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov = true
35
+ end
36
+
37
+ task :spec => :check_dependencies
38
+
39
+ task :default => :spec
40
+
41
+ begin
42
+ require 'yard'
43
+ YARD::Rake::YardocTask.new
44
+ rescue LoadError
45
+ task :yardoc do
46
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
47
+ end
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/shared_requires")
2
+
3
+ module LibraryThing
4
+ class Author < LibraryThing::Resource
5
+ get_method 'librarything.ck.getauthor'
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module LibraryThing
2
+ class Error < Exception; end
3
+ end
@@ -0,0 +1,122 @@
1
+ require 'httparty'
2
+
3
+ module LibraryThing
4
+
5
+ class NodeWrapper
6
+
7
+ attr_reader :node
8
+
9
+ def initialize(node)
10
+ @node = node
11
+ end
12
+
13
+ def content
14
+ @node.content
15
+ end
16
+
17
+ def [](name)
18
+ # Check for attributes first. Why? It works for the LT xml (for now).
19
+ if @node.attributes.has_key?(name)
20
+ return @node.attributes[name].value
21
+ end
22
+
23
+ # Find child elements with that name
24
+ children = @node.xpath("lt:#{name}")
25
+ if children.size == 1
26
+ child = children.first
27
+
28
+ # LT-specific hack to simplify access to lists. Ill-advised?
29
+ if child.name =~ /^[\w]*List$/
30
+ return wrap_children(child.children)
31
+ else
32
+ return NodeWrapper.new(child)
33
+ end
34
+ elsif children.size > 1
35
+ return wrap_children(children)
36
+ else
37
+ return nil
38
+ end
39
+ end
40
+
41
+ protected
42
+
43
+ def wrap_children(children)
44
+ children.map { |c| NodeWrapper.new(c) if c.element? }.compact
45
+ end
46
+ end
47
+
48
+ class Resource
49
+ include HTTParty
50
+ base_uri 'http://www.librarything.com/services/rest/1.0'
51
+
52
+ attr_reader :xml
53
+ attr_reader :document
54
+ attr_reader :item_node
55
+
56
+ def initialize(xml)
57
+ @xml = xml
58
+ @document = self.parse_response(@xml)
59
+ @item_node = self.find_item_node(@document)
60
+ end
61
+
62
+ def [](name)
63
+ @item_node[name]
64
+ end
65
+
66
+ protected
67
+
68
+ def parse_response(xml)
69
+ doc = Nokogiri::XML(xml)
70
+ self.check_for_errors(doc)
71
+ doc
72
+ end
73
+
74
+ def find_item_node(doc)
75
+ doc.root.add_namespace('lt', 'http://www.librarything.com/')
76
+ item = doc.xpath('/response/lt:ltml/lt:item').first
77
+ raise LibraryThing::Error.new('Missing item element in response') if item.nil?
78
+ NodeWrapper.new(item)
79
+ end
80
+
81
+ def check_for_errors(doc)
82
+ response = doc.xpath('//response')
83
+ raise LibraryThing::Error.new("LT response was missing the 'response' element.") if response.empty?
84
+
85
+ statuses = doc.xpath('//response/@stat')
86
+ status = statuses.first.value unless statuses.empty?
87
+ if status && status != 'ok'
88
+ errors = doc.xpath('//response/err')
89
+ error = errors.first unless errors.empty?
90
+ error_code = error.attributes['code'] if error
91
+ error_message = error.content if error
92
+
93
+ raise LibraryThing::Error.new("status = #{status}, error_code = #{error_code}, error_message = #{error_message}")
94
+ end
95
+ end
96
+
97
+ class << self
98
+ def get_method(method_name = nil)
99
+ if method_name
100
+ @get_method = method_name
101
+ elsif @get_method
102
+ @get_method
103
+ else
104
+ raise LibraryThing::Error.new('Cannot get a generic resource. Try LibraryThing::Work.get or LibraryThing::Author.get')
105
+ end
106
+ end
107
+
108
+ def get(query)
109
+ raise LibraryThing::Error.new("Missing developer key. Please define LibraryThing::DEVELOPER_KEY") unless defined?(LibraryThing::DEVELOPER_KEY)
110
+
111
+ all_params = {
112
+ :apikey => LibraryThing::DEVELOPER_KEY,
113
+ :method => self.get_method
114
+ }.merge(query)
115
+
116
+ response = super('', :query => all_params)
117
+ self.new(response.body)
118
+ end
119
+ end
120
+
121
+ end
122
+ end
@@ -0,0 +1,4 @@
1
+ require 'httparty'
2
+ require 'nokogiri'
3
+ require File.expand_path(File.dirname(__FILE__) + "/errors")
4
+ require File.expand_path(File.dirname(__FILE__) + "/resource")
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/shared_requires")
2
+
3
+ module LibraryThing
4
+ class Work < LibraryThing::Resource
5
+ get_method 'librarything.ck.getwork'
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/librarything")
@@ -0,0 +1,2 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/librarything/author")
2
+ require File.expand_path(File.dirname(__FILE__) + "/librarything/work")
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe LibraryThing::Author do
4
+ describe 'configuration' do
5
+ it "knows the method name for getting an author" do
6
+ LibraryThing::Author.get_method.should == 'librarything.ck.getauthor'
7
+ end
8
+ end
9
+
10
+ describe '#get' do
11
+ before(:each) do
12
+ @fake_response = load_response_body(LibraryThing::Author.get_method, '216')
13
+ @error_response = load_response_body(LibraryThing::Author.get_method, 'error')
14
+ @crash_response = load_response_body(LibraryThing::Author.get_method, 'crash')
15
+ end
16
+
17
+ it "complains if the response is not xml" do
18
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:id => '216'})
19
+ FakeWeb.register_uri(:get, expected_request_url, :body => 'Not xml' )
20
+
21
+ lambda {
22
+ LibraryThing::Author.get(:id => '216')
23
+ }.should raise_error(LibraryThing::Error, 'LT response was missing the \'response\' element.')
24
+ end
25
+
26
+ it "complains if the response does not have the response element" do
27
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:id => '216'})
28
+ FakeWeb.register_uri(:get, expected_request_url, :body => @crash_response )
29
+
30
+ lambda {
31
+ LibraryThing::Author.get(:id => '216')
32
+ }.should raise_error(LibraryThing::Error, 'LT response was missing the \'response\' element.')
33
+ end
34
+
35
+ it "complains if the response status is not 'ok'" do
36
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:id => '216'})
37
+ FakeWeb.register_uri(:get, expected_request_url, :body => @error_response )
38
+
39
+ lambda {
40
+ LibraryThing::Author.get(:id => '216')
41
+ }.should raise_error(LibraryThing::Error, "status = fail, error_code = 106, error_message = Could not determine author from supplied arguments")
42
+ end
43
+
44
+ def check_author_response(author)
45
+ author.should_not be_nil
46
+ author['id'].should == '216'
47
+ author['url'].content.should == 'http://www.librarything.com/author/216'
48
+
49
+ author_element = author['author']
50
+ author_element.should_not be_nil
51
+ author_element['id'].should == '216'
52
+ author_element['authorcode'].should == 'clarkesusanna'
53
+ author_element['name'].content.should == 'Susanna Clarke'
54
+
55
+ field_list = author['commonknowledge']['fieldList']
56
+ field_list.size.should == 8
57
+ end
58
+
59
+ it "retrieves an author by id" do
60
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:id => '216'})
61
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
62
+
63
+ author = LibraryThing::Author.get(:id => 216)
64
+ check_author_response(author)
65
+ end
66
+
67
+ it "retrieves an author by authorcode" do
68
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:authorcode => 'clarkesusanna'})
69
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
70
+
71
+ author = LibraryThing::Author.get(:authorcode => 'clarkesusanna')
72
+ check_author_response(author)
73
+ end
74
+
75
+ it "retrieves an author by name" do
76
+ expected_request_url = api_url(LibraryThing::Author.get_method, {:name => 'Clarke,+Susanna'})
77
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
78
+
79
+ author = LibraryThing::Author.get(:name => 'Clarke,+Susanna')
80
+ check_author_response(author)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe LibraryThing::Resource do
4
+ it "complains about trying to get a Resource instance" do
5
+ lambda {
6
+ LibraryThing::Resource.get(:id => '123')
7
+ }.should raise_error(LibraryThing::Error, 'Cannot get a generic resource. Try LibraryThing::Work.get or LibraryThing::Author.get')
8
+ end
9
+ end
@@ -0,0 +1,127 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe LibraryThing::Work do
4
+ describe 'configuration' do
5
+ it "knows the method name for getting a work" do
6
+ LibraryThing::Work.get_method.should == 'librarything.ck.getwork'
7
+ end
8
+ end
9
+
10
+ describe '#get' do
11
+ before(:each) do
12
+ @fake_response = load_response_body(LibraryThing::Work.get_method, '1060')
13
+ @error_response = load_response_body(LibraryThing::Work.get_method, 'error')
14
+ @crash_response = load_response_body(LibraryThing::Work.get_method, 'crash')
15
+ end
16
+
17
+ it "complains if the response is not xml" do
18
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:id => '1060'})
19
+ FakeWeb.register_uri(:get, expected_request_url, :body => 'Not xml' )
20
+
21
+ lambda {
22
+ LibraryThing::Work.get(:id => '1060')
23
+ }.should raise_error(LibraryThing::Error, 'LT response was missing the \'response\' element.')
24
+ end
25
+
26
+ it "complains if the response does not have the response element" do
27
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:id => '1060'})
28
+ FakeWeb.register_uri(:get, expected_request_url, :body => @crash_response )
29
+
30
+ lambda {
31
+ LibraryThing::Work.get(:id => '1060')
32
+ }.should raise_error(LibraryThing::Error, 'LT response was missing the \'response\' element.')
33
+ end
34
+
35
+ it "complains if the response status is not 'ok'" do
36
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:id => '1060'})
37
+ FakeWeb.register_uri(:get, expected_request_url, :body => @error_response )
38
+
39
+ lambda {
40
+ LibraryThing::Work.get(:id => '1060')
41
+ }.should raise_error(LibraryThing::Error, "status = fail, error_code = 105, error_message = Could not find work ID matching supplied arguments")
42
+ end
43
+
44
+ def check_work_response(work)
45
+ work.should_not be_nil
46
+ work['id'].should == '1060'
47
+ work['url'].content.should == 'http://www.librarything.com/work/1060'
48
+
49
+ author = work['author']
50
+ author.should_not be_nil
51
+ author['id'].should == '216'
52
+ author['authorcode'].should == 'clarkesusanna'
53
+ author.content.should == 'Susanna Clarke'
54
+
55
+ field_list = work['commonknowledge']['fieldList']
56
+ field_list.size.should == 15
57
+
58
+ epigraph = field_list.first
59
+ epigraph['type'].should == '28'
60
+ epigraph['name'].should == 'epigraph'
61
+ epigraph['displayName'].should == 'Epigraph'
62
+ epigraph['versionList'].size.should == 1
63
+
64
+ work['garbage'].should be_nil
65
+ end
66
+
67
+ it "retrieves a work by id" do
68
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:id => '1060'})
69
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
70
+
71
+ work = LibraryThing::Work.get(:id => 1060)
72
+ check_work_response(work)
73
+ end
74
+
75
+ it "retrieves a work object by isbn" do
76
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:isbn => '0765356155'})
77
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
78
+
79
+ work = LibraryThing::Work.get(:isbn => '0765356155')
80
+ check_work_response(work)
81
+ end
82
+
83
+ # Note: This appears to be broken on LT.
84
+ #
85
+ # http://www.librarything.com/services/rest/1.0/?method=librarything.ck.getwork&lccn=PR6103.L375J65&apikey=XXXXXXX
86
+ #
87
+ # <font color=ff0000>
88
+ # Warning: Missing argument 2 for workforLCCNorOCLC(), called in /var/www/html/services/rest/1.0/class_WS_CommonKnowledge.php on line 209 and defined in /var/www/html/inc_thingISBN.php on line 5
89
+ # </font><font color=ff0000>
90
+ # Warning: Invalid argument supplied for foreach() in /var/www/html/inc_thingISBN.php on line 13
91
+ # </font><?xml version="1.0" encoding="UTF-8"?>
92
+ # <response stat="fail"><err code="105">Could not find work ID matching supplied arguments</err></response>
93
+ #
94
+ it "retrieves a work object by lccn" do
95
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:lccn => 'PR6103.L375J65'})
96
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
97
+
98
+ work = LibraryThing::Work.get(:lccn => 'PR6103.L375J65')
99
+ check_work_response(work)
100
+ end
101
+
102
+ # Note: This appears to be broken on LT.
103
+ #
104
+ # http://www.librarything.com/services/rest/1.0/?method=librarything.ck.getwork&oclc=185392674&apikey=XXXXXXX
105
+ #
106
+ # <font color=ff0000>
107
+ # Warning: Invalid argument supplied for foreach() in /var/www/html/inc_thingISBN.php on line 12
108
+ # </font><?xml version="1.0" encoding="UTF-8"?>
109
+ # <response stat="fail"><err code="105">Could not find work ID matching supplied arguments</err></response>
110
+ #
111
+ it "retrieves a work object by oclc id" do
112
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:oclc => '185392674'})
113
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
114
+
115
+ work = LibraryThing::Work.get(:oclc => '185392674')
116
+ check_work_response(work)
117
+ end
118
+
119
+ it "retrieves a work object by name" do
120
+ expected_request_url = api_url(LibraryThing::Work.get_method, {:name => 'Jonathan+Strange'})
121
+ FakeWeb.register_uri(:get, expected_request_url, :body => @fake_response )
122
+
123
+ work = LibraryThing::Work.get(:name => 'Jonathan+Strange')
124
+ check_work_response(work)
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "LibrarythingApi" do
4
+ it "should require the librarything library" do
5
+ defined?(LibraryThing).should be_true
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe LibraryThing do
4
+ it "should require the Work class" do
5
+ defined?(LibraryThing::Work).should be_true
6
+ end
7
+
8
+ it "should require the Author class" do
9
+ defined?(LibraryThing::Author).should be_true
10
+ end
11
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format specdoc
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'librarything-api'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','helpers','**','*.rb'))].each { |f| require f }
8
+
9
+ LibraryThing::DEVELOPER_KEY = 'lt_test_key'
10
+
11
+ Spec::Runner.configure do |config|
12
+
13
+ end
@@ -0,0 +1,20 @@
1
+ require 'fakeweb'
2
+ require 'rack'
3
+
4
+ def spec_support_dir
5
+ File.expand_path(File.join(File.dirname(__FILE__), '..'))
6
+ end
7
+
8
+ def load_response_body(method, id)
9
+ parts = [spec_support_dir, 'responses', method, "#{id}.xml"]
10
+ File.new(File.join(parts)).read
11
+ end
12
+
13
+ def api_url(method, params, include_key = true)
14
+ all_params = {:apikey => 'lt_test_key', :method => method}.merge(params) if include_key
15
+ all_params ||= params
16
+ query_string = Rack::Utils.build_query(all_params)
17
+ "http://www.librarything.com/services/rest/1.0?" + query_string
18
+ end
19
+
20
+ FakeWeb.allow_net_connect = false
@@ -0,0 +1,137 @@
1
+ <?xml version="1.0"?>
2
+ <response stat="ok">
3
+ <ltml xmlns="http://www.librarything.com/" version="1.0">
4
+ <item id="216" type="author">
5
+ <author id="216" authorcode="clarkesusanna">
6
+ <name>Susanna Clarke</name>
7
+ </author>
8
+ <url>http://www.librarything.com/author/216</url>
9
+ <commonknowledge>
10
+ <fieldList>
11
+ <field type="6" name="placesofresidence" displayName="Places of residence">
12
+ <versionList>
13
+ <version id="1215367" archived="0" lang="eng">
14
+ <date timestamp="1236540583">Sun, 08 Mar 2009 15:29:43 -0400</date>
15
+ <person id="617371">
16
+ <name>C.S._Lewis</name>
17
+ <url>http://www.librarything.com/profile/C.S._Lewis</url>
18
+ </person>
19
+ <factList>
20
+ <fact>County Durham, England, UK</fact>
21
+ <fact>Nottingham, Nottinghamshire, England, UK (birth)</fact>
22
+ <fact>Cambridge, Cambridgeshire, England, UK</fact>
23
+ <fact>Oxford, Oxfordshire, England, UK</fact>
24
+ <fact>Bilbao, Spain</fact>
25
+ <fact>Turin, Italy</fact>
26
+ </factList>
27
+ </version>
28
+ </versionList>
29
+ </field>
30
+ <field type="22" name="canonicalname" displayName="Canonical name">
31
+ <versionList>
32
+ <version id="645774" archived="0" lang="eng">
33
+ <date timestamp="1223010501">Fri, 03 Oct 2008 01:08:21 -0400</date>
34
+ <person id="116044">
35
+ <name>Shortride</name>
36
+ <url>http://www.librarything.com/profile/Shortride</url>
37
+ </person>
38
+ <factList>
39
+ <fact>Clarke, Susanna</fact>
40
+ </factList>
41
+ </version>
42
+ </versionList>
43
+ </field>
44
+ <field type="9" name="education" displayName="Education">
45
+ <versionList>
46
+ <version id="295469" archived="0" lang="eng">
47
+ <date timestamp="1206327674">Sun, 23 Mar 2008 23:01:14 -0400</date>
48
+ <person id="108140">
49
+ <name>DisassemblyOfReason</name>
50
+ <url>http://www.librarything.com/profile/DisassemblyOfReason</url>
51
+ </person>
52
+ <factList>
53
+ <fact>Oxford University (St. Hilda's, 1981)</fact>
54
+ </factList>
55
+ </version>
56
+ </versionList>
57
+ </field>
58
+ <field type="18" name="nationality" displayName="Nationality">
59
+ <versionList>
60
+ <version id="291288" archived="0" lang="eng">
61
+ <date timestamp="1206114287">Fri, 21 Mar 2008 11:44:47 -0400</date>
62
+ <person id="45396">
63
+ <name>bw42</name>
64
+ <url>http://www.librarything.com/profile/bw42</url>
65
+ </person>
66
+ <factList>
67
+ <fact>UK</fact>
68
+ </factList>
69
+ </version>
70
+ </versionList>
71
+ </field>
72
+ <field type="17" name="occupations" displayName="Occupations">
73
+ <versionList>
74
+ <version id="272547" archived="0" lang="eng">
75
+ <date timestamp="1204897922">Fri, 07 Mar 2008 08:52:02 -0500</date>
76
+ <person id="55491">
77
+ <name>Osbaldistone</name>
78
+ <url>http://www.librarything.com/profile/Osbaldistone</url>
79
+ </person>
80
+ <factList>
81
+ <fact>editor</fact>
82
+ <fact>writer</fact>
83
+ <fact>author</fact>
84
+ <fact>novelist</fact>
85
+ </factList>
86
+ </version>
87
+ </versionList>
88
+ </field>
89
+ <field type="4" name="awards" displayName="Awards and honors">
90
+ <versionList>
91
+ <version id="87001" archived="0" lang="eng">
92
+ <date timestamp="1194126277">Sat, 03 Nov 2007 17:44:37 -0400</date>
93
+ <person id="116044">
94
+ <name>Shortride</name>
95
+ <url>http://www.librarything.com/profile/Shortride</url>
96
+ </person>
97
+ <factList>
98
+ <fact>British Book Award (Newcomer of the Year, 2005)</fact>
99
+ <fact>Waterstones 25 Authors for the Future (2007)</fact>
100
+ </factList>
101
+ </version>
102
+ </versionList>
103
+ </field>
104
+ <field type="8" name="birthdate" displayName="Birthdate">
105
+ <versionList>
106
+ <version id="36742" archived="0" lang="eng">
107
+ <date timestamp="1192329357">Sat, 13 Oct 2007 22:35:57 -0400</date>
108
+ <person id="198088">
109
+ <name>AnnaClaire</name>
110
+ <url>http://www.librarything.com/profile/AnnaClaire</url>
111
+ </person>
112
+ <factList>
113
+ <fact>1959-11-01</fact>
114
+ </factList>
115
+ </version>
116
+ </versionList>
117
+ </field>
118
+ <field type="5" name="gender" displayName="Gender">
119
+ <versionList>
120
+ <version id="7537" archived="0" lang="eng">
121
+ <date timestamp="1191988667">Tue, 09 Oct 2007 23:57:47 -0400</date>
122
+ <person id="1496">
123
+ <name>felius</name>
124
+ <url>http://www.librarything.com/profile/felius</url>
125
+ </person>
126
+ <factList>
127
+ <fact>female</fact>
128
+ </factList>
129
+ </version>
130
+ </versionList>
131
+ </field>
132
+ </fieldList>
133
+ </commonknowledge>
134
+ </item>
135
+ <legal>By using this data you agree to the LibraryThing API terms of service.</legal>
136
+ </ltml>
137
+ </response>
@@ -0,0 +1,3 @@
1
+ <font color=ff0000>
2
+ Fatal error: Call to undefined method WS_CommonKnowledge::returnError() in /var/www/html/services/rest/1.0/index.php on line 65
3
+ </font>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <response stat="fail">
3
+ <err code="106">Could not determine author from supplied arguments</err>
4
+ </response>
@@ -0,0 +1,286 @@
1
+ <?xml version="1.0"?>
2
+ <response stat="ok">
3
+ <ltml xmlns="http://www.librarything.com/" version="1.0">
4
+ <item id="1060" type="work">
5
+ <author id="216" authorcode="clarkesusanna">Susanna Clarke</author>
6
+ <url>http://www.librarything.com/work/1060</url>
7
+ <commonknowledge>
8
+ <fieldList>
9
+ <field type="28" name="epigraph" displayName="Epigraph">
10
+ <versionList>
11
+ <version id="2184856" archived="0" lang="eng">
12
+ <date timestamp="1265498292">Sat, 06 Feb 2010 18:18:12 -0500</date>
13
+ <person id="684944">
14
+ <name>fig2</name>
15
+ <url>http://www.librarything.com/profile/fig2</url>
16
+ </person>
17
+ <factList>
18
+ <fact>&lt;![CDATA[ He hardly ever spoke of magic, and when he did it was like a history lesson and no one could bear to listen to him. ]]&gt;</fact>
19
+ </factList>
20
+ </version>
21
+ </versionList>
22
+ </field>
23
+ <field type="4" name="awards" displayName="Awards and honors">
24
+ <versionList>
25
+ <version id="2138966" archived="0" lang="eng">
26
+ <date timestamp="1264486541">Tue, 26 Jan 2010 01:15:41 -0500</date>
27
+ <person id="849103">
28
+ <name>LamontCranston</name>
29
+ <url>http://www.librarything.com/profile/LamontCranston</url>
30
+ </person>
31
+ <factList>
32
+ <fact>World Fantasy Award (Novel, 2005)</fact>
33
+ <fact>Hugo (Novel, 2005)</fact>
34
+ <fact>British Fantasy Award Nominee (August Derleth Fantasy Award, 2005)</fact>
35
+ <fact>British Science Fiction Association Award Shortlist (2004)</fact>
36
+ <fact>Nebula Nominee (Novel, 2005)</fact>
37
+ <fact>SF Site Editor's Choice (#1, 2004)</fact>
38
+ <fact>Book Sense Book of the Year (2005.8 | Adult Fiction Winner, 2005)</fact>
39
+ <fact>Whitbread Shortlist (First Novel, 2004)</fact>
40
+ <fact>Locus Recommended Reading (First Novel, 2004)</fact>
41
+ <fact>SF Site Reader's Choice (#1, 2004)</fact>
42
+ <fact>Guardian 1000 (Science Fiction &amp; Fantasy)</fact>
43
+ <fact>Time Magazine's Best Books of the Year (2004.10|Fiction (1), 2004)</fact>
44
+ <fact>Salon Book Award (2004)</fact>
45
+ <fact>Booker Prize Longlist (2004)</fact>
46
+ <fact>Guardian First Book Award (Shortlist, 2004)</fact>
47
+ <fact>British Book Award (Literary Fiction Award Shortlist, 2005)</fact>
48
+ <fact>Locus (First Novel, 2005)</fact>
49
+ <fact>Mythopoeic Fantasy Award (Adult Literature, 2005)</fact>
50
+ <fact>British Book Award (Newcomer of the Year, 2005)</fact>
51
+ <fact>Geffen Award (Best Translated Fantasy Book, 2007)</fact>
52
+ <fact>thisrecording.com 100 Greatest Science Fiction or Fantasy Novels of All Time (95)</fact>
53
+ </factList>
54
+ </version>
55
+ </versionList>
56
+ </field>
57
+ <field type="3" name="characternames" displayName="People/Characters">
58
+ <versionList>
59
+ <version id="1931873" archived="0" lang="eng">
60
+ <date timestamp="1258228496">Sat, 14 Nov 2009 14:54:56 -0500</date>
61
+ <person id="108140">
62
+ <name>DisassemblyOfReason</name>
63
+ <url>http://www.librarything.com/profile/DisassemblyOfReason</url>
64
+ </person>
65
+ <factList>
66
+ <fact>Jonathan Strange</fact>
67
+ <fact>Gilbert Norrell</fact>
68
+ <fact>The gentleman with thistle-down hair</fact>
69
+ <fact>Stephen Black</fact>
70
+ <fact>Lady Pole</fact>
71
+ <fact>John Childermass</fact>
72
+ <fact>Mr. Christopher Drawlight</fact>
73
+ <fact>John Segundus</fact>
74
+ <fact>Mr. Honeyfoot</fact>
75
+ <fact>Dr. Foxcastle</fact>
76
+ <fact>Mrs. Pleasance</fact>
77
+ <fact>Mr. Thorpe</fact>
78
+ <fact>Mrs. Godesdone</fact>
79
+ <fact>Mr. Lascelles</fact>
80
+ <fact>Vinculus</fact>
81
+ <fact>John Uskglass (The Raven King)</fact>
82
+ <fact>Arabella Strange</fact>
83
+ <fact>Sir Walter Pole</fact>
84
+ <fact>Emma Wintertowne</fact>
85
+ <fact>Napoleon Bonaparte</fact>
86
+ <fact>Arthur Wellesley, 1st Duke of Wellington</fact>
87
+ <fact>George III, King of the United Kingdom</fact>
88
+ <fact>Flora Greysteel</fact>
89
+ <fact>Signor Tosetti</fact>
90
+ <fact>The old lady of Cannregio</fact>
91
+ </factList>
92
+ </version>
93
+ </versionList>
94
+ </field>
95
+ <field type="2" name="placesmentioned" displayName="Important places">
96
+ <versionList>
97
+ <version id="1902680" archived="0" lang="eng">
98
+ <date timestamp="1257306914">Tue, 03 Nov 2009 22:55:14 -0500</date>
99
+ <person id="108140">
100
+ <name>DisassemblyOfReason</name>
101
+ <url>http://www.librarything.com/profile/DisassemblyOfReason</url>
102
+ </person>
103
+ <factList>
104
+ <fact>London, England, UK</fact>
105
+ <fact>York, Yorkshire, England, UK</fact>
106
+ <fact>Faerie (fictional)</fact>
107
+ <fact>France</fact>
108
+ <fact>Portugal</fact>
109
+ <fact>Venice, Veneto, Italy</fact>
110
+ <fact>York Cathedral, York, Yorkshire, England, UK</fact>
111
+ <fact>Shropshire, England, UK</fact>
112
+ <fact>Lost-Hope, Faerie (fictional)</fact>
113
+ <fact>Padua, Veneto, Italy</fact>
114
+ <fact>Eternal Night (fictional)</fact>
115
+ </factList>
116
+ </version>
117
+ </versionList>
118
+ </field>
119
+ <field type="36" name="mediareviews" displayName="Media reviews">
120
+ <versionList>
121
+ <version id="1889043" archived="0" lang="eng">
122
+ <date timestamp="1256884900">Fri, 30 Oct 2009 02:41:40 -0400</date>
123
+ <person id="116044">
124
+ <name>Shortride</name>
125
+ <url>http://www.librarything.com/profile/Shortride</url>
126
+ </person>
127
+ <factList>
128
+ <fact>129</fact>
129
+ <fact>145</fact>
130
+ <fact>146</fact>
131
+ <fact>276</fact>
132
+ <fact>1029</fact>
133
+ <fact>4977</fact>
134
+ </factList>
135
+ </version>
136
+ </versionList>
137
+ </field>
138
+ <field type="27" name="quotations" displayName="Quotations">
139
+ <versionList>
140
+ <version id="1633900" archived="0" lang="eng">
141
+ <date timestamp="1248286869">Wed, 22 Jul 2009 14:21:09 -0400</date>
142
+ <person id="515980">
143
+ <name>aynar</name>
144
+ <url>http://www.librarything.com/profile/aynar</url>
145
+ </person>
146
+ <factList>
147
+ <fact>&lt;![CDATA[ At sixteen she spoke -- not only French, Italian and German -- which are part of any lady's commonplace accomplishments -- but all the languages of the civilized (and uncivilized) world. She spoke the language of the Scottish Highlands (which is like singing). She spoke Basque, which is a language which rarely makes any impression upon the brains of any other race, so that a man may hear it as often and as long as he likes, but never afterwards be able to recall a single syllable of it. She even learnt the language of a strange country which, Signor Tosetti had been told, some people believed still existed, although no one in the world could say where it was. (The name of the country was Wales.) ]]&gt;</fact>
148
+ </factList>
149
+ </version>
150
+ </versionList>
151
+ </field>
152
+ <field type="1" name="literaryeditors" displayName="Publisher's editor">
153
+ <versionList>
154
+ <version id="1548889" archived="0" lang="eng">
155
+ <date timestamp="1245397367">Fri, 19 Jun 2009 03:42:47 -0400</date>
156
+ <person id="61510">
157
+ <name>KingRat</name>
158
+ <url>http://www.librarything.com/profile/KingRat</url>
159
+ </person>
160
+ <factList>
161
+ <fact>Nielsen Hayden, Patrick</fact>
162
+ </factList>
163
+ </version>
164
+ </versionList>
165
+ </field>
166
+ <field type="34" name="events" displayName="Important events">
167
+ <versionList>
168
+ <version id="1494516" archived="0" lang="eng">
169
+ <date timestamp="1243869673">Mon, 01 Jun 2009 11:21:13 -0400</date>
170
+ <person id="517024">
171
+ <name>aethercowboy</name>
172
+ <url>http://www.librarything.com/profile/aethercowboy</url>
173
+ </person>
174
+ <factList>
175
+ <fact>Peninsular War</fact>
176
+ <fact>Napoleonic Wars</fact>
177
+ <fact>Battle of Waterloo</fact>
178
+ </factList>
179
+ </version>
180
+ </versionList>
181
+ </field>
182
+ <field type="23" name="series" displayName="Series">
183
+ <versionList>
184
+ <version id="915020" archived="0" lang="eng">
185
+ <date timestamp="1232521494">Wed, 21 Jan 2009 02:04:54 -0500</date>
186
+ <person id="28389">
187
+ <name>WylieMaercklein</name>
188
+ <url>http://www.librarything.com/profile/WylieMaercklein</url>
189
+ </person>
190
+ <factList>
191
+ <fact>Clarke's Faerie Stories (1)</fact>
192
+ </factList>
193
+ </version>
194
+ </versionList>
195
+ </field>
196
+ <field type="29" name="blurbers" displayName="Blurbers">
197
+ <versionList>
198
+ <version id="902293" archived="0" lang="eng">
199
+ <date timestamp="1232212596">Sat, 17 Jan 2009 12:16:36 -0500</date>
200
+ <person id="200103">
201
+ <name>PhaedraB</name>
202
+ <url>http://www.librarything.com/profile/PhaedraB</url>
203
+ </person>
204
+ <factList>
205
+ <fact>Gaiman, Neil </fact>
206
+ <fact>Palliser, Charles </fact>
207
+ </factList>
208
+ </version>
209
+ </versionList>
210
+ </field>
211
+ <field type="21" name="canonicaltitle" displayName="Canonical title">
212
+ <versionList>
213
+ <version id="705800" archived="0" lang="eng">
214
+ <date timestamp="1225654390">Sun, 02 Nov 2008 14:33:10 -0500</date>
215
+ <person id="61056">
216
+ <name>amweb</name>
217
+ <url>http://www.librarything.com/profile/amweb</url>
218
+ </person>
219
+ <factList>
220
+ <fact>Jonathan Strange &amp; Mr Norrell</fact>
221
+ </factList>
222
+ </version>
223
+ </versionList>
224
+ </field>
225
+ <field type="30" name="dedication" displayName="Dedication">
226
+ <versionList>
227
+ <version id="644458" archived="0" lang="eng">
228
+ <date timestamp="1222962793">Thu, 02 Oct 2008 11:53:13 -0400</date>
229
+ <person id="200103">
230
+ <name>PhaedraB</name>
231
+ <url>http://www.librarything.com/profile/PhaedraB</url>
232
+ </person>
233
+ <factList>
234
+ <fact>&lt;![CDATA[ In memory of my brother, Paul Frederick Gunn Clarke, 1961-2000 ]]&gt;</fact>
235
+ </factList>
236
+ </version>
237
+ </versionList>
238
+ </field>
239
+ <field type="26" name="lastwords" displayName="Last words">
240
+ <versionList>
241
+ <version id="523019" archived="0" lang="eng">
242
+ <date timestamp="1218425509">Sun, 10 Aug 2008 23:31:49 -0400</date>
243
+ <person id="23570">
244
+ <name>conceptDawg</name>
245
+ <url>http://www.librarything.com/profile/conceptDawg</url>
246
+ </person>
247
+ <factList>
248
+ <fact>&lt;![CDATA[ Then he turned upon his heel and disappeared into the Darkness. ]]&gt;</fact>
249
+ </factList>
250
+ </version>
251
+ </versionList>
252
+ </field>
253
+ <field type="25" name="firstwords" displayName="First words">
254
+ <versionList>
255
+ <version id="523018" archived="0" lang="eng">
256
+ <date timestamp="1218425423">Sun, 10 Aug 2008 23:30:23 -0400</date>
257
+ <person id="23570">
258
+ <name>conceptDawg</name>
259
+ <url>http://www.librarything.com/profile/conceptDawg</url>
260
+ </person>
261
+ <factList>
262
+ <fact>&lt;![CDATA[ Some years ago there was in the city of York a society of magicians. ]]&gt;</fact>
263
+ </factList>
264
+ </version>
265
+ </versionList>
266
+ </field>
267
+ <field type="16" name="originalpublicationdate" displayName="Original publication date">
268
+ <versionList>
269
+ <version id="132984" archived="0" lang="eng">
270
+ <date timestamp="1198164481">Thu, 20 Dec 2007 10:28:01 -0500</date>
271
+ <person id="311651">
272
+ <name>tom1066</name>
273
+ <url>http://www.librarything.com/profile/tom1066</url>
274
+ </person>
275
+ <factList>
276
+ <fact>2004-09-08</fact>
277
+ </factList>
278
+ </version>
279
+ </versionList>
280
+ </field>
281
+ </fieldList>
282
+ </commonknowledge>
283
+ </item>
284
+ <legal>By using this data you agree to the LibraryThing API terms of service.</legal>
285
+ </ltml>
286
+ </response>
@@ -0,0 +1,3 @@
1
+ <font color=ff0000>
2
+ Fatal error: Call to undefined method WS_CommonKnowledge::returnError() in /var/www/html/services/rest/1.0/index.php on line 65
3
+ </font>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <response stat="fail">
3
+ <err code="105">Could not find work ID matching supplied arguments</err>
4
+ </response>
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: librarything-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Wadsworth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-13 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: fakeweb
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.2.8
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: httparty
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.5.2
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.4.1
64
+ version:
65
+ description: Gem for accessing the LibraryThing API
66
+ email: jdwadsworth@gmail.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - LICENSE
73
+ - README.rdoc
74
+ files:
75
+ - .document
76
+ - .gitignore
77
+ - LICENSE
78
+ - README.rdoc
79
+ - Rakefile
80
+ - VERSION
81
+ - lib/librarything-api.rb
82
+ - lib/librarything.rb
83
+ - lib/librarything/author.rb
84
+ - lib/librarything/errors.rb
85
+ - lib/librarything/resource.rb
86
+ - lib/librarything/shared_requires.rb
87
+ - lib/librarything/work.rb
88
+ - spec/librarything-api_spec.rb
89
+ - spec/librarything/author_spec.rb
90
+ - spec/librarything/resource_spec.rb
91
+ - spec/librarything/work_spec.rb
92
+ - spec/librarything_spec.rb
93
+ - spec/spec.opts
94
+ - spec/spec_helper.rb
95
+ - spec/support/helpers/fakeweb_helper.rb
96
+ - spec/support/responses/librarything.ck.getauthor/216.xml
97
+ - spec/support/responses/librarything.ck.getauthor/crash.xml
98
+ - spec/support/responses/librarything.ck.getauthor/error.xml
99
+ - spec/support/responses/librarything.ck.getwork/1060.xml
100
+ - spec/support/responses/librarything.ck.getwork/crash.xml
101
+ - spec/support/responses/librarything.ck.getwork/error.xml
102
+ has_rdoc: true
103
+ homepage: http://github.com/subakva/librarything-api
104
+ licenses: []
105
+
106
+ post_install_message:
107
+ rdoc_options:
108
+ - --charset=UTF-8
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: "0"
116
+ version:
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: "0"
122
+ version:
123
+ requirements: []
124
+
125
+ rubyforge_project:
126
+ rubygems_version: 1.3.5
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Gem for accessing the LibraryThing API
130
+ test_files:
131
+ - spec/librarything/author_spec.rb
132
+ - spec/librarything/resource_spec.rb
133
+ - spec/librarything/work_spec.rb
134
+ - spec/librarything-api_spec.rb
135
+ - spec/librarything_spec.rb
136
+ - spec/spec_helper.rb
137
+ - spec/support/helpers/fakeweb_helper.rb