diff --git a/lib/avm/contact.rb b/lib/avm/contact.rb
index 00dff9b..62ecfa0 100644
--- a/lib/avm/contact.rb
+++ b/lib/avm/contact.rb
@@ -20,5 +20,9 @@ module AVM
def <=>(other)
self.name <=> other.name
end
+
+ def to_creator_list_element
+ %{#{self.name}}
+ end
end
end
diff --git a/lib/avm/creator.rb b/lib/avm/creator.rb
index 7e9fb85..65bac09 100644
--- a/lib/avm/creator.rb
+++ b/lib/avm/creator.rb
@@ -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,18 +16,36 @@ 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
- @options[key]
+ 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('')
+
+ 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)
if contact = primary_contact
@@ -33,10 +54,6 @@ module AVM
nil
end
end
-
- def primary_contact
- @contacts.find(&:primary) || @contacts.sort.first
- end
end
end
diff --git a/lib/avm/image.rb b/lib/avm/image.rb
index 1e99bd3..6ba015f 100644
--- a/lib/avm/image.rb
+++ b/lib/avm/image.rb
@@ -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)
+
+ 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
diff --git a/ruby-avm-library.gemspec b/ruby-avm-library.gemspec
index beb794d..ef7efee 100644
--- a/ruby-avm-library.gemspec
+++ b/ruby-avm-library.gemspec
@@ -21,4 +21,6 @@ Gem::Specification.new do |s|
s.add_development_dependency 'rspec'
s.add_development_dependency 'mocha'
+
+ s.add_dependency 'nokogiri'
end
diff --git a/spec/avm/contact_spec.rb b/spec/avm/contact_spec.rb
index c28371f..0c3e8df 100644
--- a/spec/avm/contact_spec.rb
+++ b/spec/avm/contact_spec.rb
@@ -37,6 +37,8 @@ describe AVM::Contact do
its(:zip) { should == postal_code }
its(:country) { should == country }
+ its(:to_creator_list_element) { should == "John Bintz" }
+
describe 'mappings' do
AVM::Contact::FIELD_MAP.each do |key, value|
context "#{key} => #{value}" do
diff --git a/spec/avm/creator_spec.rb b/spec/avm/creator_spec.rb
index 87ceb2a..42d9546 100644
--- a/spec/avm/creator_spec.rb
+++ b/spec/avm/creator_spec.rb
@@ -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
diff --git a/spec/avm/image_spec.rb b/spec/avm/image_spec.rb
index ff60f5e..a043fa5 100644
--- a/spec/avm/image_spec.rb
+++ b/spec/avm/image_spec.rb
@@ -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