ruby-fedora 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/License.txt +58 -0
- data/Manifest.txt +34 -0
- data/README.txt +19 -0
- data/Rakefile +5 -0
- data/config/hoe.rb +69 -0
- data/config/requirements.rb +17 -0
- data/lib/active-fedora.rb +1 -0
- data/lib/active_fedora/base.rb +22 -0
- data/lib/ambition/adapters/active_fedora.rb +10 -0
- data/lib/ambition/adapters/active_fedora/base.rb +14 -0
- data/lib/ambition/adapters/active_fedora/query.rb +48 -0
- data/lib/ambition/adapters/active_fedora/select.rb +104 -0
- data/lib/ambition/adapters/active_fedora/slice.rb +19 -0
- data/lib/ambition/adapters/active_fedora/sort.rb +43 -0
- data/lib/fedora/base_object.rb +19 -0
- data/lib/fedora/connection.rb +97 -0
- data/lib/fedora/datastream.rb +21 -0
- data/lib/fedora/fedora_object.rb +119 -0
- data/lib/fedora/formats.rb +30 -0
- data/lib/fedora/repository.rb +199 -0
- data/lib/ruby-fedora.rb +17 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_fedora.rb +55 -0
- data/test/test_helper.rb +6 -0
- data/test/test_httpclient.rb +73 -0
- data/test/test_restful_bits.rb +63 -0
- data/test/test_restful_fedora.rb +160 -0
- data/website/index.html +93 -0
- data/website/index.txt +39 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +113 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
module Ambition
|
2
|
+
module Adapters
|
3
|
+
module ActiveFedora
|
4
|
+
class Sort < Base
|
5
|
+
# >> sort_by { |u| u.age }
|
6
|
+
# => #sort_by(:age)
|
7
|
+
def sort_by(method)
|
8
|
+
raise "Not implemented."
|
9
|
+
end
|
10
|
+
|
11
|
+
# >> sort_by { |u| -u.age }
|
12
|
+
# => #reverse_sort_by(:age)
|
13
|
+
def reverse_sort_by(method)
|
14
|
+
raise "Not implemented."
|
15
|
+
end
|
16
|
+
|
17
|
+
# >> sort_by { |u| u.profile.name }
|
18
|
+
# => #chained_sort_by(:profile, :name)
|
19
|
+
def chained_sort_by(receiver, method)
|
20
|
+
raise "Not implemented."
|
21
|
+
end
|
22
|
+
|
23
|
+
# >> sort_by { |u| -u.profile.name }
|
24
|
+
# => #chained_reverse_sort_by(:profile, :name)
|
25
|
+
def chained_reverse_sort_by(receiver, method)
|
26
|
+
raise "Not implemented."
|
27
|
+
end
|
28
|
+
|
29
|
+
# >> sort_by(&:name)
|
30
|
+
# => #to_proc(:name)
|
31
|
+
def to_proc(symbol)
|
32
|
+
raise "Not implemented."
|
33
|
+
end
|
34
|
+
|
35
|
+
# >> sort_by { rand }
|
36
|
+
# => #rand
|
37
|
+
def rand
|
38
|
+
raise "Not implemented."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Fedora::BaseObject
|
2
|
+
attr_accessor :attributes, :xml_content, :uri, :url
|
3
|
+
attr_reader :errors, :uri
|
4
|
+
attr_writer :new_object
|
5
|
+
|
6
|
+
# == Parameters
|
7
|
+
# attrs<Hash>:: object attributes
|
8
|
+
#-
|
9
|
+
def initialize(attrs = nil)
|
10
|
+
@new_object = true
|
11
|
+
@attributes = attrs || {}
|
12
|
+
@errors = []
|
13
|
+
@xml_content = attributes.delete(:xml_content)
|
14
|
+
end
|
15
|
+
|
16
|
+
def new_object?
|
17
|
+
@new_object
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "base64"
|
2
|
+
require 'cgi'
|
3
|
+
require "mime/types"
|
4
|
+
|
5
|
+
# Add multipart/form-data support to net/http
|
6
|
+
#
|
7
|
+
# ==== Usage
|
8
|
+
# File.open(File.expand_path('script/test.png'), 'r') do |file|
|
9
|
+
# http = Net::HTTP.new('localhost', 3000)
|
10
|
+
# begin
|
11
|
+
# http.start do |http|
|
12
|
+
# request = Net::HTTP::Post.new('/your/url/here')
|
13
|
+
# request.set_multipart_data(:file => file, :title => 'test.png')
|
14
|
+
# response = http.request(request)
|
15
|
+
# puts response
|
16
|
+
# end
|
17
|
+
# rescue Net::HTTPServerException => e
|
18
|
+
# p e
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
module Fedora::Multipart
|
22
|
+
def set_multipart_data(param_hash={})
|
23
|
+
boundary_token = [Array.new(8) {rand(256)}].join
|
24
|
+
self.content_type = "multipart/form-data; boundary=#{boundary_token}"
|
25
|
+
boundary_marker = "--#{boundary_token}\r\n"
|
26
|
+
self.body = param_hash.map { |param_name, param_value|
|
27
|
+
boundary_marker + case param_value
|
28
|
+
when File then file_to_multipart(param_name, param_value)
|
29
|
+
when String then text_to_multipart(param_name, param_value)
|
30
|
+
else ""
|
31
|
+
end
|
32
|
+
}.join('') + "--#{boundary_token}--\r\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def file_to_multipart(key,file)
|
37
|
+
filename = File.basename(file.path)
|
38
|
+
mime_types = MIME::Types.of(filename)
|
39
|
+
mime_type = mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
|
40
|
+
part = %Q{Content-Disposition: form-data; name="#{key}"; filename="#{filename}"\r\n}
|
41
|
+
part += "Content-Transfer-Encoding: binary\r\n"
|
42
|
+
part += "Content-Type: #{mime_type}\r\n\r\n#{file.read}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def text_to_multipart(key,value)
|
46
|
+
"Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n#{value}\r\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Net::HTTP::Post
|
51
|
+
include Fedora::Multipart
|
52
|
+
end
|
53
|
+
|
54
|
+
class Net::HTTP::Put
|
55
|
+
include Fedora::Multipart
|
56
|
+
end
|
57
|
+
|
58
|
+
# Add multipart/form-data support to active_resource
|
59
|
+
module ActiveResource
|
60
|
+
class Connection
|
61
|
+
alias_method :post_without_multipart, :post
|
62
|
+
alias_method :put_without_multipart, :put
|
63
|
+
|
64
|
+
def put(path, body = '', headers = {})
|
65
|
+
if body.is_a?(File)
|
66
|
+
multipart_request(Net::HTTP::Put.new(path, build_request_headers(headers)), body)
|
67
|
+
else
|
68
|
+
put_without_multipart(path, body, headers)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def post(path, body = '', headers = {})
|
73
|
+
if body.is_a?(File)
|
74
|
+
multipart_request(Net::HTTP::Post.new(path, build_request_headers(headers)), body)
|
75
|
+
else
|
76
|
+
post_without_multipart(path, body, headers)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def multipart_request(req, file)
|
81
|
+
logger.info "#{method.to_s.upcase} #{site.scheme}://#{site.host}:#{site.port}#{path}" if logger
|
82
|
+
result = nil
|
83
|
+
time = Benchmark.realtime do
|
84
|
+
http.start do |conn|
|
85
|
+
req.set_multipart_data(:file => file)
|
86
|
+
result = conn.request(req)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
logger.info "--> #{result.code} #{result.message} (#{result.body ? result.body : 0}b %.2fs)" % time if logger
|
90
|
+
handle_response(result)
|
91
|
+
end
|
92
|
+
|
93
|
+
def raw_get(path, headers = {})
|
94
|
+
request(:get, path, build_request_headers(headers))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'fedora/base_object'
|
2
|
+
|
3
|
+
class Fedora::Datastream < Fedora::BaseObject
|
4
|
+
def initialize(attrs = nil)
|
5
|
+
super
|
6
|
+
# TODO: check for required attributes
|
7
|
+
end
|
8
|
+
|
9
|
+
def pid
|
10
|
+
attributes[:pid]
|
11
|
+
end
|
12
|
+
|
13
|
+
def dsid
|
14
|
+
attributes[:dsID]
|
15
|
+
end
|
16
|
+
|
17
|
+
# See http://www.fedora.info/definitions/identifiers/
|
18
|
+
def uri
|
19
|
+
"fedora:info/#{pid}/datastreams/#{dsid}"
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'xmlsimple'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'fedora/base_object'
|
4
|
+
|
5
|
+
class Fedora::FedoraObject < Fedora::BaseObject
|
6
|
+
attr_accessor :target_repository
|
7
|
+
|
8
|
+
# = Parameters
|
9
|
+
# attrs<Hash>:: fedora object attributes (see below)
|
10
|
+
#
|
11
|
+
# == Attributes (attrs)
|
12
|
+
# namespace<Symbol>::
|
13
|
+
# pid<Symbol>::
|
14
|
+
# state<Symbol>::
|
15
|
+
# label<Symbol>::
|
16
|
+
# contentModel<Symbol>::
|
17
|
+
# objectXMLFormat<Symbol>::
|
18
|
+
# ownerID<Symbol>::
|
19
|
+
#-
|
20
|
+
def initialize(attrs = nil)
|
21
|
+
super
|
22
|
+
# TODO: check for required attributes
|
23
|
+
end
|
24
|
+
|
25
|
+
####
|
26
|
+
# Attribute Accessors
|
27
|
+
####
|
28
|
+
|
29
|
+
# TODO: Create appropriate attribute accessors for these values.
|
30
|
+
# Where applicable, make sure that attributes are written to and read from self.attributes
|
31
|
+
# [pid, label, create_date, modified_date, fedora_object_type, contentModel, state, ownerID, behavior_def, behavior_mech,]
|
32
|
+
# API-M Search Value Equivalents: [pid, label, cDate, mDate, fType, cModel, state, ownerId, bDef, bMech,]
|
33
|
+
# TODO: Mix In DC attribute finders/accessors
|
34
|
+
# TODO: Make sure that fedora_object_type and contentModel are juggled properly.
|
35
|
+
def retrieve_attr_from_fedora
|
36
|
+
self.attributes.merge!(objectProfile)
|
37
|
+
self.attributes.merge!({
|
38
|
+
:state => objectXML.root.elements["objectProperties/property[@NAME='info:fedora/fedora-system:def/model#state']"].attributes["value"]
|
39
|
+
})
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_date
|
44
|
+
objectProfile[:create_date]
|
45
|
+
end
|
46
|
+
|
47
|
+
def modified_date
|
48
|
+
objectProfile[:modified_date]
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def pid
|
53
|
+
self.attributes[:pid]
|
54
|
+
end
|
55
|
+
|
56
|
+
def pid=(new_pid)
|
57
|
+
self.attributes.merge!({:pid => new_pid})
|
58
|
+
end
|
59
|
+
|
60
|
+
def state
|
61
|
+
self.attributes[:state]
|
62
|
+
end
|
63
|
+
|
64
|
+
def state=(new_state)
|
65
|
+
if ["I", "A", "D"].include? new_state
|
66
|
+
self.attributes[:state] = new_state
|
67
|
+
else
|
68
|
+
raise 'The object state of "' + new_state + '" is invalid. The allowed values for state are: A (active), D (deleted), and I (inactive).'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def label
|
73
|
+
self.attributes[:label]
|
74
|
+
end
|
75
|
+
|
76
|
+
def label=(new_label)
|
77
|
+
self.attributes[:label] = new_label
|
78
|
+
end
|
79
|
+
|
80
|
+
def content_model
|
81
|
+
self.attributes[:contentModel]
|
82
|
+
end
|
83
|
+
|
84
|
+
def content_model=(new_content_model)
|
85
|
+
self.attributes[:contentModel] = new_content_model
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get the object and read its @ownerId from the profile
|
89
|
+
def owner_id
|
90
|
+
self.attributes[:ownerID]
|
91
|
+
end
|
92
|
+
|
93
|
+
def owner_id=(new_owner_id)
|
94
|
+
self.attributes.merge!({:ownerID => new_owner_id})
|
95
|
+
end
|
96
|
+
|
97
|
+
def profile
|
98
|
+
# Use xmlsimple to slurp the attributes
|
99
|
+
objectProfile = XmlSimple.xml_in(@fedora.call_resource(:retrieve, :objects_profile, {:pid => @pid}))
|
100
|
+
# TODO: Find out if xmlsimple automatically expands camelCased element names...
|
101
|
+
profile_as_array = {
|
102
|
+
:owner_id => objectProfile[objOwnerId],
|
103
|
+
:content_model => objectProfile[objContentModel],
|
104
|
+
:label => objectProfile[objLabel],
|
105
|
+
:date_created => objectProfile[objCreateDate],
|
106
|
+
:date_modified => objectProfile[objLastModDate]
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def objectXML
|
111
|
+
# Use REXML to slurp the attributes (can't use xmlsimple because the XML is too complex. Need XPath-like queries.
|
112
|
+
@objectXML ||= REXML::Document.new(@fedora.call_resource(:retrieve, :objects_objectXml, {:pid => @pid}))
|
113
|
+
end
|
114
|
+
|
115
|
+
# See http://www.fedora.info/definitions/identifiers
|
116
|
+
def uri
|
117
|
+
"fedora:info/#{pid}"
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Fedora
|
2
|
+
module XmlFormat
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def extension
|
6
|
+
"xml"
|
7
|
+
end
|
8
|
+
|
9
|
+
def mime_type
|
10
|
+
"text/xml"
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode(hash)
|
14
|
+
hash.to_xml
|
15
|
+
end
|
16
|
+
|
17
|
+
def decode(xml)
|
18
|
+
from_xml_data(Hash.from_xml(xml))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def from_xml_data(data)
|
23
|
+
if data.is_a?(Hash) && data.keys.size == 1
|
24
|
+
data.values.first
|
25
|
+
else
|
26
|
+
data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'facets/hash/symbolize_keys'
|
2
|
+
|
3
|
+
require 'active_resource'
|
4
|
+
require 'fedora/connection'
|
5
|
+
require 'fedora/formats'
|
6
|
+
require 'fedora/fedora_object'
|
7
|
+
require 'fedora/datastream'
|
8
|
+
|
9
|
+
module Fedora
|
10
|
+
NAMESPACE = "fedora:info/"
|
11
|
+
ALL_FIELDS = [
|
12
|
+
:pid, :label, :fType, :cModel, :state, :ownerId, :cDate, :dcmDate,
|
13
|
+
:bMech, :title, :creator, :subject, :description, :contributor,
|
14
|
+
:date, :type, :format, :identifier, :source, :language, :relation, :coverage, :rights
|
15
|
+
]
|
16
|
+
|
17
|
+
class Repository
|
18
|
+
attr_accessor :fedora_url
|
19
|
+
|
20
|
+
def initialize(fedora_url = "http://localhost:8080/fedora")
|
21
|
+
@fedora_url = fedora_url.is_a?(URI) ? fedora_url : URI.parse(fedora_url)
|
22
|
+
@connection = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# Fetch the raw content of either a fedora object or datastream
|
26
|
+
def fetch_conent(object_uri)
|
27
|
+
connection.raw_get("#{url_for(object_uri)}?format=xml").body
|
28
|
+
end
|
29
|
+
|
30
|
+
# Find fedora objects with http://www.fedora.info/wiki/index.php/API-A-Lite_findObjects
|
31
|
+
#
|
32
|
+
# == Parameters
|
33
|
+
# query<String>:: the query string to be sent to Fedora.
|
34
|
+
# options<Hash>:: see below
|
35
|
+
#
|
36
|
+
# == Options<Hash> keys
|
37
|
+
# limit<String|Number>:: set the maxResults parameter in fedora
|
38
|
+
# select<Symbol|Array>:: the fields to returned. To include all fields, pass :all as the value.
|
39
|
+
# The field "pid" is always included.
|
40
|
+
#
|
41
|
+
# == Examples
|
42
|
+
# find_objects("label=Image1"
|
43
|
+
# find_objects("pid~demo:*", "label=test")
|
44
|
+
# find_objects("label=Image1", :include => :all)
|
45
|
+
# find_objects("label=Image1", :include => [:label])
|
46
|
+
#-
|
47
|
+
def find_objects(*args)
|
48
|
+
raise ArgumentError, "Missing query string" unless args.length >= 1
|
49
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
50
|
+
|
51
|
+
fields = options[:select]
|
52
|
+
fields = (fields.nil? || (fields == :all)) ? ALL_FIELDS : ([:pid] + ([fields].flatten! - [:pid]))
|
53
|
+
|
54
|
+
query = args.join(' ')
|
55
|
+
params = { :format => 'xml', :query => query }
|
56
|
+
params[:maxResults] = options[:limit] if options[:limit]
|
57
|
+
params[:sessionToken] = options[:sessionToken] if options[:sessionToken]
|
58
|
+
includes = fields.inject("") { |s, f| s += "&#{f}=true"; s }
|
59
|
+
|
60
|
+
convert_xml(connection.get("#{fedora_url.path}/objects?#{to_query(params)}#{includes}"))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Create the given object if it's new (not obtained from a find method). Otherwise update the object.
|
64
|
+
#
|
65
|
+
# == Return
|
66
|
+
# boolean:: whether the operation is successful
|
67
|
+
#-
|
68
|
+
def save(object)
|
69
|
+
object.new_object? ? create(object) : update(object)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create(object)
|
73
|
+
case object
|
74
|
+
when Fedora::FedoraObject
|
75
|
+
pid = (object.pid ? object : 'new')
|
76
|
+
response = connection.post("#{url_for(pid)}?" + object.attributes.to_query, object.xml_content)
|
77
|
+
if response.code == '201'
|
78
|
+
object.pid = extract_pid(response)
|
79
|
+
object.new_object = false
|
80
|
+
true
|
81
|
+
else
|
82
|
+
false
|
83
|
+
end
|
84
|
+
when Fedora::Datastream
|
85
|
+
raise ArgumentError, "Missing dsID attribute" if object.dsid.nil?
|
86
|
+
response = connection.post("#{url_for(object)}?" + object.attributes.to_query,
|
87
|
+
object.xml_content)
|
88
|
+
if response.code == '201'
|
89
|
+
object.new_object = false
|
90
|
+
true
|
91
|
+
else
|
92
|
+
false
|
93
|
+
end
|
94
|
+
else
|
95
|
+
raise ArgumentError, "Unknown object type"
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# Update the given object
|
101
|
+
# == Return
|
102
|
+
# boolean:: whether the operation is successful
|
103
|
+
#-
|
104
|
+
def update(object)
|
105
|
+
raise ArgumentError, "Missing pid attribute" if object.nil? || object.pid.nil?
|
106
|
+
case object
|
107
|
+
when Fedora::FedoraObject
|
108
|
+
response = connection.put("#{url_for(object)}?" + object.attributes.to_query)
|
109
|
+
response.code == '307'
|
110
|
+
when Fedora::Datastream
|
111
|
+
raise ArgumentError, "Missing dsID attribute" if object.dsid.nil?
|
112
|
+
response = connection.put("#{url_for(object)}?" + object.attributes.to_query, object.xml_content)
|
113
|
+
response.code == '201'
|
114
|
+
else
|
115
|
+
raise ArgumentError, "Unknown object type"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Delete the given pid
|
120
|
+
# == Parameters
|
121
|
+
# object<Object|String>:: The object to delete.
|
122
|
+
# This can be a uri String ("demo:1", "fedora:info/demo:1") or any object that responds uri method.
|
123
|
+
#
|
124
|
+
# == Return
|
125
|
+
# boolean:: whether the operation is successful
|
126
|
+
#-
|
127
|
+
def delete(object)
|
128
|
+
raise ArgumentError, "Object must not be nil" if object.nil?
|
129
|
+
response = connection.delete("#{url_for(object)}")
|
130
|
+
response.code == '200'
|
131
|
+
end
|
132
|
+
|
133
|
+
# Fetch the given object using custom method. This is used to fetch other aspects of a fedora object,
|
134
|
+
# such as profile, versions, etc...
|
135
|
+
# == Parameters
|
136
|
+
# object<String|Object>:: a fedora uri, pid, FedoraObject instance
|
137
|
+
# method<Symbol>:: the method to fetch such as :export, :history, :versions, etc
|
138
|
+
# extra_params<Hash>:: any other extra parameters to pass to fedora
|
139
|
+
#
|
140
|
+
# == Returns
|
141
|
+
# This method returns raw xml response from the server
|
142
|
+
#-
|
143
|
+
def fetch_custom(object, method, extra_params = { :format => 'xml' })
|
144
|
+
path = case method
|
145
|
+
when :profile then ""
|
146
|
+
else "/#{method}"
|
147
|
+
end
|
148
|
+
|
149
|
+
extra_params.delete(:format) if method == :export
|
150
|
+
connection.raw_get("#{url_for(object)}#{path}?#{to_query(extra_params)}").body
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
def convert_xml(response)
|
155
|
+
results = FedoraObjects.new
|
156
|
+
return results unless response && response['resultList']
|
157
|
+
|
158
|
+
results.session_token = response['listSession']['token'] if response['listSession']
|
159
|
+
objectFields = response['resultList']['objectFields']
|
160
|
+
case objectFields
|
161
|
+
when Array
|
162
|
+
objectFields.each { |attrs| results << FedoraObject.new(attrs.symbolize_keys!) }
|
163
|
+
when Hash
|
164
|
+
results << FedoraObject.new(objectFields.symbolize_keys!)
|
165
|
+
end
|
166
|
+
results
|
167
|
+
end
|
168
|
+
|
169
|
+
def url_for(object)
|
170
|
+
uri = object.respond_to?(:uri) ? object.uri : object.to_s
|
171
|
+
uri = (uri[0..NAMESPACE.length-1] == NAMESPACE ? uri[NAMESPACE.length..-1] : uri) # strip of fedora:info namespace
|
172
|
+
"#{fedora_url.path}/objects/#{uri}"
|
173
|
+
end
|
174
|
+
|
175
|
+
# Low level access to the remote fedora server
|
176
|
+
# The +refresh+ parameter toggles whether or not the connection is refreshed at every request
|
177
|
+
# or not (defaults to +false+).
|
178
|
+
def connection(refresh = false)
|
179
|
+
if refresh || @connection.nil?
|
180
|
+
@connection = ActiveResource::Connection.new(@fedora_url, Fedora::XmlFormat)
|
181
|
+
end
|
182
|
+
@connection
|
183
|
+
end
|
184
|
+
|
185
|
+
def extract_pid(response)
|
186
|
+
CGI.unescape(response['Location'].split('/').last)
|
187
|
+
end
|
188
|
+
|
189
|
+
# {:q => 'test', :num => 5}.to_query # => 'q=test&num=5'
|
190
|
+
def to_query(hash)
|
191
|
+
hash.collect { |key, value| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}" }.sort * '&'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class FedoraObjects < Array
|
197
|
+
attr_accessor :session_token
|
198
|
+
end
|
199
|
+
|