Skip to content

Instantly share code, notes, and snippets.

@kardeiz
Created September 10, 2012 22:19
Show Gist options
  • Save kardeiz/3694401 to your computer and use it in GitHub Desktop.
Save kardeiz/3694401 to your computer and use it in GitHub Desktop.
Batch editing with DigiTool Web Services
#!/usr/bin/env ruby
require 'nokogiri'
require 'csv'
require 'savon'
Savon.configure do |config|
config.log = false
end
HTTPI.log = false
# define wsdl connection
CLIENT = Savon::Client.new do
wsdl.document = "http://libdigit1.lib.tcu.edu:1801/de_repository_web/services/DigitalEntityManager?wsdl"
end
# auth
GENERAL = Nokogiri::XML::Builder.new do |xml|
xml.general("xmlns:xb"=>"http://com/exlibris/digitool/repository/api/xmlbeans") {
xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=="xb"}
xml.application { xml.parent.namespace = nil; xml.text "DIGITOOL-3" }
xml.owner { xml.parent.namespace = nil; xml.text "SPC01" }
xml.interface_version { xml.parent.namespace = nil; xml.text "1.0" }
xml.user { xml.parent.namespace = nil; xml.text "creator:JHBROWN" }
xml.password { xml.parent.namespace = nil; xml.text "mypass" }
}
end.to_xml
def read_query_builder(pid)
Nokogiri::XML::Builder.new do |xml|
xml.digital_entity_call("xmlns:xb"=>"http://com/exlibris/digitool/repository/api/xmlbeans") {
xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=="xb"}
xml.digital_entity { xml.pid { xml.parent.namespace = nil; xml.text pid } }
xml.command { xml.parent.namespace = nil; xml.text "retrieve" }
}
end.to_xml
end
def update_query_builder(pid, mid, xml_block)
query = Nokogiri::XML::Builder.new do |xml|
xml.digital_entity_call("xmlns:xb"=>"http://com/exlibris/digitool/repository/api/xmlbeans") {
xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=="xb"}
xml.digital_entity {
xml.pid {
xml.parent.namespace = nil
xml.text pid
}
xml.mds {
xml.parent.namespace = nil
xml.md("cmd" => "update") {
xml.parent.namespace = nil
xml.mid { xml.parent.namespace = nil; xml.text mid }
xml.name { xml.parent.namespace = nil; xml.text "descriptive" }
xml.type { xml.parent.namespace = nil; xml.text "dc" }
xml.value {
xml.parent.namespace = nil
xml.cdata(xml_block)
}
}
}
}
xml.command { xml.parent.namespace = nil; xml.text "update" }
}
end.to_xml
return query
end
def soap_proc(client,general,query)
response = client.request :api, :digital_entity_call, "env:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/" do
soap.namespaces["xmlns:api"] = "http://api.repository.digitool.exlibris.com"
xdoc = Nokogiri::XML::DocumentFragment.parse ""; Nokogiri::XML::Builder.with(xdoc) do |xml|
xml.general("xsi:type" => "soapenc:string", "xmlns:soapenc" => "http://schemas.xmlsoap.org/soap/encoding/") { xml.cdata general }
xml.query("xsi:type" => "soapenc:string", "xmlns:soapenc" => "http://schemas.xmlsoap.org/soap/encoding/") { xml.cdata query }
end
soap.body = xdoc
end
return (response.to_hash)[:digital_entity_call_response][:digital_entity_call_return]
end
# method returns nil unless has Dublin Core md
def get_dc_stuff(xml_string)
(Nokogiri::XML(xml_string)).at_xpath("//md[type='dc']/value").tap do |o|
temp = {}
temp[:mid] = o.at_xpath("../mid/text()").content unless o.nil? rescue nil
temp[:content] = Nokogiri::XML(o.content).to_xml unless o.nil? rescue nil
return temp
end
end
def change_add_dates(xml_block,new_date,numeric_date)
temp = nil
temp = Nokogiri::XML(xml_block)
temp.at_xpath("//dc:date","dc" => "http://purl.org/dc/elements/1.1/").content = new_date
if temp.root.namespace_definitions.find{|ns|ns.prefix=="dcterms"}.nil?
temp.root.add_namespace_definition("dcterms","http://purl.org/dc/terms/")
end
unless numeric_date.nil? || temp.at_xpath("//dcterms:issued","dcterms" => "http://purl.org/dc/terms/")
numeric = nil
numeric = Nokogiri::XML::Node.new "issued", temp
numeric.namespace = temp.root.namespace_definitions.find{|ns|ns.prefix=="dcterms"}
numeric.content = numeric_date
temp.root.add_child(numeric)
end
return temp.to_xml
end
f = File.open('/home/jhbrown/shared_with_fedora/dates_to_convert_checked_by_Amy.csv') do |file|
CSV.parse(file.read) # , :headers => true, :header_converters => :symbol)
end
# done so far -> 1000 AND 3000 ->
g = f[1..-1].sort_by{|x|x[0]}
# require 'csv'; f = File.open('/home/jhbrown/shared_with_fedora/dates_to_convert_checked_by_Amy.csv') { |file| CSV.parse(file.read) }; g = f[1..-1].sort_by{|x|x[0]};
dothis = g[892..1000]
output = []
dothis.each_with_index do |x, index|
puts "Working: #{x[0]}"
pid = x[0]; new_date = x[2]; numeric_date = x[3]
raw_xml = soap_proc(CLIENT, GENERAL, read_query_builder(pid))
parsed_xml = get_dc_stuff(raw_xml)
fixed_dates = change_add_dates(parsed_xml[:content],new_date,numeric_date)
query = update_query_builder(pid, parsed_xml[:mid], fixed_dates)
# output << fixed_dates
# output << soap_proc(CLIENT, GENERAL, query)
tempo = Nokogiri::XML(soap_proc(CLIENT, GENERAL, query))
output << tempo.at_xpath("//pid/text()").content rescue "Error: #{pid}"
sleep 10 and puts "Sleeping..." if index % 50 == 0
end
puts "---"
puts output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment