active_musicbrainz 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7323c327554fad6ca29c48a436a51bda55400783
4
+ data.tar.gz: 5a9515e43385659163c972b01d05c19a60c9654c
5
+ SHA512:
6
+ metadata.gz: 27907fad9a780d541a4147babe2ba90b1c63953ebc5eedd4d6062635a9a266ae51f66c1973aa83ec161ff1633936d882815a1e023c0d404fcb4b488f833fdebf
7
+ data.tar.gz: f45004a93a5582db123168de9e09a43527a5f428fecc094927e77f147acadd81cf0258b915451c938490b69f0edd484b2553a21c5a22a744b80fbe48df369623
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.swp
2
+ .DS_Store
3
+ pkg
4
+ Gemfile.lock
5
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Andrea Franz (http://gravityblast.com)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # ActiveMusicbrainz
2
+
3
+ ActiveRecord models for the [MusicBrainz](http://musicbrainz.org/) [database](http://musicbrainz.org/doc/MusicBrainz_Database).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_musicbrainz'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_musicbrainz
18
+
19
+ ## Usage
20
+
21
+ Require ActiveMusicbrainz and initialize the database **(if you are inside a rails app, you can skip the following lines)**:
22
+
23
+ require 'active_musicbrainz'
24
+ ActiveRecord::Base.establish_connection(YAML.load_file('path/to/config.yml'))
25
+
26
+ Some models are hardcoded, others are dynamically generated based on existing tables. You can initialize all those models with the following line:
27
+
28
+ ActiveMusicbrainz.init
29
+
30
+ The *init* method should be called after establishing a database connection since the library needs to read all the database tables.
31
+ If you are inside a rails project you could put the code above in **config/initializers/active_musicbrainz.rb**.
32
+
33
+ Now under the ActiveMusicbrainz::Model module, you have one model for each MusicBrainz table.
34
+ Here some examples:
35
+
36
+ artist = ActiveMusicbrainz::Model::Artist.where(gid: '9a709693-b4f8-4da9-8cc1-038c911a61be').first
37
+ => #<ActiveMusicbrainz::Model::Artist id: 24146, gid: "9a709693-b4f8-4da9-8cc1-038c911a61be", name: 143497, sort_name: 143497, begin_date_year: 1976, begin_date_month: 3, begin_date_day: 30, end_date_year: nil, end_date_month: nil, end_date_day: nil, type: 1, area: 221, gender: 1, comment: "UK electro artist Simon Green", edits_pending: 0, last_updated: "2013-05-13 11:00:09", ended: false, begin_area: nil, end_area: nil>
38
+
39
+ artist.name
40
+ => "Bonobo"
41
+
42
+ artist.release_groups.first.type
43
+ => #<ActiveMusicbrainz::Model::ReleaseGroupPrimaryType id: 1, name: "Album">
44
+
45
+ artist.release_groups.each{|r| puts r.name }
46
+ Black Sands
47
+ Dial 'M' for Monkey
48
+ Scuba EP
49
+ Flutter
50
+ Pick Up
51
+ Terrapin
52
+ Eyesdown
53
+ ...
54
+
55
+ artist.release_groups.first.releases.first.mediums
56
+ => [#<ActiveMusicbrainz::Model::Medium id: 654199, release: 654199, position: 1, format: 1, name: nil, edits_pending: 0, last_updated: "2012-01-15 13:46:18", track_count: 12>]
57
+
58
+ artist.release_groups.first.releases.first.mediums.first.tracks.each{|t| puts t.name}
59
+ Prelude
60
+ Kiara
61
+ Kong
62
+ Eyesdown
63
+ ...
64
+
65
+ artist.release_groups.first.releases.first.mediums.first.format
66
+ => #<ActiveMusicbrainz::Model::MediumFormat id: 1, name: "CD", parent: nil, child_order: 0, year: 1982, has_discids: true>
67
+
68
+ ## Contributing
69
+
70
+ 1. Fork it
71
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
72
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
73
+ 4. Push to the branch (`git push origin my-new-feature`)
74
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_musicbrainz/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_musicbrainz"
8
+ spec.version = ActiveMusicbrainz::VERSION
9
+ spec.authors = ["Andrea Franz"]
10
+ spec.email = ["andrea@gravityblast.com"]
11
+ spec.description = %q{ActiveRecord models for the MusicBrainz database.}
12
+ spec.summary = %q{ActiveRecord models the MusicBrainz database}
13
+ spec.homepage = "https://github.com/pilu/active_musicbrainz"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency 'activerecord'
25
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_record'
2
+ require 'active_musicbrainz/version'
3
+ require 'active_musicbrainz/config'
4
+ require 'active_musicbrainz/models/base'
5
+ require 'active_musicbrainz/models/factory'
6
+ require 'active_musicbrainz/models/model'
7
+
8
+ module ActiveMusicbrainz
9
+ def self.init
10
+ Model.build_models
11
+ end
12
+ end
13
+
@@ -0,0 +1,19 @@
1
+ require 'yaml'
2
+
3
+ module ActiveMusicbrainz
4
+ class Config
5
+ class << self
6
+ def load config_path
7
+ self.config = YAML.load_file config_path
8
+ end
9
+
10
+ def config= config
11
+ @config = config
12
+ end
13
+
14
+ def database
15
+ @config[:database]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module ActiveMusicbrainz
2
+ module Model
3
+ module Base
4
+ def self.included base
5
+ base.send :extend, ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def has_name association_name
10
+ define_method :name do
11
+ send(association_name).name
12
+ end
13
+ end
14
+
15
+ def has_artist_credits
16
+ belongs_to :artist_credit, foreign_key: :artist_credit
17
+ has_many :artist_credit_names, through: :artist_credit
18
+ has_many :artists, through: :artist_credit_names
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module ActiveMusicbrainz
2
+ module Model
3
+ class Factory
4
+ def self.define &block
5
+ factory = new
6
+ factory.instance_eval &block if block_given?
7
+ factory
8
+ end
9
+
10
+ def model table_name, &block
11
+ klass = model_class table_name
12
+ klass.class_eval &block if block_given?
13
+ klass
14
+ end
15
+
16
+ private
17
+
18
+ def camelize_table_name(term, uppercase_first_letter = true)
19
+ string = term.to_s
20
+ string = string.sub(/^[a-z\d]*/) { $&.capitalize }
21
+ string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
22
+ end
23
+
24
+ def model_class table_name
25
+ Model.const_get camelize_table_name(table_name)
26
+ rescue NameError
27
+ build_model_class table_name
28
+ end
29
+
30
+ def build_model_class table_name
31
+ klass = Class.new ActiveRecord::Base do
32
+ self.table_name = table_name
33
+ self.inheritance_column = :_sti_type
34
+ include Base
35
+ end
36
+ Model.const_set camelize_table_name(table_name), klass
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,111 @@
1
+ module ActiveMusicbrainz
2
+ module Model
3
+ def self.build_models
4
+ Factory.define do
5
+ ActiveRecord::Base.connection.tables.each do |table_name|
6
+ model table_name
7
+ end
8
+ end
9
+ true
10
+ end
11
+
12
+ Factory.define do
13
+ model :artist do
14
+ belongs_to :artist_name, foreign_key: :name
15
+ has_many :artist_credit_name, foreign_key: :artist
16
+ has_many :artist_credits, through: :artist_credit_name
17
+ has_many :release_groups, through: :artist_credits
18
+ has_many :releases, through: :release_groups
19
+ has_many :recordings, through: :artist_credits
20
+ has_many :tracks, through: :artist_credits
21
+ has_many :aliases, foreign_key: :artist
22
+ has_name :artist_name
23
+ end
24
+
25
+ model :artist_credit_name do
26
+ belongs_to :artist_credit, foreign_key: :artist_credit
27
+ belongs_to :artist_name, foreign_key: :name
28
+ belongs_to :artist, foreign_key: :artist
29
+ has_name :artist_name
30
+ end
31
+
32
+ model :artist_credit do
33
+ belongs_to :artist_name, foreign_key: :name
34
+ has_many :artist_credit_names, foreign_key: :artist_credit
35
+ has_many :artists, through: :artist_credit_names
36
+ has_many :recordings, foreign_key: :artist_credit
37
+ has_many :tracks, foreign_key: :artist_credit
38
+ has_many :releases, foreign_key: :artist_credit
39
+ has_many :release_groups, foreign_key: :artist_credit
40
+ has_name :artist_name
41
+ end
42
+
43
+ model :artist_alias do
44
+ belongs_to :artist_name, foreign_key: :name
45
+ belongs_to :artist, foreign_key: :artist
46
+ has_name :artist_name
47
+ end
48
+
49
+ model :track do
50
+ belongs_to :track_name, foreign_key: :name
51
+ belongs_to :recording, foreign_key: :recording
52
+ belongs_to :medium, foreign_key: :medium
53
+ has_name :track_name
54
+ has_artist_credits
55
+ end
56
+
57
+ model :release_group_secondary_type do
58
+ has_many :release_group_secondary_type_joins, foreign_key: :secondary_type
59
+ has_many :release_groups, through: :release_group_secondary_type_joins
60
+ end
61
+
62
+ model :release_group_secondary_type_join do
63
+ belongs_to :release_group, foreign_key: :release_group
64
+ belongs_to :type, class_name: 'ReleaseGroupSecondaryType', foreign_key: :secondary_type
65
+ end
66
+
67
+ model :release_group do
68
+ belongs_to :release_name, foreign_key: :name
69
+ has_many :releases, foreign_key: :release_group
70
+ has_name :release_name
71
+ belongs_to :type, class_name: 'ReleaseGroupPrimaryType', foreign_key: :type
72
+ has_many :release_group_secondary_type_joins, foreign_key: :release_group
73
+ has_many :secondary_types, through: :release_group_secondary_type_joins, source: :type
74
+
75
+ has_artist_credits
76
+ end
77
+
78
+ model :release do
79
+ belongs_to :release_name, foreign_key: :name
80
+ belongs_to :release_group, foreign_key: :release_group
81
+ has_many :mediums, foreign_key: :release, order: :position
82
+ has_many :recordings, through: :mediums
83
+ has_name :release_name
84
+ has_many :tracks, through: :mediums
85
+ belongs_to :status, class_name: 'ReleaseStatus', foreign_key: :status
86
+ belongs_to :packaging, class_name: 'ReleasePackaging', foreign_key: :packaging
87
+
88
+ has_artist_credits
89
+ end
90
+
91
+ model :medium do
92
+ belongs_to :release, foreign_key: :release
93
+ has_many :tracks, foreign_key: :medium
94
+ has_many :recordings, through: :tracks
95
+ belongs_to :format, class_name: 'MediumFormat', foreign_key: :format
96
+ belongs_to :medium_format, foreign_key: :format
97
+ end
98
+
99
+ model :recording do
100
+ belongs_to :track_name, foreign_key: :name
101
+ has_many :tracks, foreign_key: :recording
102
+ has_many :release_groups, through: :tracks
103
+ has_many :releases, through: :mediums
104
+ has_many :release_groups, through: :releases
105
+ has_many :mediums, through: :tracks
106
+ has_name :track_name
107
+ has_artist_credits
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveMusicbrainz
2
+ VERSION = "0.1.0"
3
+ end
data/test/config.yml ADDED
@@ -0,0 +1,5 @@
1
+ test:
2
+ adapter: 'postgresql'
3
+ database: 'musicbrainz'
4
+ username: 'musicbrainz'
5
+
@@ -0,0 +1,42 @@
1
+ require_relative '../test_helper'
2
+
3
+ module ActiveMusicbrainz
4
+ describe Model do
5
+
6
+ def model table_name, &block
7
+ Model::Factory.define.model table_name, &block
8
+ end
9
+
10
+ after do
11
+ Model.send :remove_const, 'Artist'
12
+ end
13
+
14
+ it 'creates model class' do
15
+ klass = model 'artist'
16
+ klass.superclass.must_equal(ActiveRecord::Base)
17
+ end
18
+
19
+ it 'sends &block to the created class' do
20
+ klass = model 'artist' do
21
+ def hello; end
22
+ end
23
+ klass.instance_methods.must_include :hello
24
+ end
25
+
26
+ it 'creates the new model inside the Model module' do
27
+ klass = model 'artist'
28
+ klass.name.must_equal 'ActiveMusicbrainz::Model::Artist'
29
+ end
30
+
31
+ it 'reopens class' do
32
+ model 'artist' do
33
+ def method_1; end
34
+ end
35
+ model 'artist' do
36
+ def method_2; end
37
+ end
38
+ Model::Artist.instance_methods.must_include :method_1
39
+ Model::Artist.instance_methods.must_include :method_2
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'minitest/autorun'
4
+ require 'rubygems'
5
+ require 'active_musicbrainz'
6
+ require 'yaml'
7
+
8
+ config = YAML.load_file(File.join(File.dirname(__FILE__), 'config.yml'))
9
+
10
+
11
+ ActiveRecord::Base.establish_connection config['test']
12
+ ActiveMusicbrainz.init
13
+
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_musicbrainz
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrea Franz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: ActiveRecord models for the MusicBrainz database.
56
+ email:
57
+ - andrea@gravityblast.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - active_musicbrainz.gemspec
68
+ - lib/active_musicbrainz.rb
69
+ - lib/active_musicbrainz/config.rb
70
+ - lib/active_musicbrainz/models/base.rb
71
+ - lib/active_musicbrainz/models/factory.rb
72
+ - lib/active_musicbrainz/models/model.rb
73
+ - lib/active_musicbrainz/version.rb
74
+ - test/config.yml
75
+ - test/models/model_test.rb
76
+ - test/test_helper.rb
77
+ homepage: https://github.com/pilu/active_musicbrainz
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: ActiveRecord models the MusicBrainz database
101
+ test_files:
102
+ - test/config.yml
103
+ - test/models/model_test.rb
104
+ - test/test_helper.rb