rbrainz 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/TODO +12 -7
- data/lib/rbrainz/model/artist.rb +4 -4
- data/lib/rbrainz/model/entity.rb +50 -3
- data/lib/rbrainz/model/label.rb +4 -3
- data/lib/rbrainz/model/relation.rb +84 -0
- data/lib/rbrainz/model/release.rb +4 -3
- data/lib/rbrainz/model/track.rb +5 -3
- data/lib/rbrainz/webservice.rb +31 -1
- data/lib/rbrainz/webservice/mbxml.rb +130 -18
- data/lib/rbrainz/webservice/query.rb +13 -9
- data/lib/rbrainz/webservice/webservice.rb +39 -9
- data/test/lib/test_entity.rb +67 -5
- data/test/lib/testing_helper.rb +1 -1
- data/test/test_alias.rb +1 -1
- data/test/test_artist.rb +1 -15
- data/test/test_artist_filter.rb +1 -1
- data/test/test_artist_includes.rb +1 -1
- data/test/test_disc.rb +1 -1
- data/test/test_incomplete_date.rb +1 -1
- data/test/test_label.rb +1 -8
- data/test/test_label_filter.rb +1 -1
- data/test/test_label_includes.rb +1 -1
- data/test/test_mbid.rb +1 -1
- data/test/test_mbxml.rb +39 -4
- data/test/test_query.rb +1 -1
- data/test/test_relation.rb +116 -0
- data/test/test_release.rb +1 -22
- data/test/test_release_event.rb +1 -1
- data/test/test_release_filter.rb +1 -1
- data/test/test_release_includes.rb +1 -1
- data/test/test_track.rb +1 -15
- data/test/test_track_filter.rb +1 -1
- data/test/test_track_includes.rb +1 -1
- data/test/test_webservice.rb +42 -3
- metadata +4 -2
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: Rakefile
|
1
|
+
# $Id: Rakefile 34 2007-05-29 15:08:03Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -13,7 +13,7 @@ require 'rake/rdoctask'
|
|
13
13
|
# Packaging tasks: -------------------------------------------------------
|
14
14
|
|
15
15
|
PKG_NAME = 'rbrainz'
|
16
|
-
PKG_VERSION = '0.1.
|
16
|
+
PKG_VERSION = '0.1.1'
|
17
17
|
PKG_FILES = FileList[
|
18
18
|
"Rakefile", "LICENSE", "README", "TODO",
|
19
19
|
"doc/README.rdoc",
|
data/TODO
CHANGED
@@ -1,24 +1,29 @@
|
|
1
1
|
=TODO
|
2
2
|
|
3
3
|
==Short term tasks
|
4
|
-
*
|
5
|
-
* Query collections (0.1.2)
|
4
|
+
* Query collections (0.2.0)
|
6
5
|
* Support for the score parameter in search result. Could be implemented
|
7
6
|
a little bit like in PythonMusicBrainz2, but more flexible. Maybe a result
|
8
|
-
object over which one can iterate to retrieve all results
|
9
|
-
corresponding score. (0.
|
7
|
+
object over which one can iterate to retrieve all results with the
|
8
|
+
corresponding score. (0.2.0)
|
10
9
|
result.each {|entity, score|
|
11
10
|
...
|
12
11
|
}
|
13
12
|
* Support for the offset parameter for queries on collections
|
14
13
|
to retrieve results below the 100 results limit. Could be easily integrated
|
15
|
-
into the result object (see previous point). (0.
|
14
|
+
into the result object (see previous point). (0.2.0)
|
16
15
|
* Make it easier to create MBID objects or allow usage of ID strings
|
17
|
-
where it makes life easier.
|
16
|
+
where it makes life easier (>= 0.2.1).
|
17
|
+
* Add usefull constructor parameters to the models (>= 0.2.1).
|
18
|
+
* Improve API documentation.
|
18
19
|
|
19
20
|
==Longer term tasks
|
20
21
|
* Calculation of disc IDs (0.3.0)
|
21
22
|
* User authentication (0.4.0)
|
22
23
|
* Querying of user information (0.4.0)
|
23
24
|
* PUID submission
|
24
|
-
* Full text search (lucene search queries).
|
25
|
+
* Full text search (lucene search queries).
|
26
|
+
* Implement a command line tool (+mbquery+) for querying the MusicBrainz
|
27
|
+
database which will serve as a usefull example for RBrainz.
|
28
|
+
* Support for common extensions (this could be implemented by adding
|
29
|
+
additional extension libraries which extend the existing classes).
|
data/lib/rbrainz/model/artist.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: artist.rb
|
1
|
+
# $Id: artist.rb 30 2007-05-29 02:12:33Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -18,12 +18,12 @@ module MusicBrainz
|
|
18
18
|
TYPE_PERSON = NS_MMD_1 + 'Person'
|
19
19
|
TYPE_GROUP = NS_MMD_1 + 'Group'
|
20
20
|
|
21
|
-
attr_accessor :name, :sort_name, :disambiguation,
|
22
|
-
:type, :aliases, :releases
|
21
|
+
attr_accessor :name, :sort_name, :disambiguation, :type
|
23
22
|
|
24
|
-
attr_reader :begin_date, :end_date
|
23
|
+
attr_reader :begin_date, :end_date, :aliases, :releases
|
25
24
|
|
26
25
|
def initialize
|
26
|
+
super
|
27
27
|
@aliases = Array.new
|
28
28
|
@releases = Array.new
|
29
29
|
end
|
data/lib/rbrainz/model/entity.rb
CHANGED
@@ -1,20 +1,29 @@
|
|
1
|
-
# $Id: entity.rb
|
1
|
+
# $Id: entity.rb 30 2007-05-29 02:12:33Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
5
5
|
|
6
6
|
require 'rbrainz/model/mbid'
|
7
|
+
require 'rbrainz/model/relation'
|
7
8
|
|
8
9
|
module MusicBrainz
|
9
10
|
module Model
|
10
11
|
|
11
12
|
# Superclass for all entities.
|
12
|
-
#
|
13
|
-
# TODO: implement relations.
|
14
13
|
class Entity
|
15
14
|
|
16
15
|
attr_reader :id
|
17
16
|
|
17
|
+
def initialize
|
18
|
+
@relations = {
|
19
|
+
Relation::TO_ARTIST => Array.new,
|
20
|
+
Relation::TO_RELEASE => Array.new,
|
21
|
+
Relation::TO_TRACK => Array.new,
|
22
|
+
Relation::TO_LABEL => Array.new,
|
23
|
+
Relation::TO_URL => Array.new,
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
18
27
|
# Set the MBID.
|
19
28
|
#
|
20
29
|
# +mbid+ should be an instance of +MBID+ or a string
|
@@ -66,6 +75,44 @@ module MusicBrainz
|
|
66
75
|
self.class.entity_type
|
67
76
|
end
|
68
77
|
|
78
|
+
# Add a relation to this entity.
|
79
|
+
def add_relation(relation)
|
80
|
+
@relations[relation.target_type] << relation
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the relations of this entity.
|
84
|
+
def get_relations(options = {:target_type => nil, :relation_type => nil,
|
85
|
+
:required_attributes => [], :direction => nil})
|
86
|
+
# Select all results depending on the requested target type
|
87
|
+
if options[:target_type]
|
88
|
+
result = @relations[options[:target_type]]
|
89
|
+
else
|
90
|
+
result = []
|
91
|
+
@relations.each_value {|array| result += array}
|
92
|
+
end
|
93
|
+
|
94
|
+
# Remove relations which don't meet all the criteria.
|
95
|
+
result.delete_if {|relation|
|
96
|
+
(options[:relation_type] and relation.type != options[:relation_type]) \
|
97
|
+
or (options[:required_attributes] and
|
98
|
+
(relation.attributes & options[:required_attributes]).sort \
|
99
|
+
!= options[:required_attributes].sort) \
|
100
|
+
or (options[:direction] and relation.direction != options[:direction])
|
101
|
+
}
|
102
|
+
|
103
|
+
return result
|
104
|
+
end
|
105
|
+
|
106
|
+
# Return all relation target types for which this entity
|
107
|
+
# has relations defined.
|
108
|
+
def relation_target_types
|
109
|
+
result = []
|
110
|
+
@relations.each_pair {|type, relations|
|
111
|
+
result << type unless relations.empty?
|
112
|
+
}
|
113
|
+
return result
|
114
|
+
end
|
115
|
+
|
69
116
|
end
|
70
117
|
|
71
118
|
end
|
data/lib/rbrainz/model/label.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: label.rb
|
1
|
+
# $Id: label.rb 30 2007-05-29 02:12:33Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -21,11 +21,12 @@ module MusicBrainz
|
|
21
21
|
TYPE_REISSUE_PRODUCTION = NS_MMD_1 + 'ReissueProduction'
|
22
22
|
|
23
23
|
attr_accessor :name, :sort_name, :disambiguation,
|
24
|
-
:code, :country, :type
|
24
|
+
:code, :country, :type
|
25
25
|
|
26
|
-
attr_reader :founding_date, :dissolving_date
|
26
|
+
attr_reader :founding_date, :dissolving_date, :releases
|
27
27
|
|
28
28
|
def initialize
|
29
|
+
super
|
29
30
|
@releases = Array.new
|
30
31
|
end
|
31
32
|
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# $Id: relation.rb 33 2007-05-29 14:48:47Z phw $
|
2
|
+
# Copyright (c) 2007, Philipp Wolfer
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE for permissions.
|
5
|
+
|
6
|
+
module MusicBrainz
|
7
|
+
module Model
|
8
|
+
|
9
|
+
# Relationship class.
|
10
|
+
class Relation
|
11
|
+
|
12
|
+
DIR_BACKWARD = :backward
|
13
|
+
DIR_FORWARD = :forward
|
14
|
+
DIR_BOTH = :both
|
15
|
+
|
16
|
+
TO_ARTIST = NS_REL_1 + 'Artist'
|
17
|
+
TO_RELEASE = NS_REL_1 + 'Release'
|
18
|
+
TO_TRACK = NS_REL_1 + 'Track'
|
19
|
+
TO_LABEL = NS_REL_1 + 'Label'
|
20
|
+
TO_URL = NS_REL_1 + 'Url'
|
21
|
+
|
22
|
+
attr_accessor :type, :direction
|
23
|
+
|
24
|
+
attr_reader :target, :begin_date, :end_date, :attributes
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@attributes = Array.new
|
28
|
+
@target = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Set the target of this relation.
|
32
|
+
#
|
33
|
+
# The target can either be a object of the type Model::Entity
|
34
|
+
# or a URL.
|
35
|
+
def target=(target)
|
36
|
+
if target.is_a? Entity
|
37
|
+
@target = target
|
38
|
+
else
|
39
|
+
@target = target.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the target type.
|
44
|
+
def target_type
|
45
|
+
if @target.is_a? Model::Entity
|
46
|
+
case @target.entity_type
|
47
|
+
when :artist
|
48
|
+
return TO_ARTIST
|
49
|
+
when :release
|
50
|
+
return TO_RELEASE
|
51
|
+
when :track
|
52
|
+
return TO_TRACK
|
53
|
+
when :label
|
54
|
+
return TO_LABEL
|
55
|
+
end
|
56
|
+
elsif not @target.nil?
|
57
|
+
return TO_URL
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set the begin date of this relation.
|
62
|
+
#
|
63
|
+
# Should be an IncompleteDate object or
|
64
|
+
# a date string, which will get converted
|
65
|
+
# into an IncompleteDate.
|
66
|
+
def begin_date=(date)
|
67
|
+
date = IncompleteDate.new date unless date.is_a? IncompleteDate
|
68
|
+
@begin_date = date
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set the end date of this relation.
|
72
|
+
#
|
73
|
+
# Should be an IncompleteDate object or
|
74
|
+
# a date string, which will get converted
|
75
|
+
# into an IncompleteDate.
|
76
|
+
def end_date=(date)
|
77
|
+
date = IncompleteDate.new date unless date.is_a? IncompleteDate
|
78
|
+
@end_date = date
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: release.rb
|
1
|
+
# $Id: release.rb 30 2007-05-29 02:12:33Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -32,12 +32,13 @@ module MusicBrainz
|
|
32
32
|
TYPE_SOUNDTRACK = NS_MMD_1 + 'Soundtrack'
|
33
33
|
TYPE_SPOKENWORD = NS_MMD_1 + 'Spokenword'
|
34
34
|
|
35
|
-
attr_accessor :title, :
|
35
|
+
attr_accessor :title, :asin, :artist,
|
36
36
|
:text_language, :text_script
|
37
37
|
|
38
|
-
|
38
|
+
attr_reader :tracks, :release_events, :discs, :types
|
39
39
|
|
40
40
|
def initialize
|
41
|
+
super
|
41
42
|
@tracks = Array.new
|
42
43
|
@release_events = Array.new
|
43
44
|
@discs = Array.new
|
data/lib/rbrainz/model/track.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: track.rb
|
1
|
+
# $Id: track.rb 30 2007-05-29 02:12:33Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -13,10 +13,12 @@ module MusicBrainz
|
|
13
13
|
# See http://musicbrainz.org/doc/Track.
|
14
14
|
class Track < Entity
|
15
15
|
|
16
|
-
attr_accessor :title, :duration, :artist
|
17
|
-
|
16
|
+
attr_accessor :title, :duration, :artist
|
17
|
+
|
18
|
+
attr_reader :puids, :releases
|
18
19
|
|
19
20
|
def initialize
|
21
|
+
super
|
20
22
|
@puids = Array.new
|
21
23
|
@releases = Array.new
|
22
24
|
end
|
data/lib/rbrainz/webservice.rb
CHANGED
@@ -1,6 +1,36 @@
|
|
1
|
-
# $Id: webservice.rb
|
1
|
+
# $Id: webservice.rb 36 2007-05-29 18:43:36Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
5
5
|
|
6
|
+
module MusicBrainz
|
7
|
+
module Webservice
|
8
|
+
|
9
|
+
# Connecting to the web service failed.
|
10
|
+
#
|
11
|
+
# This exception is raised if the connection to the server can not be
|
12
|
+
# established due to networking problems (e.g. wrong port number or
|
13
|
+
# server down).
|
14
|
+
class ConnectionError < Exception
|
15
|
+
end
|
16
|
+
|
17
|
+
# An invalid request was made (invalid IDs or parameters).
|
18
|
+
class RequestError < Exception
|
19
|
+
end
|
20
|
+
|
21
|
+
# Client requested a resource which requires authentication via HTTP
|
22
|
+
# Digest Authentication.
|
23
|
+
#
|
24
|
+
# If sent even though user name and password were given: user name and/or
|
25
|
+
# password are incorrect.
|
26
|
+
class AuthenticationError < Exception
|
27
|
+
end
|
28
|
+
|
29
|
+
# The requested resource doesn't exist.
|
30
|
+
class ResourceNotFoundError < Exception
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
6
36
|
require 'rbrainz/webservice/query'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: mbxml.rb
|
1
|
+
# $Id: mbxml.rb 36 2007-05-29 18:43:36Z phw $
|
2
2
|
# Copyright (c) 2007, Philipp Wolfer
|
3
3
|
# All rights reserved.
|
4
4
|
# See LICENSE for permissions.
|
@@ -14,6 +14,7 @@ module MusicBrainz
|
|
14
14
|
# webservice and create the corresponding model classes.
|
15
15
|
# The class understands the MusicBrainz XML Metadata Version 1.0
|
16
16
|
# schema.
|
17
|
+
#
|
17
18
|
# See http://musicbrainz.org/doc/MusicBrainzXMLMetaData for more
|
18
19
|
# information on the MusicBrainz XML Metadata schema.
|
19
20
|
class MBXML
|
@@ -107,7 +108,7 @@ module MusicBrainz
|
|
107
108
|
return nil
|
108
109
|
end
|
109
110
|
|
110
|
-
private
|
111
|
+
private # ----------------------------------------------------------------
|
111
112
|
|
112
113
|
# Iterate over a list of artists.
|
113
114
|
#
|
@@ -119,8 +120,6 @@ module MusicBrainz
|
|
119
120
|
end
|
120
121
|
|
121
122
|
# Create an +Artist+ object from the given artist node.
|
122
|
-
#
|
123
|
-
# TODO: relation list
|
124
123
|
def create_artist(node)
|
125
124
|
if node.attributes['id'] and @artists[node.attributes['id']]
|
126
125
|
artist = @artists[node.attributes['id']]
|
@@ -131,7 +130,9 @@ module MusicBrainz
|
|
131
130
|
|
132
131
|
# Read all defined data fields
|
133
132
|
artist.id = node.attributes['id']
|
134
|
-
|
133
|
+
if node.attributes['type']
|
134
|
+
artist.type = MBXML.add_namespace(node.attributes['type'], Model::NS_MMD_1)
|
135
|
+
end
|
135
136
|
|
136
137
|
artist.name = node.elements['name'].text if node.elements['name']
|
137
138
|
artist.sort_name = node.elements['sort-name'].text if node.elements['sort-name']
|
@@ -161,6 +162,15 @@ module MusicBrainz
|
|
161
162
|
}
|
162
163
|
end
|
163
164
|
|
165
|
+
# Read the relation list
|
166
|
+
if node.elements['relation-list']
|
167
|
+
node.elements.each('relation-list') {|relation_node|
|
168
|
+
read_relation_list(relation_node) {|relation|
|
169
|
+
artist.add_relation relation
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
164
174
|
return artist
|
165
175
|
end
|
166
176
|
|
@@ -176,7 +186,6 @@ module MusicBrainz
|
|
176
186
|
# Create a +Release+ object from the given release node.
|
177
187
|
#
|
178
188
|
# TODO: PUID list
|
179
|
-
# TODO: relation list
|
180
189
|
def create_release(node)
|
181
190
|
if node.attributes['id'] and @releases[node.attributes['id']]
|
182
191
|
release = @releases[node.attributes['id']]
|
@@ -193,7 +202,7 @@ module MusicBrainz
|
|
193
202
|
|
194
203
|
# Read the types
|
195
204
|
node.attributes['type'].split(' ').each {|type|
|
196
|
-
release.types << MBXML.
|
205
|
+
release.types << MBXML.add_namespace(type, Model::NS_MMD_1)
|
197
206
|
} if node.attributes['type']
|
198
207
|
|
199
208
|
# Read the text representation information.
|
@@ -225,6 +234,15 @@ module MusicBrainz
|
|
225
234
|
}
|
226
235
|
end
|
227
236
|
|
237
|
+
# Read the relation list
|
238
|
+
if node.elements['relation-list']
|
239
|
+
node.elements.each('relation-list') {|relation_node|
|
240
|
+
read_relation_list(relation_node) {|relation|
|
241
|
+
release.add_relation relation
|
242
|
+
}
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
228
246
|
return release
|
229
247
|
end
|
230
248
|
|
@@ -238,8 +256,6 @@ module MusicBrainz
|
|
238
256
|
end
|
239
257
|
|
240
258
|
# Create a +Track+ object from the given track node.
|
241
|
-
#
|
242
|
-
# TODO: relation list
|
243
259
|
def create_track(node)
|
244
260
|
if node.attributes['id'] and @tracks[node.attributes['id']]
|
245
261
|
track = @tracks[node.attributes['id']]
|
@@ -269,6 +285,15 @@ module MusicBrainz
|
|
269
285
|
}
|
270
286
|
end
|
271
287
|
|
288
|
+
# Read the relation list
|
289
|
+
if node.elements['relation-list']
|
290
|
+
node.elements.each('relation-list') {|relation_node|
|
291
|
+
read_relation_list(relation_node) {|relation|
|
292
|
+
track.add_relation relation
|
293
|
+
}
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
272
297
|
return track
|
273
298
|
end
|
274
299
|
|
@@ -282,8 +307,6 @@ module MusicBrainz
|
|
282
307
|
end
|
283
308
|
|
284
309
|
# Create a +Label+ object from the given label node.
|
285
|
-
#
|
286
|
-
# TODO: Relations
|
287
310
|
def create_label(node)
|
288
311
|
if node.attributes['id'] and @labels[node.attributes['id']]
|
289
312
|
label = @labels[node.attributes['id']]
|
@@ -294,7 +317,9 @@ module MusicBrainz
|
|
294
317
|
|
295
318
|
# Read all defined data fields
|
296
319
|
label.id = node.attributes['id']
|
297
|
-
|
320
|
+
if node.attributes['type']
|
321
|
+
label.type = MBXML.add_namespace(node.attributes['type'], Model::NS_MMD_1)
|
322
|
+
end
|
298
323
|
|
299
324
|
label.name = node.elements['name'].text if node.elements['name']
|
300
325
|
label.sort_name = node.elements['sort-name'].text if node.elements['sort-name']
|
@@ -318,6 +343,15 @@ module MusicBrainz
|
|
318
343
|
}
|
319
344
|
end
|
320
345
|
|
346
|
+
# Read the relation list
|
347
|
+
if node.elements['relation-list']
|
348
|
+
node.elements.each('relation-list') {|relation_node|
|
349
|
+
read_relation_list(relation_node) {|relation|
|
350
|
+
label.add_relation relation
|
351
|
+
}
|
352
|
+
}
|
353
|
+
end
|
354
|
+
|
321
355
|
return label
|
322
356
|
end
|
323
357
|
|
@@ -385,16 +419,94 @@ module MusicBrainz
|
|
385
419
|
}
|
386
420
|
end
|
387
421
|
|
422
|
+
# Iterate over a list of relations.
|
423
|
+
#
|
424
|
+
# The node must be of the type <em>relation-list</em>.
|
425
|
+
def read_relation_list(node)
|
426
|
+
node.elements.each('relation') {|child|
|
427
|
+
target_type = MBXML.add_namespace(node.attributes['target-type'], Model::NS_REL_1)
|
428
|
+
yield create_relation(child, target_type)
|
429
|
+
}
|
430
|
+
end
|
431
|
+
|
432
|
+
# Create a +Relation+ object from the given relation node.
|
433
|
+
def create_relation(node, target_type)
|
434
|
+
relation = Model::Relation.new
|
435
|
+
|
436
|
+
# Read all defined data fields
|
437
|
+
if node.attributes['direction']
|
438
|
+
relation.direction = node.attributes['direction'].to_sym
|
439
|
+
end
|
440
|
+
|
441
|
+
if node.attributes['type']
|
442
|
+
relation.type = MBXML.add_namespace(node.attributes['type'], Model::NS_REL_1)
|
443
|
+
end
|
444
|
+
|
445
|
+
if node.attributes['begin']
|
446
|
+
relation.begin_date = Model::IncompleteDate.new node.attributes['begin']
|
447
|
+
end
|
448
|
+
|
449
|
+
if node.attributes['end']
|
450
|
+
relation.begin_end = Model::IncompleteDate.new node.attributes['end']
|
451
|
+
end
|
452
|
+
|
453
|
+
if node.attributes['attributes']
|
454
|
+
node.attributes['attributes'].split(' ').each {|attribute|
|
455
|
+
relation.attributes << MBXML.add_namespace(attribute, Model::NS_REL_1)
|
456
|
+
}
|
457
|
+
end
|
458
|
+
|
459
|
+
# Set the target. Either use the target included in the relation
|
460
|
+
# or create a new target according to the target type if no target
|
461
|
+
# is present.
|
462
|
+
case target_type
|
463
|
+
when Model::Relation::TO_ARTIST
|
464
|
+
if node.elements['artist']
|
465
|
+
target = create_artist node.elements['artist']
|
466
|
+
else
|
467
|
+
target = Model::Artist.new
|
468
|
+
target.id = Model::MBID.from_uuid(:artist, node.attributes['target'])
|
469
|
+
end
|
470
|
+
when Model::Relation::TO_RELEASE
|
471
|
+
if node.elements['release']
|
472
|
+
target = create_release node.elements['release']
|
473
|
+
else
|
474
|
+
target = Model::Release.new
|
475
|
+
target.id = Model::MBID.from_uuid(:release, node.attributes['target'])
|
476
|
+
end
|
477
|
+
when Model::Relation::TO_TRACK
|
478
|
+
if node.elements['track']
|
479
|
+
target = create_track node.elements['track']
|
480
|
+
else
|
481
|
+
target = Model::Track.new
|
482
|
+
target.id = Model::MBID.from_uuid(:track, node.attributes['target'])
|
483
|
+
end
|
484
|
+
when Model::Relation::TO_LABEL
|
485
|
+
if node.elements['label']
|
486
|
+
target = create_label node.elements['label']
|
487
|
+
else
|
488
|
+
target = Model::Label.new
|
489
|
+
target.id = Model::MBID.from_uuid(:label, node.attributes['target'])
|
490
|
+
end
|
491
|
+
when Model::Relation::TO_URL
|
492
|
+
target = node.attributes['target']
|
493
|
+
end
|
494
|
+
|
495
|
+
relation.target = target
|
496
|
+
|
497
|
+
return relation
|
498
|
+
end
|
499
|
+
|
388
500
|
# Helper method which will return the given property
|
389
|
-
# extended by the
|
501
|
+
# extended by the namespace. If the property
|
390
502
|
# already includes the namespace it will be returned
|
391
503
|
# unchanged.
|
392
|
-
def self.
|
393
|
-
regex = Regexp.new("/#{
|
394
|
-
unless
|
395
|
-
return
|
504
|
+
def self.add_namespace(property, namespace)
|
505
|
+
regex = Regexp.new("/#{namespace}[a-z-]/i")
|
506
|
+
unless property =~ regex
|
507
|
+
return namespace + property
|
396
508
|
else
|
397
|
-
return
|
509
|
+
return property
|
398
510
|
end
|
399
511
|
end
|
400
512
|
|