xmp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # http://rvm.beginrescueend.com/workflow/rvmrc/
4
+
5
+ ruby_string="ruby-1.9.2"
6
+ gemset_name="xmp"
7
+
8
+ if rvm list strings | grep -q "${ruby_string}" ; then
9
+
10
+ # Load or create the specified environment
11
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
12
+ && -s "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}" ]] ; then
13
+ \. "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}"
14
+ else
15
+ rvm --create "${ruby_string}@${gemset_name}"
16
+ fi
17
+
18
+ # (
19
+ # Ensure that Bundler is installed, install it if it is not.
20
+ if ! command -v bundle &> /dev/null; then
21
+ echo "Installing bundler and creating bundle"
22
+ gem install bundler
23
+ bundle
24
+ fi
25
+ # )&
26
+
27
+ else
28
+
29
+ # Notify the user to install the desired interpreter before proceeding.
30
+ echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
31
+
32
+ fi
33
+
34
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,51 @@
1
+ = xmp - Extensible Metadata Platform (XMP) parser
2
+
3
+ XMP provides object oriented interface to XMP data (http://en.wikipedia.org/wiki/Extensible_Metadata_Platform). XMP data can be found in PDF, JPEG, GIF, PNG, and many other formats.
4
+
5
+ == Supported formats
6
+
7
+ Currently only JPEG is supported through exifr gem.
8
+
9
+ == JPEG example
10
+
11
+ # gem install xmp exifr
12
+ require 'xmp'
13
+ require 'exifr'
14
+ require 'open-uri'
15
+
16
+ img = EXIFR::JPEG.new('spec/fixtures/multiple-app1.jpg')
17
+ xmp = XMP.parse(img)
18
+ xmp.dc.subject #=> ["something interesting"]
19
+
20
+ # explore XMP data
21
+ xmp.namespaces.each do |namespace_name|
22
+ namespace = xmp.send(namespace_name)
23
+ namespace.attributes.each do |attr|
24
+ puts "#{namespace_name}.#{attr}: " + namespace.send(attr).inspect
25
+ end
26
+ end
27
+
28
+ == Installation
29
+
30
+ gem install xmp
31
+ # for JPEG support
32
+ gem install exifr -v ">=1.0.4"
33
+
34
+ == Requirements
35
+
36
+ * Ruby 1.8.7, 1.9.2
37
+ * Nokogiri 1.4
38
+ * EXIFR >= 1.0.4
39
+
40
+ == Development
41
+
42
+ # install development dependencies
43
+ bundle install
44
+ # run specs
45
+ rake spec
46
+
47
+ == License
48
+
49
+ Ruby's license.
50
+
51
+ Copyright (c) 2011 Wojciech Piekutowski, AmberBit (http://amberbit.com)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :default => :spec
6
+
7
+ desc "Run all specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.ruby_opts = "-w"
10
+ t.verbose = true
11
+ t.skip_bundler = true
12
+ end
data/lib/xmp.rb ADDED
@@ -0,0 +1,70 @@
1
+ require 'xmp/silencer'
2
+ XMP::Silencer.silently { require 'nokogiri' }
3
+ require 'xmp/namespace'
4
+
5
+ # = XMP XML parser
6
+ #
7
+ # == Example
8
+ # xmp = XMP.new(File.read('xmp.xml'))
9
+ # xmp.dc.title # => "Amazing Photo"
10
+ # xmp.photoshop.Category # => "summer"
11
+ # xmp.photoshop.SupplementalCategories # => ["morning", "sea"]
12
+ class XMP
13
+ # underlying XML content
14
+ attr_reader :xml
15
+ # available namespace names
16
+ attr_reader :namespaces
17
+
18
+ # accepts valid XMP XML
19
+ def initialize(xml)
20
+ doc = Nokogiri::XML(xml)
21
+ @xml = doc.root
22
+
23
+ available_namespaces = doc.collect_namespaces
24
+ # let nokogiri know about all namespaces
25
+ available_namespaces.each do |ns, url|
26
+ @xml.add_namespace_definition ns, url
27
+ end
28
+
29
+ # collect namespace names
30
+ @namespaces = available_namespaces.collect do |ns, _|
31
+ ns =~ /^xmlns:(.+)/
32
+ $1
33
+ end
34
+ end
35
+
36
+ def inspect
37
+ "#<XMP:@namespaces=#{@namespaces.inspect}>"
38
+ end
39
+
40
+ # returns Namespace object if namespace exists, otherwise tries to call a method
41
+ def method_missing(namespace, *args)
42
+ if has_namespace?(namespace)
43
+ Namespace.new(self, namespace)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ def respond_to?(method)
50
+ has_namespace?(method) or super
51
+ end
52
+
53
+ def self.parse(doc)
54
+ case doc.class.to_s
55
+ when 'EXIFR::JPEG'
56
+ if xmp_chunk = doc.app1s.find { |a| a =~ %r|\Ahttp://ns.adobe.com/xap/1.0/| }
57
+ xmp_data = xmp_chunk.split("\000")[1]
58
+ XMP.new(xmp_data)
59
+ end
60
+ else
61
+ raise "Document not supported:\n#{doc.inspect}"
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def has_namespace?(namespace)
68
+ namespaces.include?(namespace.to_s)
69
+ end
70
+ end
@@ -0,0 +1,69 @@
1
+ class XMP
2
+ class Namespace
3
+ # available attributes
4
+ attr_reader :attributes
5
+
6
+ def initialize(xmp, namespace) # :nodoc
7
+ @xmp = xmp
8
+ @namespace = namespace.to_s
9
+
10
+ @attributes = []
11
+ embedded_attributes =
12
+ xml.xpath("//rdf:Description").map { |d|
13
+ d.attributes.values.
14
+ select { |attr| attr.namespace.prefix.to_s == @namespace }.
15
+ map(&:name)
16
+ }.flatten
17
+ @attributes.concat embedded_attributes
18
+ standalone_attributes = xml.xpath("//rdf:Description/#{@namespace}:*").
19
+ map(&:name)
20
+ @attributes.concat standalone_attributes
21
+ end
22
+
23
+ def inspect
24
+ "#<XMP::Namespace:#{@namespace}>"
25
+ end
26
+
27
+ def method_missing(method, *args)
28
+ if has_attribute?(method)
29
+ embedded_attribute(method) || standalone_attribute(method)
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def respond_to?(method)
36
+ has_attribute?(method) or super
37
+ end
38
+
39
+ private
40
+
41
+ def embedded_attribute(name)
42
+ element = xml.at("//rdf:Description[@#{@namespace}:#{name}]")
43
+ return unless element
44
+ element.attribute(name.to_s).text
45
+ end
46
+
47
+ def has_attribute?(name)
48
+ attributes.include?(name.to_s)
49
+ end
50
+
51
+ def standalone_attribute(name)
52
+ attribute_xpath = "//#{@namespace}:#{name}"
53
+ attribute = xml.xpath(attribute_xpath).first
54
+ return unless attribute
55
+
56
+ array_value = attribute.xpath("./rdf:Bag | ./rdf:Seq | ./rdf:Alt").first
57
+ if array_value
58
+ items = array_value.xpath("./rdf:li")
59
+ items.map { |i| i.text }
60
+ else
61
+ raise "Don't know how to handle: \n" + attribute.to_s
62
+ end
63
+ end
64
+
65
+ def xml
66
+ @xmp.xml
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ class XMP
2
+ module Silencer
3
+ def self.silently
4
+ verbosity = $VERBOSE
5
+ $VERBOSE = nil
6
+ result = yield
7
+ $VERBOSE = verbosity
8
+ result
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ class XMP
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ require './spec/spec_helper.rb'
2
+
3
+ describe "XMP with EXIFR::JPEG" do
4
+ before do
5
+ XMP::Silencer.silently { @img = EXIFR::JPEG.new('spec/fixtures/multiple-app1.jpg') }
6
+ end
7
+
8
+ it "should parse image" do
9
+ xmp = XMP.parse(@img)
10
+ xmp.should be_instance_of(XMP)
11
+ xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
12
+ end
13
+ end
Binary file
@@ -0,0 +1,239 @@
1
+ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
2
+ <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 4.2-c020 1.124078, Tue Sep 11 2007 23:21:40 ">
3
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
4
+ <rdf:Description rdf:about=""
5
+ xmlns:tiff="http://ns.adobe.com/tiff/1.0/"
6
+ xmlns:exif="http://ns.adobe.com/exif/1.0/"
7
+ xmlns:xap="http://ns.adobe.com/xap/1.0/"
8
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
9
+ xmlns:aux="http://ns.adobe.com/exif/1.0/aux/"
10
+ xmlns:Iptc4xmpCore="http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
11
+ xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
12
+ xmlns:crs="http://ns.adobe.com/camera-raw-settings/1.0/"
13
+ tiff:Make="Canon"
14
+ tiff:Model="Canon EOS-1D Mark III"
15
+ tiff:ImageWidth="800"
16
+ tiff:ImageLength="533"
17
+ tiff:XResolution="72/1"
18
+ tiff:YResolution="72/1"
19
+ tiff:ResolutionUnit="2"
20
+ exif:ExifVersion="0221"
21
+ exif:ExposureTime="1/320"
22
+ exif:ShutterSpeedValue="8321928/1000000"
23
+ exif:FNumber="35/10"
24
+ exif:ApertureValue="361471/100000"
25
+ exif:ExposureProgram="1"
26
+ exif:DateTimeOriginal="2011-01-18T15:48:52.00+01:00"
27
+ exif:DateTimeDigitized="2011-01-18T15:48:52.00+01:00"
28
+ exif:ExposureBiasValue="0/1"
29
+ exif:MaxApertureValue="175/100"
30
+ exif:SubjectDistance="727/100"
31
+ exif:MeteringMode="5"
32
+ exif:FocalLength="85/1"
33
+ exif:CustomRendered="0"
34
+ exif:ExposureMode="1"
35
+ exif:WhiteBalance="0"
36
+ exif:SceneCaptureType="0"
37
+ exif:FocalPlaneXResolution="3888000/1107"
38
+ exif:FocalPlaneYResolution="2592000/736"
39
+ exif:FocalPlaneResolutionUnit="2"
40
+ exif:PixelXDimension="800"
41
+ exif:PixelYDimension="533"
42
+ xap:ModifyDate="2011-02-04T11:12:00+01:00"
43
+ xap:CreateDate="2011-01-18T15:48:52.00+01:00"
44
+ xap:CreatorTool="Adobe Photoshop Lightroom"
45
+ aux:SerialNumber="562133"
46
+ aux:LensInfo="85/1 85/1 0/0 0/0"
47
+ aux:Lens="EF85mm f/1.8 USM"
48
+ aux:LensID="155"
49
+ aux:ImageNumber="0"
50
+ aux:FlashCompensation="0/1"
51
+ aux:OwnerName="John Doe"
52
+ aux:Firmware="1.2.3"
53
+ Iptc4xmpCore:Location="Miejsce"
54
+ photoshop:Category="Kategoria"
55
+ photoshop:LegacyIPTCDigest="7220E75D669D5F417F2D6C9ADA130467"
56
+ crs:Version="6.1"
57
+ crs:ProcessVersion="5.7"
58
+ crs:WhiteBalance="As Shot"
59
+ crs:Temperature="4950"
60
+ crs:Tint="-6"
61
+ crs:Exposure="-0.75"
62
+ crs:Shadows="15"
63
+ crs:Brightness="+92"
64
+ crs:Contrast="+27"
65
+ crs:Saturation="+5"
66
+ crs:Sharpness="25"
67
+ crs:LuminanceSmoothing="0"
68
+ crs:ColorNoiseReduction="25"
69
+ crs:ChromaticAberrationR="0"
70
+ crs:ChromaticAberrationB="0"
71
+ crs:VignetteAmount="-61"
72
+ crs:VignetteMidpoint="50"
73
+ crs:ShadowTint="0"
74
+ crs:RedHue="+14"
75
+ crs:RedSaturation="+18"
76
+ crs:GreenHue="0"
77
+ crs:GreenSaturation="0"
78
+ crs:BlueHue="-7"
79
+ crs:BlueSaturation="-7"
80
+ crs:FillLight="31"
81
+ crs:Vibrance="0"
82
+ crs:HighlightRecovery="30"
83
+ crs:Clarity="+100"
84
+ crs:Defringe="0"
85
+ crs:HueAdjustmentRed="0"
86
+ crs:HueAdjustmentOrange="+33"
87
+ crs:HueAdjustmentYellow="0"
88
+ crs:HueAdjustmentGreen="0"
89
+ crs:HueAdjustmentAqua="0"
90
+ crs:HueAdjustmentBlue="0"
91
+ crs:HueAdjustmentPurple="0"
92
+ crs:HueAdjustmentMagenta="0"
93
+ crs:SaturationAdjustmentRed="-2"
94
+ crs:SaturationAdjustmentOrange="-30"
95
+ crs:SaturationAdjustmentYellow="0"
96
+ crs:SaturationAdjustmentGreen="0"
97
+ crs:SaturationAdjustmentAqua="0"
98
+ crs:SaturationAdjustmentBlue="0"
99
+ crs:SaturationAdjustmentPurple="0"
100
+ crs:SaturationAdjustmentMagenta="0"
101
+ crs:LuminanceAdjustmentRed="0"
102
+ crs:LuminanceAdjustmentOrange="0"
103
+ crs:LuminanceAdjustmentYellow="0"
104
+ crs:LuminanceAdjustmentGreen="0"
105
+ crs:LuminanceAdjustmentAqua="0"
106
+ crs:LuminanceAdjustmentBlue="0"
107
+ crs:LuminanceAdjustmentPurple="0"
108
+ crs:LuminanceAdjustmentMagenta="0"
109
+ crs:SplitToningShadowHue="0"
110
+ crs:SplitToningShadowSaturation="0"
111
+ crs:SplitToningHighlightHue="0"
112
+ crs:SplitToningHighlightSaturation="0"
113
+ crs:SplitToningBalance="+64"
114
+ crs:ParametricShadows="+60"
115
+ crs:ParametricDarks="-11"
116
+ crs:ParametricLights="+15"
117
+ crs:ParametricHighlights="+70"
118
+ crs:ParametricShadowSplit="25"
119
+ crs:ParametricMidtoneSplit="50"
120
+ crs:ParametricHighlightSplit="80"
121
+ crs:SharpenRadius="+1.0"
122
+ crs:SharpenDetail="25"
123
+ crs:SharpenEdgeMasking="0"
124
+ crs:PostCropVignetteAmount="0"
125
+ crs:GrainAmount="0"
126
+ crs:ColorNoiseReductionDetail="50"
127
+ crs:LensProfileEnable="0"
128
+ crs:LensManualDistortionAmount="0"
129
+ crs:PerspectiveVertical="0"
130
+ crs:PerspectiveHorizontal="0"
131
+ crs:PerspectiveRotate="0.0"
132
+ crs:PerspectiveScale="100"
133
+ crs:ConvertToGrayscale="False"
134
+ crs:ToneCurveName="Medium Contrast"
135
+ crs:CameraProfile="Adobe Standard"
136
+ crs:CameraProfileDigest="631F0C9CC003981496182C3DD10EF165"
137
+ crs:LensProfileSetup="LensDefaults"
138
+ crs:HasSettings="True"
139
+ crs:CropTop="0.024828"
140
+ crs:CropLeft="0.012414"
141
+ crs:CropBottom="1"
142
+ crs:CropRight="0.987586"
143
+ crs:CropAngle="0"
144
+ crs:CropConstrainToWarp="0"
145
+ crs:CropWidth="800"
146
+ crs:CropHeight="533"
147
+ crs:CropUnit="0"
148
+ crs:HasCrop="True"
149
+ crs:AlreadyApplied="True">
150
+ <exif:ISOSpeedRatings>
151
+ <rdf:Seq>
152
+ <rdf:li>100</rdf:li>
153
+ </rdf:Seq>
154
+ </exif:ISOSpeedRatings>
155
+ <dc:creator>
156
+ <rdf:Seq>
157
+ <rdf:li>John Doe</rdf:li>
158
+ </rdf:Seq>
159
+ </dc:creator>
160
+ <dc:title>
161
+ <rdf:Alt>
162
+ <rdf:li xml:lang="x-default">Tytuł zdjęcia</rdf:li>
163
+ </rdf:Alt>
164
+ </dc:title>
165
+ <dc:rights>
166
+ <rdf:Alt>
167
+ <rdf:li xml:lang="x-default">Autor</rdf:li>
168
+ </rdf:Alt>
169
+ </dc:rights>
170
+ <dc:subject>
171
+ <rdf:Bag>
172
+ <rdf:li>Słowa kluczowe i numery startowe.</rdf:li>
173
+ </rdf:Bag>
174
+ </dc:subject>
175
+ <dc:description>
176
+ <rdf:Alt>
177
+ <rdf:li xml:lang="x-default">Opis zdjęcia</rdf:li>
178
+ </rdf:Alt>
179
+ </dc:description>
180
+ <photoshop:SupplementalCategories>
181
+ <rdf:Bag>
182
+ <rdf:li>Nazwa imprezy</rdf:li>
183
+ </rdf:Bag>
184
+ </photoshop:SupplementalCategories>
185
+ <crs:ToneCurve>
186
+ <rdf:Seq>
187
+ <rdf:li>0, 0</rdf:li>
188
+ <rdf:li>32, 22</rdf:li>
189
+ <rdf:li>64, 56</rdf:li>
190
+ <rdf:li>128, 128</rdf:li>
191
+ <rdf:li>192, 196</rdf:li>
192
+ <rdf:li>255, 255</rdf:li>
193
+ </rdf:Seq>
194
+ </crs:ToneCurve>
195
+ </rdf:Description>
196
+ </rdf:RDF>
197
+ </x:xmpmeta>
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+ <?xpacket end="w"?>
@@ -0,0 +1,57 @@
1
+ <?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
2
+ <?adobe-xap-filters esc="CR"?>
3
+ <x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9-9, framework 1.6'>
4
+ <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
5
+ <rdf:Description rdf:about='' xmlns:pdf='http://ns.adobe.com/pdf/1.3/'></rdf:Description>
6
+ <rdf:Description rdf:about='' xmlns:photoshop='http://ns.adobe.com/photoshop/1.0/' photoshop:Headline='DeniseTestImage' photoshop:Credit='Remco'></rdf:Description>
7
+ <rdf:Description rdf:about='' xmlns:tiff='http://ns.adobe.com/tiff/1.0/'></rdf:Description>
8
+ <rdf:Description rdf:about='' xmlns:xap='http://ns.adobe.com/xap/1.0/'></rdf:Description>
9
+ <rdf:Description rdf:about='' xmlns:xapRights='http://ns.adobe.com/xap/1.0/rights/'></rdf:Description>
10
+ <rdf:Description rdf:about='' xmlns:dc='http://purl.org/dc/elements/1.1/'>
11
+ <dc:subject><rdf:Bag><rdf:li>SAMPLEkeyworddataFromIview</rdf:li></rdf:Bag></dc:subject>
12
+ <dc:creator><rdf:Seq><rdf:li>BenjaminStorrier</rdf:li></rdf:Seq></dc:creator>
13
+ <dc:rights><rdf:Alt> <rdf:li>PublicDomain</rdf:li></rdf:Alt></dc:rights>
14
+ </rdf:Description>
15
+ </rdf:RDF>
16
+ </x:xmpmeta>
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+ <?xpacket end='r'?>
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'xmp/silencer'
3
+
4
+ XMP::Silencer.silently {
5
+ require 'bundler/setup'
6
+ Bundler.require(:development)
7
+ }
8
+
9
+ # load whole montgomery after bundler loads required gems
10
+ require 'xmp'
11
+
12
+ require 'pp'
data/spec/xmp_spec.rb ADDED
@@ -0,0 +1,61 @@
1
+ # encoding: UTF-8
2
+ require './spec/spec_helper.rb'
3
+
4
+ describe XMP do
5
+ describe "with xmp.xml" do
6
+ before { @xmp = XMP.new(File.read('spec/fixtures/xmp.xml')) }
7
+
8
+ it "should return all namespace names" do
9
+ @xmp.namespaces.should =~ %w{rdf x tiff exif xap aux Iptc4xmpCore photoshop crs dc}
10
+ end
11
+
12
+ it "should return standalone attribute" do
13
+ @xmp.dc.title.should eq(['Tytuł zdjęcia'])
14
+ @xmp.dc.subject.should eq(['Słowa kluczowe i numery startowe.'])
15
+ @xmp.photoshop.SupplementalCategories.should eq(['Nazwa imprezy'])
16
+ end
17
+
18
+ it "should return embedded attribute" do
19
+ @xmp.Iptc4xmpCore.Location.should eq('Miejsce')
20
+ @xmp.photoshop.Category.should eq('Kategoria')
21
+ end
22
+
23
+ it "should raise NoMethodError on unknown attribute" do
24
+ lambda { @xmp.photoshop.UnknownAttribute }.should raise_error(NoMethodError)
25
+ end
26
+
27
+ describe "namespace 'tiff'" do
28
+ before { @namespace = @xmp.tiff }
29
+
30
+ it "should return all attribute names" do
31
+ @namespace.attributes.should =~ %w{Make Model ImageWidth ImageLength XResolution YResolution ResolutionUnit}
32
+ end
33
+ end
34
+
35
+ describe "namespace 'photoshop'" do
36
+ before { @namespace = @xmp.photoshop }
37
+
38
+ it "should return all attribute names" do
39
+ @namespace.attributes.should =~ %w{LegacyIPTCDigest Category SupplementalCategories}
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "with xmp2.xml" do
45
+ before { @xmp = XMP.new(File.read('spec/fixtures/xmp2.xml')) }
46
+
47
+ it "should return all namespace names" do
48
+ @xmp.namespaces.should =~ %w{dc iX pdf photoshop rdf tiff x xap xapRights}
49
+ end
50
+
51
+ it "should return standalone attribute" do
52
+ @xmp.dc.creator.should eq(['BenjaminStorrier'])
53
+ @xmp.dc.subject.should eq(['SAMPLEkeyworddataFromIview'])
54
+ end
55
+
56
+ it "should return embedded attribute" do
57
+ @xmp.photoshop.Headline.should eq('DeniseTestImage')
58
+ @xmp.photoshop.Credit.should eq('Remco')
59
+ end
60
+ end
61
+ end
data/xmp.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "xmp/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "xmp"
7
+ s.version = XMP::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Wojciech Piekutowski"]
10
+ s.email = ["wojciech.piekutowski@amberbit.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Extensible Metadata Platform (XMP) parser}
13
+ s.description = %q{Extensible Metadata Platform (XMP) parser}
14
+
15
+ s.rubyforge_project = "xmp"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.extra_rdoc_files = %w(README.rdoc)
23
+
24
+ s.add_dependency 'nokogiri', '~>1.4.0'
25
+
26
+ s.add_development_dependency 'exifr', '>=1.0.4'
27
+ s.add_development_dependency 'rspec', '~>2.0'
28
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xmp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Wojciech Piekutowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-02-26 00:00:00.000000000 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: &8132500 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *8132500
26
+ - !ruby/object:Gem::Dependency
27
+ name: exifr
28
+ requirement: &8132000 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.4
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *8132000
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ requirement: &8131540 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: '2.0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *8131540
48
+ description: Extensible Metadata Platform (XMP) parser
49
+ email:
50
+ - wojciech.piekutowski@amberbit.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files:
54
+ - README.rdoc
55
+ files:
56
+ - .gitignore
57
+ - .rspec
58
+ - .rvmrc
59
+ - Gemfile
60
+ - README.rdoc
61
+ - Rakefile
62
+ - lib/xmp.rb
63
+ - lib/xmp/namespace.rb
64
+ - lib/xmp/silencer.rb
65
+ - lib/xmp/version.rb
66
+ - spec/exifr_jpeg_spec.rb
67
+ - spec/fixtures/multiple-app1.jpg
68
+ - spec/fixtures/xmp.xml
69
+ - spec/fixtures/xmp2.xml
70
+ - spec/spec_helper.rb
71
+ - spec/xmp_spec.rb
72
+ - xmp.gemspec
73
+ has_rdoc: true
74
+ homepage: ''
75
+ licenses: []
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project: xmp
94
+ rubygems_version: 1.5.2
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Extensible Metadata Platform (XMP) parser
98
+ test_files: []