unapi 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/unapi/format.rb +4 -10
- data/lib/unapi/page.rb +11 -11
- data/lib/unapi/service.rb +5 -5
- data/lib/unapi/validator.rb +25 -30
- data/test/index.html +7 -7
- data/test/unapi_servlet.rb +17 -19
- data/test/unapi_test.rb +15 -15
- metadata +2 -2
data/lib/unapi/format.rb
CHANGED
@@ -3,17 +3,11 @@ module UnAPI
|
|
3
3
|
class Format
|
4
4
|
attr_accessor :name, :type, :docs, :namespace_uri, :schema_location
|
5
5
|
|
6
|
-
def Format.new_from_element(
|
6
|
+
def Format.new_from_element(element)
|
7
7
|
format = Format.new
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
when 'type' : format.type = e.text
|
12
|
-
when 'docs' : format.docs = e.text
|
13
|
-
when 'namespace_uri' : format.namespace_uri = e.text
|
14
|
-
when 'schema_location' : format.schema_location = e.text
|
15
|
-
end
|
16
|
-
end
|
8
|
+
format.name = element.attributes['name']
|
9
|
+
format.type = element.attributes['type']
|
10
|
+
format.docs = element.attributes['docs']
|
17
11
|
return format
|
18
12
|
end
|
19
13
|
end
|
data/lib/unapi/page.rb
CHANGED
@@ -19,7 +19,7 @@ module UnAPI
|
|
19
19
|
return nil if not @document or not @document.head
|
20
20
|
link_url = nil
|
21
21
|
@document.head.find_all('link') do |link|
|
22
|
-
link_url = link['href'] if link['
|
22
|
+
link_url = link['href'] if link['rel'] == 'unapi-server'
|
23
23
|
end
|
24
24
|
return nil if not link_url
|
25
25
|
|
@@ -43,19 +43,19 @@ module UnAPI
|
|
43
43
|
return nil
|
44
44
|
end
|
45
45
|
|
46
|
-
# get a list of
|
47
|
-
def
|
48
|
-
|
49
|
-
return
|
50
|
-
@document.find_all('
|
51
|
-
next unless
|
46
|
+
# get a list of ids for the page
|
47
|
+
def ids
|
48
|
+
ids = []
|
49
|
+
return ids if not @document
|
50
|
+
@document.find_all('abbr') do |abbr|
|
51
|
+
next unless abbr['class'] and abbr['title']
|
52
52
|
# can have multiple css classes
|
53
|
-
classes =
|
54
|
-
if classes.member? 'unapi-
|
55
|
-
|
53
|
+
classes = abbr['class'].split(/\s+/)
|
54
|
+
if classes.member? 'unapi-id'
|
55
|
+
ids << abbr['title']
|
56
56
|
end
|
57
57
|
end
|
58
|
-
return
|
58
|
+
return ids
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
data/lib/unapi/service.rb
CHANGED
@@ -25,9 +25,9 @@ module UnAPI
|
|
25
25
|
return formats
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def formats_for_id(id)
|
29
29
|
formats = []
|
30
|
-
request_url = @url + "?
|
30
|
+
request_url = @url + "?id=#{CGI.escape(id)}"
|
31
31
|
@status_code, @document, @content_type = Utils.get_document request_url
|
32
32
|
@document.elements.each('.//formats/format') do |e|
|
33
33
|
formats << Format.new_from_element(e)
|
@@ -36,10 +36,10 @@ module UnAPI
|
|
36
36
|
return formats
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
|
39
|
+
def get_id_in_format(id, format)
|
40
|
+
id_esc = CGI.escape(id)
|
41
41
|
format_esc = CGI.escape(format)
|
42
|
-
request_url = @url + "?
|
42
|
+
request_url = @url + "?id=#{id_esc}&format=#{format_esc}"
|
43
43
|
@document = nil
|
44
44
|
@status_code, body, @content_type = Utils.get request_url
|
45
45
|
@last_url = request_url
|
data/lib/unapi/validator.rb
CHANGED
@@ -107,7 +107,7 @@ module UnAPI
|
|
107
107
|
def validate_page(page_url)
|
108
108
|
page = UnAPI::Page.new page_url
|
109
109
|
check_service page
|
110
|
-
|
110
|
+
check_ids page
|
111
111
|
end
|
112
112
|
|
113
113
|
private
|
@@ -132,53 +132,51 @@ module UnAPI
|
|
132
132
|
check_formats(formats, service, 'unapi service')
|
133
133
|
end
|
134
134
|
|
135
|
-
def
|
135
|
+
def check_ids(page)
|
136
136
|
service = page.service
|
137
137
|
return if not service
|
138
138
|
|
139
|
-
# look for unap-
|
140
|
-
|
141
|
-
@handler.test
|
142
|
-
"page should > 0 elements with class unapi-
|
143
|
-
|
139
|
+
# look for unap-ids on the page
|
140
|
+
ids = page.ids
|
141
|
+
@handler.test ids.length > 0,
|
142
|
+
"page should > 0 elements with class unapi-id",
|
143
|
+
ids.length,
|
144
144
|
page.uri
|
145
145
|
|
146
146
|
# go through each identifier
|
147
|
-
|
147
|
+
ids.each do |id|
|
148
148
|
|
149
149
|
# verify it has formats available
|
150
|
-
formats = service.
|
151
|
-
check_formats(formats, service,
|
150
|
+
formats = service.formats_for_id(id)
|
151
|
+
check_formats(formats, service, id)
|
152
152
|
|
153
153
|
# request an invalid format
|
154
|
-
content = service.
|
155
|
-
@handler.check service.status_code ==
|
156
|
-
"request for
|
157
|
-
"status code
|
154
|
+
content = service.get_id_in_format(id, 'thisformatdoesnotexist')
|
155
|
+
@handler.check service.status_code == 406,
|
156
|
+
"request for id #{id} with bad format should return with " +
|
157
|
+
"status code 406",
|
158
158
|
service.status_code,
|
159
159
|
service.last_url
|
160
160
|
|
161
161
|
# verify that each format is available
|
162
162
|
content = ''
|
163
163
|
formats.each do |format|
|
164
|
-
|
165
|
-
|
166
|
-
"request for #{uri} content should return with 200 status code",
|
167
|
-
service.status_code,
|
168
|
-
service.last_url
|
164
|
+
next if format.name == nil
|
165
|
+
content = service.get_id_in_format(id, format.name)
|
169
166
|
@handler.test((content != nil and content.length > 0),
|
170
|
-
"request for #{
|
167
|
+
"request for id #{id} in format #{format.name} should return data",
|
171
168
|
"#{content.length} bytes",
|
172
169
|
service.last_url)
|
173
170
|
@handler.test service.content_type.include?(format.type),
|
174
|
-
"request for #{
|
171
|
+
"request for id #{id} in format #{format.name} should return " +
|
172
|
+
"with content-type #{format.type}",
|
175
173
|
service.content_type,
|
176
174
|
service.last_url
|
177
175
|
|
178
|
-
# request an invalid
|
179
|
-
service.
|
176
|
+
# request an invalid id with a valid format
|
177
|
+
service.get_id_in_format('invalidrughdinvalid', format.name)
|
180
178
|
@handler.check service.status_code == 404,
|
181
|
-
"request for invalid
|
179
|
+
"request for invalid id with valid format #{format.name} " +
|
182
180
|
"should return with 404 status code",
|
183
181
|
service.status_code,
|
184
182
|
service.last_url
|
@@ -193,12 +191,9 @@ module UnAPI
|
|
193
191
|
service.content_type,
|
194
192
|
service.last_url
|
195
193
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
service.status_code,
|
200
|
-
service.last_url
|
201
|
-
else
|
194
|
+
# requesting formats on a server shouldn't return 300 apparently
|
195
|
+
# unless a specific identifier was requested
|
196
|
+
unless target == 'unapi service'
|
202
197
|
@handler.check service.status_code == 300,
|
203
198
|
"formats request for #{target} should return with 300 status code",
|
204
199
|
service.status_code,
|
data/test/index.html
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<title>
|
4
4
|
Amazon.com: Online Shopping for Electronics, Apparel, Computers, Books, DVDs & more
|
5
5
|
</title>
|
6
|
-
<link rel="
|
6
|
+
<link rel="unapi-server" type="application/xml" title="unAPI" href="http://localhost:9000/unapi" />
|
7
7
|
<meta name="description" content="Online shopping from the earth's biggest selection of books, magazines, music, DVDs, videos, electronics, computers, software, apparel & accessories, shoes, jewelry, tools & hardware, housewares, furniture, sporting goods, beauty & personal care, gourmet food & just about anything else.">
|
8
8
|
<meta name="keywords" content="Amazon, Amazon.com, Books, Online Shopping, Book Store, Magazine, Subscription, Music, CDs, DVDs, Videos, Electronics, Video Games, Computers, Cell Phones, Toys, Games, Apparel, Accessories, Shoes, Jewelry, Watches, Office Products, Sports & Outdoors, Sporting Goods, Baby Products, Health, Personal Care, Beauty, Home, Garden, Bed & Bath, Furniture, Tools, Hardware, Vacuums, Outdoor Living, Automotive Parts, Pet Supplies">
|
9
9
|
<style type="text/css"><!-- .serif { font-family: times,serif; font-size: small; }
|
@@ -490,21 +490,21 @@ Sign in to get <a href=/exec/obidos/flex-sign-in?opt=a&page=recs/sign-in-secure.
|
|
490
490
|
<br><br>
|
491
491
|
<div class="small">
|
492
492
|
<b class="h1">2006 Spring Preview: What to Read Next</b><br clear=left>
|
493
|
-
<
|
493
|
+
<abbr class="unapi-id display" title="urn:isbn:0553804790">
|
494
494
|
<a href="http://www.amazon.com/exec/obidos/ASIN/0553804790">
|
495
495
|
<img src="http://images.amazon.com/images/P/0553804790.01.37TRZZZZ.jpg" width=81 height=121 align=left valign=top hspace=5 vspace=3 border=0 border=0>
|
496
496
|
</a>
|
497
|
-
</
|
498
|
-
<
|
497
|
+
</abbr>
|
498
|
+
<abbr class="unapi-id" title="urn:isbn:030723827X">
|
499
499
|
<a href="http://www.amazon.com/exec/obidos/ASIN/030723827X">
|
500
500
|
<img src="http://images.amazon.com/images/P/030723827X.01.37TRZZZZ.jpg" width=94 height=121 align=left valign=top hspace=5 vspace=3 border=0 border=0>
|
501
501
|
</a>
|
502
|
-
</
|
503
|
-
<
|
502
|
+
</abbr>
|
503
|
+
<abbr class="unapi-id" title="urn:isbn:0307236579">
|
504
504
|
<a href="http://www.amazon.com/exec/obidos/ASIN/0307236579">
|
505
505
|
<img src="http://images.amazon.com/images/P/0307236579.01.35TRZZZZ.jpg" width=93 height=121 align=left valign=top hspace=5 vspace=3 border=0 border=0>
|
506
506
|
</a>
|
507
|
-
</
|
507
|
+
</abbr>
|
508
508
|
See what's coming up this spring in our 2006 sneak preview, including a thriller from <a href="http://www.amazon.com/exec/obidos/ASIN/0553804790">Dean Koontz</a>, a new cookbook from <a href="http://www.amazon.com/exec/obidos/ASIN/030723827X">Giada De Laurentiis</a>, and a <a href="http://www.amazon.com/exec/obidos/ASIN/0307236579">little knitting book</a> that will get you ready for summer. <br clear=all>
|
509
509
|
<ul>
|
510
510
|
<li>Top Releases: <a href="http://www.amazon.com/gp/richpub/listmania/fullview/R3PET96BPF14S4">Fiction</a> | <a href="http://www.amazon.com/gp/richpub/listmania/fullview/R1DTUMBWJP7PN1">Nonfiction</a>
|
data/test/unapi_servlet.rb
CHANGED
@@ -9,29 +9,29 @@ require 'net/http'
|
|
9
9
|
class UnAPIServlet < WEBrick::HTTPServlet::AbstractServlet
|
10
10
|
|
11
11
|
def service(request, response)
|
12
|
-
|
12
|
+
id = request.query.fetch('id', nil)
|
13
13
|
format = request.query.fetch('format', nil)
|
14
14
|
|
15
|
-
if not
|
15
|
+
if not id and not format
|
16
16
|
doc = REXML::Document.new
|
17
17
|
doc.add_element get_formats
|
18
18
|
response['Content-Type'] = 'application/xml'
|
19
19
|
response.status = 300
|
20
20
|
response.body = doc.to_s
|
21
21
|
|
22
|
-
elsif
|
23
|
-
if not has_record(
|
22
|
+
elsif id and not format
|
23
|
+
if not has_record(id)
|
24
24
|
response.status = 404
|
25
25
|
else
|
26
26
|
doc = REXML::Document.new
|
27
|
-
doc.add_element get_formats(
|
27
|
+
doc.add_element get_formats(id)
|
28
28
|
response['Content-Type'] = 'application/xml'
|
29
29
|
response.status = 300
|
30
30
|
response.body = doc.to_s
|
31
31
|
end
|
32
32
|
|
33
|
-
elsif
|
34
|
-
record = get_record(
|
33
|
+
elsif id and format
|
34
|
+
record = get_record(id, format)
|
35
35
|
if not ok_format? format
|
36
36
|
response.status = 415
|
37
37
|
elsif not record
|
@@ -54,11 +54,11 @@ class UnAPIServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
54
54
|
return(['mods','dc'].member? format)
|
55
55
|
end
|
56
56
|
|
57
|
-
def get_formats(
|
57
|
+
def get_formats(id=nil)
|
58
58
|
formats = REXML::Element.new 'formats'
|
59
|
-
if
|
60
|
-
|
61
|
-
|
59
|
+
if id
|
60
|
+
id_element = REXML::Element.new 'id', formats
|
61
|
+
id_element.text = id
|
62
62
|
end
|
63
63
|
formats.add_element get_format('dc', 'text/xml')
|
64
64
|
formats.add_element get_format('mods', 'text/xml')
|
@@ -67,20 +67,18 @@ class UnAPIServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
67
67
|
|
68
68
|
def get_format(name, type)
|
69
69
|
format = REXML::Element.new 'format'
|
70
|
-
|
71
|
-
|
72
|
-
type_element = REXML::Element.new 'type', format
|
73
|
-
type_element.text = type
|
70
|
+
format.attributes['name'] = name
|
71
|
+
format.attributes['type'] = type
|
74
72
|
return format
|
75
73
|
end
|
76
74
|
|
77
|
-
def has_record(
|
75
|
+
def has_record(id)
|
78
76
|
ids = ['urn:isbn:0553804790', 'urn:isbn:030723827X', 'urn:isbn:0307236579']
|
79
|
-
return(ids.member?
|
77
|
+
return(ids.member? id)
|
80
78
|
end
|
81
79
|
|
82
|
-
def get_record(
|
83
|
-
if has_record(
|
80
|
+
def get_record(id, format)
|
81
|
+
if has_record(id)
|
84
82
|
case format
|
85
83
|
when 'dc' : return(REXML::Element.new 'dc')
|
86
84
|
when 'mods' : return(REXML::Element.new 'mods')
|
data/test/unapi_test.rb
CHANGED
@@ -7,10 +7,10 @@ class UnAPITest < Test::Unit::TestCase
|
|
7
7
|
assert_equal page.service_url, 'http://localhost:9000/unapi'
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def test_ids
|
11
11
|
page = UnAPI::Page.new 'http://localhost:9000/index.html'
|
12
12
|
assert_equal [ 'urn:isbn:0553804790', 'urn:isbn:030723827X',
|
13
|
-
'urn:isbn:0307236579'], page.
|
13
|
+
'urn:isbn:0307236579'], page.ids
|
14
14
|
end
|
15
15
|
|
16
16
|
def test_service
|
@@ -38,9 +38,9 @@ class UnAPITest < Test::Unit::TestCase
|
|
38
38
|
assert_equal nil, service.status_code
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
41
|
+
def test_id_formats
|
42
42
|
service = UnAPI::Service.new 'http://localhost:9000/unapi'
|
43
|
-
formats = service.
|
43
|
+
formats = service.formats_for_id('urn:isbn:0553804790')
|
44
44
|
assert_equal 2, formats.length
|
45
45
|
assert_equal formats[0].name, 'dc'
|
46
46
|
assert_equal formats[0].type, 'text/xml'
|
@@ -49,32 +49,32 @@ class UnAPITest < Test::Unit::TestCase
|
|
49
49
|
assert_equal 300, service.status_code
|
50
50
|
end
|
51
51
|
|
52
|
-
def
|
52
|
+
def test_bad_id_formats
|
53
53
|
service = UnAPI::Service.new 'http://localhost:9000/unapi'
|
54
|
-
formats = service.
|
54
|
+
formats = service.formats_for_id('urn:isbn:foobarf')
|
55
55
|
assert_equal 0, formats.length
|
56
56
|
assert_equal 404, service.status_code
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
59
|
+
def test_get_id_in_format
|
60
60
|
service = UnAPI::Service.new 'http://localhost:9000/unapi'
|
61
|
-
|
62
|
-
assert_equal '<dc/>', service.
|
61
|
+
id = 'urn:isbn:0553804790'
|
62
|
+
assert_equal '<dc/>', service.get_id_in_format(id, 'dc')
|
63
63
|
assert_equal 200, service.status_code
|
64
|
-
assert_equal '<mods/>', service.
|
64
|
+
assert_equal '<mods/>', service.get_id_in_format(id, 'mods')
|
65
65
|
assert_equal 200, service.status_code
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def test_get_bad_id_
|
69
69
|
service = UnAPI::Service.new 'http://localhost:9000/unapi'
|
70
|
-
assert_equal nil, service.
|
70
|
+
assert_equal nil, service.get_id_in_format('foobar', 'dc')
|
71
71
|
assert_equal 404, service.status_code
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
74
|
+
def test_get_bad_id_in_format
|
75
|
+
id = 'urn:isbn:0553804790'
|
76
76
|
service = UnAPI::Service.new 'http://localhost:9000/unapi'
|
77
|
-
assert_equal nil, service.
|
77
|
+
assert_equal nil, service.get_id_in_format(id, 'cheese')
|
78
78
|
assert_equal 415, service.status_code
|
79
79
|
end
|
80
80
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: unapi
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.0.6
|
7
|
+
date: 2006-07-02 00:00:00 -04:00
|
8
8
|
summary: A library for working with the unapi protocol
|
9
9
|
require_paths:
|
10
10
|
- lib
|