read one creator
This commit is contained in:
parent
29449d381b
commit
efff98eb32
@ -7,10 +7,13 @@ module AVM
|
||||
|
||||
IPTC_CORE_FIELDS = [ :address, :city, :state, :zip, :country ]
|
||||
PRIMARY_CONTACT_FIELDS = IPTC_CORE_FIELDS + [ :province, :postal_code ]
|
||||
IPTC_MULTI_FIELD_MAP = [ [ :telephone, 'CiTelWork' ], [ :email, 'CiEmailWork' ] ]
|
||||
IPTC_CORE_FIELD_ELEMENT_NAMES = %w{CiAdrExtadr CiAdrCity CiAdrRegion CiAdrPcode CiAdrCtry}
|
||||
IPTC_CORE_FIELDS_AND_NAMES = IPTC_CORE_FIELDS.zip(IPTC_CORE_FIELD_ELEMENT_NAMES)
|
||||
|
||||
def initialize(image)
|
||||
def initialize(image, given_contacts = [])
|
||||
@options = {}
|
||||
@contacts = []
|
||||
@contacts = given_contacts
|
||||
@image = image
|
||||
end
|
||||
|
||||
@ -18,6 +21,14 @@ module AVM
|
||||
@options.merge!(hash)
|
||||
end
|
||||
|
||||
def length
|
||||
contacts.length
|
||||
end
|
||||
|
||||
def [](which)
|
||||
contacts[which]
|
||||
end
|
||||
|
||||
def method_missing(key, *opts)
|
||||
if key.to_s[-1..-1] == '='
|
||||
@options[key.to_s[0..-2].to_sym] = opts.first
|
||||
@ -31,7 +42,7 @@ module AVM
|
||||
end
|
||||
|
||||
def add_to_document(document)
|
||||
document.add_to_doc do |refs|
|
||||
document.get_refs do |refs|
|
||||
creator = refs[:dublin_core].add_child('<dc:creator><rdf:Seq></rdf:Seq></dc:creator>')
|
||||
|
||||
list = creator.at_xpath('.//rdf:Seq')
|
||||
@ -42,13 +53,13 @@ module AVM
|
||||
end
|
||||
|
||||
if primary_contact
|
||||
[ [ :telephone, 'CiTelWork' ], [ :email, 'CiEmailWork' ] ].each do |key, element_name|
|
||||
IPTC_MULTI_FIELD_MAP.each do |key, element_name|
|
||||
contact_info.add_child "<Iptc4xmpCore:#{element_name}>#{contacts.sort.collect(&key).join(',')}</Iptc4xmpCore:#{element_name}>"
|
||||
end
|
||||
|
||||
iptc_namespace = document.doc.root.namespace_scopes.find { |ns| ns.prefix == 'Iptc4xmpCore' }
|
||||
|
||||
IPTC_CORE_FIELDS.zip(%w{CiAdrExtadr CiAdrCity CiAdrRegion CiAdrPcode CiAdrCtry}).each do |key, element_name|
|
||||
IPTC_CORE_FIELDS_AND_NAMES.each do |key, element_name|
|
||||
node = contact_info.document.create_element(element_name, primary_contact.send(key))
|
||||
node.namespace = iptc_namespace
|
||||
contact_info.add_child node
|
||||
@ -57,6 +68,31 @@ module AVM
|
||||
end
|
||||
end
|
||||
|
||||
def from_xml(image, document)
|
||||
contacts = []
|
||||
document.get_refs do |refs|
|
||||
refs[:dublin_core].search('.//rdf:li').each do |name|
|
||||
contacts << { :name => name.text }
|
||||
end
|
||||
|
||||
IPTC_MULTI_FIELD_MAP.each do |key, element_name|
|
||||
if node = refs[:iptc].at_xpath("//Iptc4xmpCore:#{element_name}")
|
||||
node.text.split(',').collect(&:strip).each_with_index do |value, index|
|
||||
contacts[index][key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
IPTC_CORE_FIELDS_AND_NAMES.each do |key, element_name|
|
||||
if node = refs[:iptc].at_xpath("//Iptc4xmpCore:#{element_name}")
|
||||
contacts.first[key] = node.text.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@contacts = contacts.collect { |contact| Contact.new(contact) }
|
||||
end
|
||||
|
||||
def primary_contact
|
||||
@contacts.find(&:primary) || @contacts.sort.first
|
||||
end
|
||||
|
@ -16,6 +16,14 @@ module AVM
|
||||
|
||||
document.doc
|
||||
end
|
||||
|
||||
def self.from_xml(string)
|
||||
document = AVM::XMP.from_string(string)
|
||||
|
||||
image = new
|
||||
image.creator.from_xml(self, document)
|
||||
image
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,15 +4,49 @@ module AVM
|
||||
class XMP
|
||||
attr_reader :doc
|
||||
|
||||
def initialize
|
||||
@doc = empty_xml_doc
|
||||
def initialize(doc = nil)
|
||||
@doc = doc || empty_xml_doc
|
||||
ensure_namespaces!
|
||||
ensure_descriptions_findable!
|
||||
end
|
||||
|
||||
def add_to_doc
|
||||
def get_refs
|
||||
yield Hash[[ :dublin_core, :iptc ].collect { |key| [ key, send(key) ] }]
|
||||
end
|
||||
|
||||
def self.from_string(string)
|
||||
new(Nokogiri::XML(string))
|
||||
end
|
||||
|
||||
private
|
||||
def ensure_namespaces!
|
||||
{
|
||||
:x => "adobe:ns:meta/",
|
||||
:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||
:dc => "http://purl.org/dc/elements/1.1/",
|
||||
:photoshop => "http://ns.adobe.com/photoshop/1.0/",
|
||||
:avm => "http://www.communicatingastronomy.org/avm/1.0/",
|
||||
:Iptc4xmpCore => "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||
}.each do |namespace, url|
|
||||
doc.root.add_namespace_definition(namespace.to_s, url)
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_descriptions_findable!
|
||||
doc.search('//rdf:Description').each do |description|
|
||||
if first_child = description.first_element_child
|
||||
if first_child.namespace
|
||||
case first_child.namespace.prefix
|
||||
when 'dc'
|
||||
description['about'] = 'Dublin Core'
|
||||
when 'Iptc4xmpCore'
|
||||
description['about'] = 'IPTC'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def dublin_core
|
||||
at_rdf_description "Dublin Core"
|
||||
end
|
||||
@ -26,7 +60,7 @@ module AVM
|
||||
end
|
||||
|
||||
def empty_xml_doc
|
||||
document = Nokogiri::XML(<<-XML)
|
||||
Nokogiri::XML(<<-XML)
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:RDF>
|
||||
<rdf:Description about="Dublin Core">
|
||||
@ -38,17 +72,6 @@ module AVM
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
XML
|
||||
|
||||
{
|
||||
:dc => "http://purl.org/dc/elements/1.1/",
|
||||
:photoshop => "http://ns.adobe.com/photoshop/1.0/",
|
||||
:avm => "http://www.communicatingastronomy.org/avm/1.0/",
|
||||
:Iptc4xmpCore => "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
||||
}.each do |namespace, url|
|
||||
document.root.add_namespace_definition(namespace.to_s, url)
|
||||
end
|
||||
|
||||
document
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -91,6 +91,51 @@ describe AVM::Creator do
|
||||
its(:name) { should == first_name }
|
||||
end
|
||||
|
||||
describe '#from_xml' do
|
||||
let(:document) { image.to_xml }
|
||||
let(:image) { AVM::Image.from_xml(File.read(file_path)) }
|
||||
|
||||
subject { image }
|
||||
|
||||
context 'no creator' do
|
||||
let(:file_path) { 'spec/sample_files/creator/no_creator.xmp' }
|
||||
|
||||
its('creator.length') { should == 0 }
|
||||
end
|
||||
|
||||
context 'one creator' do
|
||||
let(:file_path) { 'spec/sample_files/creator/one_creator.xmp' }
|
||||
|
||||
its('creator.length') { should == 1 }
|
||||
|
||||
context 'creator one' do
|
||||
subject { image.creator[0] }
|
||||
|
||||
let(:name) { 'John Bintz' }
|
||||
let(:email) { 'bintz@stsci.edu' }
|
||||
let(:telephone) { '800-555-1234' }
|
||||
let(:address) { '3700 San Martin Drive' }
|
||||
let(:city) { 'Baltimore' }
|
||||
let(:state) { 'Maryland' }
|
||||
let(:zip) { '21218' }
|
||||
let(:country) { 'USA' }
|
||||
|
||||
its(:name) { should == name }
|
||||
its(:address) { should == address }
|
||||
its(:city) { should == city }
|
||||
its(:state) { should == state }
|
||||
its(:zip) { should == zip }
|
||||
its(:country) { should == country }
|
||||
its(:email) { should == email }
|
||||
its(:telephone) { should == telephone }
|
||||
end
|
||||
end
|
||||
|
||||
context 'two creators' do
|
||||
let(:file_path) { 'spec/sample_files/creator/two_creators.xmp' }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'contact name node' do
|
||||
let(:first_name) { 'John' }
|
||||
let(:second_name) { 'Zohn' }
|
||||
|
@ -4,9 +4,11 @@ require 'avm/xmp'
|
||||
describe AVM::XMP do
|
||||
let(:xmp) { self.class.describes.new }
|
||||
|
||||
describe '#add_to_doc' do
|
||||
subject { xmp }
|
||||
|
||||
describe '#get_refs' do
|
||||
before {
|
||||
xmp.add_to_doc do |refs|
|
||||
xmp.get_refs do |refs|
|
||||
refs[:dublin_core] << "<rdf:addedToDublinCore />"
|
||||
refs[:iptc] << "<rdf:addedToIPTC />"
|
||||
end
|
||||
@ -15,4 +17,46 @@ describe AVM::XMP do
|
||||
specify { xmp.doc.at_xpath('//rdf:Description[@about="Dublin Core"]//rdf:addedToDublinCore').should_not be_nil }
|
||||
specify { xmp.doc.at_xpath('//rdf:Description[@about="IPTC"]//rdf:addedToIPTC').should_not be_nil }
|
||||
end
|
||||
|
||||
describe '.from_string' do
|
||||
let(:xmp) { self.class.describes.from_string(string) }
|
||||
let(:string) { '<xml><node /></xml>' }
|
||||
|
||||
specify { xmp.doc.at_xpath('//node').should_not be_nil }
|
||||
end
|
||||
|
||||
describe '#ensure_descriptions_findable!' do
|
||||
let(:document) { <<-XML }
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
#{content}
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
XML
|
||||
|
||||
let(:xmp) { self.class.describes.new(Nokogiri::XML(document)) }
|
||||
|
||||
context 'no nodes within' do
|
||||
let(:content) { '' }
|
||||
|
||||
[ 'Dublin Core', 'IPTC' ].each do |which|
|
||||
specify { xmp.doc.at_xpath(%{//rdf:Description[@about="#{which}"]}).should be_nil }
|
||||
end
|
||||
end
|
||||
|
||||
context 'has identifying nodes within' do
|
||||
let(:content) { <<-XML }
|
||||
<rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:creator />
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about="" xmlns:Iptc4xmpCore="http://itpc.org/stf/Iptc4xmpCore/1.0/xmlns/">
|
||||
<Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource" />
|
||||
</rdf:Description>
|
||||
XML
|
||||
|
||||
[ 'Dublin Core', 'IPTC' ].each do |which|
|
||||
specify { xmp.doc.at_xpath(%{//rdf:Description[@about="#{which}"]}).should_not be_nil }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
14
spec/sample_files/creator/no_creator.xmp
Normal file
14
spec/sample_files/creator/no_creator.xmp
Normal file
@ -0,0 +1,14 @@
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.2-c063 53.352624, 2008/07/30-18:05:41 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:creator />
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
|
||||
<Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource">
|
||||
</Iptc4xmpCore:CreatorContactInfo>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
25
spec/sample_files/creator/one_creator.xmp
Normal file
25
spec/sample_files/creator/one_creator.xmp
Normal file
@ -0,0 +1,25 @@
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2.2-c063 53.352624, 2008/07/30-18:05:41 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:creator>
|
||||
<rdf:Seq><rdf:li>John Bintz</rdf:li></rdf:Seq>
|
||||
</dc:creator>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/">
|
||||
<Iptc4xmpCore:CreatorContactInfo rdf:parseType="Resource">
|
||||
<Iptc4xmpCore:CiAdrExtadr>3700 San Martin Drive</Iptc4xmpCore:CiAdrExtadr>
|
||||
<Iptc4xmpCore:CiAdrCity>Baltimore</Iptc4xmpCore:CiAdrCity>
|
||||
<Iptc4xmpCore:CiAdrRegion>Maryland</Iptc4xmpCore:CiAdrRegion>
|
||||
<Iptc4xmpCore:CiAdrPcode>21218</Iptc4xmpCore:CiAdrPcode>
|
||||
<Iptc4xmpCore:CiAdrCtry>USA</Iptc4xmpCore:CiAdrCtry>
|
||||
<Iptc4xmpCore:CiTelWork>800-555-1234</Iptc4xmpCore:CiTelWork>
|
||||
<Iptc4xmpCore:CiEmailWork>bintz@stsci.edu</Iptc4xmpCore:CiEmailWork>
|
||||
<Iptc4xmpCore:CiUrlWork>http://hubblesite.org</Iptc4xmpCore:CiUrlWork>
|
||||
</Iptc4xmpCore:CreatorContactInfo>
|
||||
</rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.mock_with :mocha
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user