contacts to xml

This commit is contained in:
John Bintz 2011-03-09 10:14:31 -05:00
parent 8f21381475
commit 59320b3420
7 changed files with 127 additions and 14 deletions

View File

@ -20,5 +20,9 @@ module AVM
def <=>(other)
self.name <=> other.name
end
def to_creator_list_element
%{<rdf:li>#{self.name}</rdf:li>}
end
end
end

View File

@ -1,9 +1,12 @@
require 'avm/contact'
require 'nokogiri'
module AVM
class Creator
attr_reader :contacts
PRIMARY_CONTACT_FIELDS = [ :address, :city, :state, :province, :postal_code, :zip, :country ]
def initialize
@options = {}
@contacts = []
@ -13,17 +16,35 @@ module AVM
@options.merge!(hash)
end
def address
primary_contact_field :address
end
def method_missing(key, *opts)
if key.to_s[-1..-1] == '='
@options[key.to_s[0..-2].to_sym] = opts.first
else
if PRIMARY_CONTACT_FIELDS.include?(key)
primary_contact_field key
else
@options[key]
end
end
end
def add_to_rdf(rdf)
creator = rdf.add_child('<dc:creator><rdf:Seq></rdf:Seq></dc:creator>')
list = creator.at_xpath('.//rdf:Seq')
contacts.sort.each { |contact| list.add_child(contact.to_creator_list_element) }
end
def primary_contact
@contacts.find(&:primary) || @contacts.sort.first
end
def create_contact(info)
contact = Contact.new(info)
contacts << contact
contact
end
private
def primary_contact_field(field)
@ -33,10 +54,6 @@ module AVM
nil
end
end
def primary_contact
@contacts.find(&:primary) || @contacts.sort.first
end
end
end

View File

@ -7,6 +7,34 @@ module AVM
def initialize
@creator = AVM::Creator.new
end
def to_xml
document = empty_xml_doc
rdf = document.at_xpath('//rdf:RDF')
creator.add_to_rdf(rdf)
document
end
private
def empty_xml_doc
document = 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: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/",
:Iptc4xmlCore => "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

View File

@ -21,4 +21,6 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rspec'
s.add_development_dependency 'mocha'
s.add_dependency 'nokogiri'
end

View File

@ -37,6 +37,8 @@ describe AVM::Contact do
its(:zip) { should == postal_code }
its(:country) { should == country }
its(:to_creator_list_element) { should == "<rdf:li>John Bintz</rdf:li>" }
describe 'mappings' do
AVM::Contact::FIELD_MAP.each do |key, value|
context "#{key} => #{value}" do

View File

@ -40,29 +40,80 @@ describe AVM::Creator do
end
context 'one contact, must be primary' do
let(:first_contact) { AVM::Contact.new(:name => 'zz bill', :address => first_contact_address) }
let(:first_contact) { AVM::Contact.new(
:name => 'zz bill',
:address => first_contact_address,
:city => first_contact_address,
:state => first_contact_address,
:postal_code => first_contact_address,
:country => first_contact_address
) }
let(:first_contact_address) { 'first contact' }
before { creator.contacts << first_contact }
its(:address) { should == first_contact_address }
fields = [ :address, :city, :state, :province, :postal_code, :zip, :country ]
fields.each { |field| its(field) { should == first_contact_address } }
context 'two contacts' do
let(:second_contact) { AVM::Contact.new(:name => 'aa bill', :address => second_contact_address) }
let(:second_contact) { AVM::Contact.new(
:name => 'aa bill',
:address => second_contact_address,
:city => second_contact_address,
:state => second_contact_address,
:postal_code => second_contact_address,
:country => second_contact_address
) }
let(:second_contact_address) { 'second contact' }
before { creator.contacts << second_contact }
context 'no primary, first alphabetical is primary' do
its(:address) { should == second_contact_address }
fields.each { |field| its(field) { should == second_contact_address } }
end
context 'one is primary, use it' do
before { first_contact.primary = true }
its(:address) { should == first_contact_address }
fields.each { |field| its(field) { should == first_contact_address } }
end
end
end
end
describe '#create_contact' do
let(:first_name) { 'John' }
let(:first_contact) { creator.create_contact(:name => first_name) }
subject { creator.primary_contact }
before { first_contact }
its(:name) { should == first_name }
end
describe 'contact name node' do
let(:first_name) { 'John' }
let(:second_name) { 'Zohn' }
let(:first_contact) { creator.create_contact(:name => first_name) }
let(:second_contact) { creator.create_contact(:name => second_name) }
subject { image.to_xml.search('//dc:creator/rdf:Seq/rdf:li').collect { |node| node.text } }
context 'no contacts' do
it { should == [] }
end
context 'one contact' do
before { first_contact }
it { should == [ first_name ] }
end
context 'second contact' do
before { second_contact ; first_contact }
it { should == [ first_name, second_name ] }
end
end
end

View File

@ -11,5 +11,14 @@ describe AVM::Image do
its(:creator) { should be_a_kind_of(AVM::Creator) }
end
describe '#to_xml' do
let(:xml) { image.to_xml }
context 'nothing in it' do
subject { xml.at_xpath('//rdf:RDF').should_not be_nil }
subject { xml.search('//rdf:RDF/rdf:Description').should be_empty }
end
end
end