voluntary_music_metadata_enrichment 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/CHANGELOG.md +30 -0
- data/LICENSE +22 -0
- data/README.md +33 -0
- data/app/controllers/library/music/year_in_review_releases_controller.rb +1 -1
- data/app/controllers/library/music/year_in_review_tracks_controller.rb +1 -1
- data/app/controllers/library/music/years_in_review_controller.rb +2 -2
- data/app/controllers/library/music_controller.rb +1 -1
- data/app/controllers/music_metadata_enrichment/artists_controller.rb +1 -1
- data/app/controllers/music_metadata_enrichment/releases_controller.rb +1 -1
- data/app/controllers/music_metadata_enrichment/videos_controller.rb +1 -1
- data/app/controllers/voluntary/api/v1/music/artists_controller.rb +34 -0
- data/app/controllers/voluntary/api/v1/music/releases_controller.rb +14 -0
- data/app/controllers/voluntary/api/v1/music/tracks_controller.rb +14 -0
- data/app/controllers/voluntary/api/v1/music/videos_controller.rb +21 -14
- data/app/controllers/voluntary/api/v1/music/year_in_reviews_controller.rb +1 -1
- data/app/models/music_artist.rb +31 -1
- data/app/models/music_metadata_enrichment/group.rb +9 -13
- data/app/models/music_release.rb +17 -1
- data/app/models/music_track.rb +19 -1
- data/app/models/music_video.rb +7 -0
- data/app/models/year_in_review_music.rb +8 -0
- data/config/routes/api.rb +12 -2
- data/lib/voluntary_music_metadata_enrichment/version.rb +1 -1
- metadata +53 -63
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ODlmMjQ3YjYzNjcwYjQzMWNmNzE5ZTE3MmI2NDkxZmE1OTc0ZTM5Ng==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 87672c5c80c85f0d27af153e16b910685a89c003
|
4
|
+
data.tar.gz: 0c36cc13b3dc311815c753ac5259d4816bae3e97
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NGFiMTM1NTc5YWJkZTkzZjUyZmY4MTg0NmMwNDBmNjZhYjQwZjc0OWY2NDAx
|
11
|
-
NzNmNGJlZTI1ZWE5OGZkNjM2YmQ0NTA0MmExZjE2Njc4NzQ4NzM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzgwMmY2NDdlMTEwNjI5MGIxZGVjNmRiNmYwN2FkNDViNDYyYjgwMWVmN2Qz
|
14
|
-
ZDJjMjk2ZGU1OWNkMWNlMTYyN2E1Zjk0MDNkZjVhYzdhNDQwYTkyOGI3YWM1
|
15
|
-
ODMyMGEwMjBmNTczNWYwZGY0NzJiZDQ4ZmFhMmVlOTg2ZjZmMmM=
|
6
|
+
metadata.gz: 639cb58ebf3281b608db03b0d8b995fdd1fb59006bf7065b8e87ca5dfb172e7b96751a6057414d7488c16880d85ced22d08f9ed5b1bdbcb0031ed0b7691789fd
|
7
|
+
data.tar.gz: 08483590bb0275299f84f0817d340e38198c2f5d94776606c97fb5d7bc7a5a5538032fa805cd7dead62287937bb79d2170cae716b3412392d8404d207b04ec2f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
## 0.2.0 (April 12, 2015) ##
|
2
|
+
|
3
|
+
* #121 Rails 4.2.1 upgrade and Travis setup.
|
4
|
+
* #118 API actions for artists, artists/:id, artists/:artist_id/releases, releases/:id, releases/:release_id/tracks, tracks/:id, tracks/:track_id/videos and videos/:id
|
5
|
+
* #116 Import all artists with the same name through MusicMetadataEnrichment::Group#import_artist_connections.
|
6
|
+
|
7
|
+
## 0.1.1 (March 23, 2015) ##
|
8
|
+
|
9
|
+
* Changes home page in gemspec.
|
10
|
+
|
11
|
+
## 0.1.0 (March 23, 2015) ##
|
12
|
+
|
13
|
+
* #113 #114 Implements bulk releases and tracks route for API.
|
14
|
+
* #110 Implements API route for videos liked by user.
|
15
|
+
* #107 #109 Initializes API with first resource year in reviews including top releases and tracks.
|
16
|
+
* #70 Option to sort year in review releases and tracks by round-robin tournament.
|
17
|
+
* #64 Create year in review music releases and tracks for groups by average of lists by members.
|
18
|
+
* refs #65 Implements group membership.
|
19
|
+
* refs #1 Also import soundtrack releases.
|
20
|
+
* #60 Initializes year in review music releases and tracks by user's overall top releases and tracks.
|
21
|
+
* #61 Implements music_artists.is_ambiguous and import all artist with the same name at last.fm library artists import.
|
22
|
+
* #56 Implements option to hide releases and tracks from add multiple tracks / releases to year in review modal window.
|
23
|
+
* Shows top tracks of release on year in review entry for release including "Top Track Positions Sum".
|
24
|
+
* #48 Sets music_releases.is_lp and music release is now also uniq by artist_id, name plus is_lp.
|
25
|
+
* #49 don't import releases of classical artists. Tracks will be added to release "[Bonus Tracks]".
|
26
|
+
* refs #1 Never ending story: metadata importer improvements.
|
27
|
+
|
28
|
+
## 0.0.1 (February 5, 2015) ##
|
29
|
+
|
30
|
+
* Initial version.
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Volontari.at
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# voluntary_music_metadata_enrichment [![Build Status](https://travis-ci.org/volontariat/voluntary_music_metadata_enrichment.svg?branch=master)](https://travis-ci.org/volontariat/voluntary_music_metadata_enrichment) [![Code Climate](https://codeclimate.com/github/volontariat/voluntary_music_metadata_enrichment/badges/gpa.svg)](https://codeclimate.com/github/volontariat/voluntary_music_metadata_enrichment) [![Test Coverage](https://codeclimate.com/github/volontariat/voluntary_music_metadata_enrichment/badges/coverage.svg)](https://codeclimate.com/github/volontariat/voluntary_music_metadata_enrichment) [![Dependency Status](https://gemnasium.com/volontariat/voluntary_music_metadata_enrichment.png)](https://gemnasium.com/volontariat/voluntary_music_metadata_enrichment)
|
2
|
+
|
3
|
+
A plugin for crowdsourcing management system http://Voluntary.Software which adds a music model with discography sync through http://MusicBrainz.org, http://last.fm plus http://Spotify.com to every Ruby on Rails application. But it does not import everything: see [Which data will be imported?](https://github.com/volontariat/voluntary_music_metadata_enrichment/wiki/Which-data-will-be-imported%3F).
|
4
|
+
|
5
|
+
You can create year in reviews for music albums and songs, read more about it in my blog post @ http://last.fm: [Top Songs 2014 created with Open Source Website Volontari.at](http://www.last.fm/user/Volontarian/journal/2015/03/12/6grdr2_top_songs_2014_created_with_open_source_website_volontari.at)
|
6
|
+
|
7
|
+
Furthermore you can manage last.fm groups with artist connections voting, release announcements and music video indexing.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Preconditions: install the voluntary gem in your rails application https://GitHub.com/volontariat/voluntary
|
12
|
+
|
13
|
+
Add this to your Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'voluntary_music_metadata_enrichment'
|
17
|
+
```
|
18
|
+
|
19
|
+
Run this in your console:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
bundle install
|
23
|
+
```
|
24
|
+
|
25
|
+
Run this in your console:
|
26
|
+
|
27
|
+
```bash
|
28
|
+
rake railties:install:migrations
|
29
|
+
```
|
30
|
+
|
31
|
+
## License
|
32
|
+
|
33
|
+
This project uses MIT-LICENSE.
|
@@ -6,7 +6,7 @@ class Library::Music::YearInReviewReleasesController < ::MusicMetadataEnrichment
|
|
6
6
|
authorize_resource class: 'YearInReviewMusicRelease'
|
7
7
|
|
8
8
|
def index
|
9
|
-
@user = User.
|
9
|
+
@user = User.by_slug_or_id(params[:user_id])
|
10
10
|
find_year_in_review
|
11
11
|
get_year_in_review_releases
|
12
12
|
|
@@ -6,7 +6,7 @@ class Library::Music::YearInReviewTracksController < ::MusicMetadataEnrichment::
|
|
6
6
|
authorize_resource class: 'YearInReviewMusicTrack'
|
7
7
|
|
8
8
|
def index
|
9
|
-
@user = User.
|
9
|
+
@user = User.by_slug_or_id(params[:user_id])
|
10
10
|
find_year_in_review
|
11
11
|
get_year_in_review_tracks
|
12
12
|
|
@@ -19,7 +19,7 @@ class Library::Music::YearsInReviewController < ::MusicMetadataEnrichment::Appli
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def show
|
22
|
-
@user = User.
|
22
|
+
@user = User.by_slug_or_id(params[:user_id])
|
23
23
|
@year_in_review = @user.years_in_review_music
|
24
24
|
@year_in_review = @year_in_review.published unless current_user.try(:id) == @user.id
|
25
25
|
@year_in_review = @year_in_review.where(year: params[:year]).first
|
@@ -55,7 +55,7 @@ class Library::Music::YearsInReviewController < ::MusicMetadataEnrichment::Appli
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def get_years_in_review
|
58
|
-
@user ||= User.
|
58
|
+
@user ||= User.by_slug_or_id(params[:user_id])
|
59
59
|
@years_in_review = @user.years_in_review_music
|
60
60
|
@years_in_review = @years_in_review.published unless current_user.try(:id) == @user.id
|
61
61
|
@years_in_review = @years_in_review.order('year DESC').paginate(per_page: 10, page: params[:page] || 1)
|
@@ -4,7 +4,7 @@ class Library::MusicController < ::MusicMetadataEnrichment::ApplicationControlle
|
|
4
4
|
|
5
5
|
def index
|
6
6
|
@year = Time.now.strftime('%Y')
|
7
|
-
@user = User.
|
7
|
+
@user = User.by_slug_or_id(params[:user_id])
|
8
8
|
@releases = @user.music_releases.released_in_year(@year).order('released_at DESC')
|
9
9
|
end
|
10
10
|
|
@@ -14,7 +14,7 @@ class MusicMetadataEnrichment::ArtistsController < ::MusicMetadataEnrichment::Ap
|
|
14
14
|
@artists = @group.artists
|
15
15
|
@pagination_params = { group_id: (params[:group_id] || params[:id]) }
|
16
16
|
elsif params[:user_id].present?
|
17
|
-
@artists = User.
|
17
|
+
@artists = User.by_slug_or_id(params[:user_id]).music_artists
|
18
18
|
end
|
19
19
|
|
20
20
|
@artists = @artists.order('name ASC').paginate(per_page: 10, page: params[:page] || 1)
|
@@ -14,7 +14,7 @@ class MusicMetadataEnrichment::ReleasesController < ::MusicMetadataEnrichment::A
|
|
14
14
|
@group = MusicMetadataEnrichment::Group.find(params[:id])
|
15
15
|
@releases = @group.releases
|
16
16
|
elsif params[:user_id].present?
|
17
|
-
@user = User.
|
17
|
+
@user = User.by_slug_or_id(params[:user_id])
|
18
18
|
@releases = @user.music_releases
|
19
19
|
end
|
20
20
|
|
@@ -17,7 +17,7 @@ class MusicMetadataEnrichment::VideosController < ::MusicMetadataEnrichment::App
|
|
17
17
|
elsif params[:uploaded_by_the_user] == 'true'
|
18
18
|
@videos = MusicVideo.where(user_id: params[:user_id])
|
19
19
|
elsif params[:user_id].present?
|
20
|
-
@videos = User.
|
20
|
+
@videos = User.by_slug_or_id(params[:user_id]).music_videos
|
21
21
|
end
|
22
22
|
|
23
23
|
@videos = @videos.order('created_at DESC').paginate(per_page: 5, page: params[:page] || 1)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Voluntary
|
2
|
+
module Api
|
3
|
+
module V1
|
4
|
+
module Music
|
5
|
+
class ArtistsController < Voluntary::Api::V1::BaseController
|
6
|
+
respond_to :json
|
7
|
+
|
8
|
+
def index
|
9
|
+
params[:page] = nil if params[:page] == ''
|
10
|
+
params[:per_page] = nil if params[:per_page] == ''
|
11
|
+
artists = MusicArtist
|
12
|
+
artists = artists.where(state: params[:state]) if params[:state].present?
|
13
|
+
artists = artists.order('name ASC').paginate(per_page: params[:per_page] || 10, page: params[:page] || 1)
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.json {
|
17
|
+
render json: {
|
18
|
+
current_page: artists.current_page, per_page: artists.per_page, total_entries: artists.total_entries, total_pages: artists.total_pages,
|
19
|
+
entries: artists.map(&:to_json),
|
20
|
+
}.to_json
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def show
|
26
|
+
respond_to do |format|
|
27
|
+
format.json { render json: MusicArtist.find(params[:id]).to_json }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -5,11 +5,25 @@ module Voluntary
|
|
5
5
|
class ReleasesController < Voluntary::Api::V1::BaseController
|
6
6
|
respond_to :json
|
7
7
|
|
8
|
+
def index
|
9
|
+
respond_to do |format|
|
10
|
+
format.json {
|
11
|
+
render json: MusicRelease.where(artist_id: params[:artist_id]).order('released_at DESC').map(&:to_json).to_json
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
def bulk
|
9
17
|
respond_to do |format|
|
10
18
|
format.json { render json: MusicRelease.enrich_metadata(params[:releases]).to_json }
|
11
19
|
end
|
12
20
|
end
|
21
|
+
|
22
|
+
def show
|
23
|
+
respond_to do |format|
|
24
|
+
format.json { render json: MusicRelease.find(params[:id]).to_json }
|
25
|
+
end
|
26
|
+
end
|
13
27
|
end
|
14
28
|
end
|
15
29
|
end
|
@@ -5,11 +5,25 @@ module Voluntary
|
|
5
5
|
class TracksController < Voluntary::Api::V1::BaseController
|
6
6
|
respond_to :json
|
7
7
|
|
8
|
+
def index
|
9
|
+
respond_to do |format|
|
10
|
+
format.json {
|
11
|
+
render json: MusicTrack.where(release_id: params[:release_id]).order('nr ASC').map(&:to_json).to_json
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
8
16
|
def bulk
|
9
17
|
respond_to do |format|
|
10
18
|
format.json { render json: MusicTrack.enrich_metadata(params[:tracks]).to_json }
|
11
19
|
end
|
12
20
|
end
|
21
|
+
|
22
|
+
def show
|
23
|
+
respond_to do |format|
|
24
|
+
format.json { render json: MusicTrack.find(params[:id]).to_json }
|
25
|
+
end
|
26
|
+
end
|
13
27
|
end
|
14
28
|
end
|
15
29
|
end
|
@@ -6,23 +6,30 @@ module Voluntary
|
|
6
6
|
respond_to :json
|
7
7
|
|
8
8
|
def index
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
primitive_videos = if params[:track_id].present?
|
10
|
+
MusicVideo.where(track_id: params[:track_id]).order_by_status.map(&:to_json)
|
11
|
+
else
|
12
|
+
params[:page] = nil if params[:page] == ''
|
13
|
+
params[:per_page] = nil if params[:per_page] == ''
|
14
|
+
videos = MusicVideo.liked_by(params[:user_id]).order('likes.created_at DESC').paginate(per_page: params[:per_page] || 10, page: params[:page] || 1)
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
{
|
19
|
-
id: v.id, status: v.status, artist_id: v.artist_id, artist_name: v.artist_name,
|
20
|
-
track_id: v.track_id, track_name: v.track_name, url: v.url, liked_at: v.liked_at.iso8601
|
21
|
-
}
|
22
|
-
end,
|
23
|
-
}.to_json
|
16
|
+
{
|
17
|
+
current_page: videos.current_page, per_page: videos.per_page, total_entries: videos.total_entries, total_pages: videos.total_pages,
|
18
|
+
entries: videos.map do |video|
|
19
|
+
video.to_json.merge(liked_at: video.liked_at.iso8601)
|
20
|
+
end,
|
24
21
|
}
|
25
22
|
end
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
format.json { render json: primitive_videos.to_json }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def show
|
30
|
+
respond_to do |format|
|
31
|
+
format.json { render json: MusicVideo.find(params[:id]).to_json }
|
32
|
+
end
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
data/app/models/music_artist.rb
CHANGED
@@ -19,6 +19,8 @@ class MusicArtist < ActiveRecord::Base
|
|
19
19
|
|
20
20
|
attr_accessible :name, :is_ambiguous, :mbid, :disambiguation, :founded_at, :dissolved_at, :listeners, :plays
|
21
21
|
|
22
|
+
after_initialize :set_initial_state
|
23
|
+
|
22
24
|
state_machine :state, initial: :without_metadata do
|
23
25
|
event :import_metadata do transition :without_metadata => :active; end
|
24
26
|
|
@@ -39,8 +41,9 @@ class MusicArtist < ActiveRecord::Base
|
|
39
41
|
is_ambiguous: is_ambiguous
|
40
42
|
)
|
41
43
|
|
44
|
+
lastfm = Lastfm.new(LastfmApiKey, LastfmApiSecret)
|
45
|
+
|
42
46
|
unless artist.listeners.present? && artist.plays.present?
|
43
|
-
lastfm = Lastfm.new(LastfmApiKey, LastfmApiSecret)
|
44
47
|
lastfm_artist = artist.lastfm_request(lastfm, :artist, :get_info, 'The artist you supplied could not be found', artist: artist.name)
|
45
48
|
artist.update_attributes(listeners: lastfm_artist['stats']['listeners'], plays: lastfm_artist['stats']['playcount']) unless lastfm_artist.nil?
|
46
49
|
end
|
@@ -53,6 +56,20 @@ class MusicArtist < ActiveRecord::Base
|
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
59
|
+
def self.create_by_name(name)
|
60
|
+
music_brainz_artists = MusicBrainz::Artist.search(name).select{|a| a[:name].downcase == name.downcase }
|
61
|
+
artist_mbids = music_brainz_artists.map{|a| a[:mbid] }
|
62
|
+
existing_artists = where(mbid: artist_mbids).map{|a| [a.id, a.mbid] }
|
63
|
+
ids = existing_artists.map(&:first); mbids = existing_artists.map(&:last)
|
64
|
+
|
65
|
+
artist_mbids.select{|m| !mbids.include?(m) }.each do |mbid|
|
66
|
+
artist = create(name: name, mbid: mbid, is_ambiguous: music_brainz_artists.length > 1)
|
67
|
+
ids << artist.id if artist.persisted?
|
68
|
+
end
|
69
|
+
|
70
|
+
ids
|
71
|
+
end
|
72
|
+
|
56
73
|
def is_classical?(lastfm = nil)
|
57
74
|
lastfm ||= Lastfm.new(LastfmApiKey, LastfmApiSecret)
|
58
75
|
|
@@ -217,8 +234,21 @@ class MusicArtist < ActiveRecord::Base
|
|
217
234
|
end
|
218
235
|
end
|
219
236
|
|
237
|
+
def to_json
|
238
|
+
{
|
239
|
+
id: id, mbid: mbid, name: name, is_ambiguous: is_ambiguous,
|
240
|
+
disambiguation: disambiguation, listeners: listeners, plays: plays,
|
241
|
+
founded_at: founded_at.try(:iso8601), dissolved_at: dissolved_at.try(:iso8601),
|
242
|
+
state: state
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
220
246
|
private
|
221
247
|
|
248
|
+
def set_initial_state
|
249
|
+
self.state ||= :without_metadata
|
250
|
+
end
|
251
|
+
|
222
252
|
def create_bonustracks_release
|
223
253
|
release = releases.create(name: '[Bonus Tracks]', is_lp: true)
|
224
254
|
release.update_attribute(:state, 'active')
|
@@ -34,22 +34,18 @@ module MusicMetadataEnrichment
|
|
34
34
|
next
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
artist_ids = MusicArtist.create_by_name(artist_name)
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
next if artist_ids.none?
|
40
|
+
|
41
|
+
artist_connection_artist_ids = artist_connections.where(artist_id: artist_ids).map(&:artist_id)
|
42
|
+
artist_ids = artist_ids.select{|id| !artist_connection_artist_ids.include?(id) }
|
43
|
+
|
44
|
+
if artist_ids.any?
|
45
|
+
artist_ids.each do |artist_id|
|
46
|
+
MusicMetadataEnrichment::GroupArtistConnection.create(group_id: id, artist_id: artist_id)
|
45
47
|
end
|
46
48
|
end
|
47
|
-
|
48
|
-
next unless artist
|
49
|
-
|
50
|
-
if artist_connections.where(artist_id: artist.id).none?
|
51
|
-
MusicMetadataEnrichment::GroupArtistConnection.create(group_id: id, artist_id: artist.id)
|
52
|
-
end
|
53
49
|
end
|
54
50
|
|
55
51
|
artist_names_without_mbid
|
data/app/models/music_release.rb
CHANGED
@@ -126,6 +126,8 @@ class MusicRelease < ActiveRecord::Base
|
|
126
126
|
|
127
127
|
attr_accessor :releases
|
128
128
|
|
129
|
+
after_initialize :set_initial_state
|
130
|
+
|
129
131
|
state_machine :state, initial: :without_metadata do
|
130
132
|
event :import_metadata do transition :without_metadata => :active; end
|
131
133
|
|
@@ -287,7 +289,7 @@ class MusicRelease < ActiveRecord::Base
|
|
287
289
|
|
288
290
|
musicbrainz_release_groups = musicbrainz_release_groups.select do |rg|
|
289
291
|
['Album', 'Soundtrack', 'EP'].include?(rg[:type]) &&
|
290
|
-
rg[:releases].select{|r| r[:status] == 'Official'}.any? &&
|
292
|
+
!rg[:releases].nil? && rg[:releases].select{|r| r[:status] == 'Official'}.any? &&
|
291
293
|
(rg[:secondary_types].nil? || rg[:secondary_types].select{|st| SECONDARY_TYPES_BLACKLIST.include?(st)}.none?) &&
|
292
294
|
rg[:artists].length == 1
|
293
295
|
end
|
@@ -393,8 +395,22 @@ class MusicRelease < ActiveRecord::Base
|
|
393
395
|
first_track_nr_of_disc
|
394
396
|
end
|
395
397
|
|
398
|
+
def to_json
|
399
|
+
{
|
400
|
+
id: id, mbid: mbid, spotify_id: spotify_album_id, is_lp: is_lp,
|
401
|
+
artist_id: artist_id, artist_name: artist_name, name: name,
|
402
|
+
future_release_date: future_release_date,
|
403
|
+
released_at: released_at.try(:iso8601), listeners: listeners,
|
404
|
+
plays: plays, state: state
|
405
|
+
}
|
406
|
+
end
|
407
|
+
|
396
408
|
private
|
397
409
|
|
410
|
+
def set_initial_state
|
411
|
+
self.state ||= :without_metadata
|
412
|
+
end
|
413
|
+
|
398
414
|
def future_release_date_format
|
399
415
|
return unless future_release_date.present?
|
400
416
|
|
data/app/models/music_track.rb
CHANGED
@@ -6,7 +6,7 @@ class MusicTrack < ActiveRecord::Base
|
|
6
6
|
|
7
7
|
# cached associations
|
8
8
|
belongs_to :artist, class_name: 'MusicArtist'
|
9
|
-
belongs_to :release, class_name: 'MusicRelease', counter_cache:
|
9
|
+
belongs_to :release, class_name: 'MusicRelease', counter_cache: 'tracks_count'
|
10
10
|
|
11
11
|
has_many :videos, foreign_key: 'track_id', class_name: 'MusicVideo', dependent: :destroy
|
12
12
|
has_many :group_year_in_review_tops, foreign_key: 'track_id', class_name: 'MusicMetadataEnrichment::GroupYearInReviewTrack', dependent: :destroy
|
@@ -66,6 +66,8 @@ class MusicTrack < ActiveRecord::Base
|
|
66
66
|
after_update :sync_year_in_review_music_tracks
|
67
67
|
after_destroy :destroy_slaves
|
68
68
|
|
69
|
+
after_initialize :set_initial_state
|
70
|
+
|
69
71
|
state_machine :state, initial: :without_metadata do
|
70
72
|
event :import_metadata do transition :without_metadata => :active; end
|
71
73
|
|
@@ -294,8 +296,24 @@ class MusicTrack < ActiveRecord::Base
|
|
294
296
|
Time.at(duration / 1000).strftime('%M:%S') if duration.present?
|
295
297
|
end
|
296
298
|
|
299
|
+
def to_json
|
300
|
+
{
|
301
|
+
id: id, mbid: mbid, spotify_id: spotify_track_id, nr: nr,
|
302
|
+
master_track_id: master_track_id, artist_id: artist_id,
|
303
|
+
artist_name: artist_name, name: name,
|
304
|
+
release_id: release_id, release_name: release_name,
|
305
|
+
duration: formatted_duration,
|
306
|
+
released_at: released_at.try(:iso8601), listeners: listeners,
|
307
|
+
plays: plays, state: state
|
308
|
+
}
|
309
|
+
end
|
310
|
+
|
297
311
|
private
|
298
312
|
|
313
|
+
def set_initial_state
|
314
|
+
self.state ||= :without_metadata
|
315
|
+
end
|
316
|
+
|
299
317
|
def name_not_included_in_blacklist
|
300
318
|
if ::MusicTrack.name_included_in_blacklist?(name)
|
301
319
|
errors[:name] << I18n.t('activerecord.errors.models.music_metadata_enrichment_group.attributes.name.included_in_blacklist')
|
data/app/models/music_video.rb
CHANGED
@@ -60,6 +60,13 @@ class MusicVideo < ActiveRecord::Base
|
|
60
60
|
"#{track.artist_name } – #{track_name} (#{status})"
|
61
61
|
end
|
62
62
|
|
63
|
+
def to_json
|
64
|
+
{
|
65
|
+
id: id, status: status, artist_id: artist_id, artist_name: artist_name,
|
66
|
+
track_id: track_id, track_name: track_name, url: url
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
63
70
|
private
|
64
71
|
|
65
72
|
def url_format
|
@@ -20,6 +20,8 @@ class YearInReviewMusic < ActiveRecord::Base
|
|
20
20
|
serialize :top_release_matches, Array
|
21
21
|
serialize :top_track_matches, Array
|
22
22
|
|
23
|
+
after_initialize :set_initial_state
|
24
|
+
|
23
25
|
state_machine :state, initial: :draft do
|
24
26
|
event :publish do
|
25
27
|
transition draft: :published
|
@@ -322,4 +324,10 @@ class YearInReviewMusic < ActiveRecord::Base
|
|
322
324
|
end
|
323
325
|
end
|
324
326
|
end
|
327
|
+
|
328
|
+
private
|
329
|
+
|
330
|
+
def set_initial_state
|
331
|
+
self.state ||= :draft
|
332
|
+
end
|
325
333
|
end
|
data/config/routes/api.rb
CHANGED
@@ -1,19 +1,29 @@
|
|
1
1
|
namespace :voluntary, path: 'api', module: 'voluntary/api', defaults: {format: 'json'} do
|
2
2
|
namespace :v1 do
|
3
3
|
namespace :music do
|
4
|
-
resources :
|
4
|
+
resources :artists, only: [:index, :show] do
|
5
|
+
resources :releases, only: [:index]
|
6
|
+
end
|
7
|
+
|
8
|
+
resources :releases, only: [:show] do
|
5
9
|
collection do
|
6
10
|
get :bulk
|
7
11
|
post :bulk
|
8
12
|
end
|
13
|
+
|
14
|
+
resources :tracks, only: [:index]
|
9
15
|
end
|
10
16
|
|
11
|
-
resources :tracks, only: [] do
|
17
|
+
resources :tracks, only: [:show] do
|
12
18
|
collection do
|
13
19
|
get :bulk
|
14
20
|
post :bulk
|
15
21
|
end
|
22
|
+
|
23
|
+
resources :videos, only: [:index]
|
16
24
|
end
|
25
|
+
|
26
|
+
resources :videos, only: [:show]
|
17
27
|
end
|
18
28
|
|
19
29
|
resources :users, only: [:show] do
|
metadata
CHANGED
@@ -1,316 +1,305 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: voluntary_music_metadata_enrichment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Gawlista
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: voluntary
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: musicbrainz
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: lastfm
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 1.26.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 1.26.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: letter_opener
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.0.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.0.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: oink
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 0.10.1
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 0.10.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: awesome_print
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: 1.1.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 1.1.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec-rails
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '2.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '2.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: capybara
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: 1.1.2
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 1.1.2
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: capybara-webkit
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - ~>
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: 0.13.0
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - ~>
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 0.13.0
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: cucumber
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ~>
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 1.2.5
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ~>
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 1.2.5
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: cucumber-rails-training-wheels
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
|
-
- - ~>
|
143
|
+
- - "~>"
|
158
144
|
- !ruby/object:Gem::Version
|
159
145
|
version: 1.0.0
|
160
146
|
type: :development
|
161
147
|
prerelease: false
|
162
148
|
version_requirements: !ruby/object:Gem::Requirement
|
163
149
|
requirements:
|
164
|
-
- - ~>
|
150
|
+
- - "~>"
|
165
151
|
- !ruby/object:Gem::Version
|
166
152
|
version: 1.0.0
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
name: timecop
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
170
156
|
requirements:
|
171
|
-
- - ~>
|
157
|
+
- - "~>"
|
172
158
|
- !ruby/object:Gem::Version
|
173
159
|
version: 0.6.1
|
174
160
|
type: :development
|
175
161
|
prerelease: false
|
176
162
|
version_requirements: !ruby/object:Gem::Requirement
|
177
163
|
requirements:
|
178
|
-
- - ~>
|
164
|
+
- - "~>"
|
179
165
|
- !ruby/object:Gem::Version
|
180
166
|
version: 0.6.1
|
181
167
|
- !ruby/object:Gem::Dependency
|
182
168
|
name: factory_girl_rails
|
183
169
|
requirement: !ruby/object:Gem::Requirement
|
184
170
|
requirements:
|
185
|
-
- - ~>
|
171
|
+
- - "~>"
|
186
172
|
- !ruby/object:Gem::Version
|
187
173
|
version: 1.7.0
|
188
174
|
type: :development
|
189
175
|
prerelease: false
|
190
176
|
version_requirements: !ruby/object:Gem::Requirement
|
191
177
|
requirements:
|
192
|
-
- - ~>
|
178
|
+
- - "~>"
|
193
179
|
- !ruby/object:Gem::Version
|
194
180
|
version: 1.7.0
|
195
181
|
- !ruby/object:Gem::Dependency
|
196
182
|
name: fixture_builder
|
197
183
|
requirement: !ruby/object:Gem::Requirement
|
198
184
|
requirements:
|
199
|
-
- - ~>
|
185
|
+
- - "~>"
|
200
186
|
- !ruby/object:Gem::Version
|
201
187
|
version: 0.3.3
|
202
188
|
type: :development
|
203
189
|
prerelease: false
|
204
190
|
version_requirements: !ruby/object:Gem::Requirement
|
205
191
|
requirements:
|
206
|
-
- - ~>
|
192
|
+
- - "~>"
|
207
193
|
- !ruby/object:Gem::Version
|
208
194
|
version: 0.3.3
|
209
195
|
- !ruby/object:Gem::Dependency
|
210
196
|
name: selenium-webdriver
|
211
197
|
requirement: !ruby/object:Gem::Requirement
|
212
198
|
requirements:
|
213
|
-
- - ~>
|
199
|
+
- - "~>"
|
214
200
|
- !ruby/object:Gem::Version
|
215
201
|
version: 2.22.1
|
216
202
|
type: :development
|
217
203
|
prerelease: false
|
218
204
|
version_requirements: !ruby/object:Gem::Requirement
|
219
205
|
requirements:
|
220
|
-
- - ~>
|
206
|
+
- - "~>"
|
221
207
|
- !ruby/object:Gem::Version
|
222
208
|
version: 2.22.1
|
223
209
|
- !ruby/object:Gem::Dependency
|
224
210
|
name: spork
|
225
211
|
requirement: !ruby/object:Gem::Requirement
|
226
212
|
requirements:
|
227
|
-
- - ~>
|
213
|
+
- - "~>"
|
228
214
|
- !ruby/object:Gem::Version
|
229
215
|
version: 1.0rc2
|
230
216
|
type: :development
|
231
217
|
prerelease: false
|
232
218
|
version_requirements: !ruby/object:Gem::Requirement
|
233
219
|
requirements:
|
234
|
-
- - ~>
|
220
|
+
- - "~>"
|
235
221
|
- !ruby/object:Gem::Version
|
236
222
|
version: 1.0rc2
|
237
223
|
- !ruby/object:Gem::Dependency
|
238
224
|
name: guard-rspec
|
239
225
|
requirement: !ruby/object:Gem::Requirement
|
240
226
|
requirements:
|
241
|
-
- - ~>
|
227
|
+
- - "~>"
|
242
228
|
- !ruby/object:Gem::Version
|
243
229
|
version: 3.0.2
|
244
230
|
type: :development
|
245
231
|
prerelease: false
|
246
232
|
version_requirements: !ruby/object:Gem::Requirement
|
247
233
|
requirements:
|
248
|
-
- - ~>
|
234
|
+
- - "~>"
|
249
235
|
- !ruby/object:Gem::Version
|
250
236
|
version: 3.0.2
|
251
237
|
- !ruby/object:Gem::Dependency
|
252
238
|
name: guard-spork
|
253
239
|
requirement: !ruby/object:Gem::Requirement
|
254
240
|
requirements:
|
255
|
-
- - ~>
|
241
|
+
- - "~>"
|
256
242
|
- !ruby/object:Gem::Version
|
257
243
|
version: 1.5.1
|
258
244
|
type: :development
|
259
245
|
prerelease: false
|
260
246
|
version_requirements: !ruby/object:Gem::Requirement
|
261
247
|
requirements:
|
262
|
-
- - ~>
|
248
|
+
- - "~>"
|
263
249
|
- !ruby/object:Gem::Version
|
264
250
|
version: 1.5.1
|
265
251
|
- !ruby/object:Gem::Dependency
|
266
252
|
name: guard-cucumber
|
267
253
|
requirement: !ruby/object:Gem::Requirement
|
268
254
|
requirements:
|
269
|
-
- - ~>
|
255
|
+
- - "~>"
|
270
256
|
- !ruby/object:Gem::Version
|
271
257
|
version: 1.4.0
|
272
258
|
type: :development
|
273
259
|
prerelease: false
|
274
260
|
version_requirements: !ruby/object:Gem::Requirement
|
275
261
|
requirements:
|
276
|
-
- - ~>
|
262
|
+
- - "~>"
|
277
263
|
- !ruby/object:Gem::Version
|
278
264
|
version: 1.4.0
|
279
265
|
- !ruby/object:Gem::Dependency
|
280
266
|
name: launchy
|
281
267
|
requirement: !ruby/object:Gem::Requirement
|
282
268
|
requirements:
|
283
|
-
- - ~>
|
269
|
+
- - "~>"
|
284
270
|
- !ruby/object:Gem::Version
|
285
271
|
version: 2.1.2
|
286
272
|
type: :development
|
287
273
|
prerelease: false
|
288
274
|
version_requirements: !ruby/object:Gem::Requirement
|
289
275
|
requirements:
|
290
|
-
- - ~>
|
276
|
+
- - "~>"
|
291
277
|
- !ruby/object:Gem::Version
|
292
278
|
version: 2.1.2
|
293
279
|
- !ruby/object:Gem::Dependency
|
294
280
|
name: database_cleaner
|
295
281
|
requirement: !ruby/object:Gem::Requirement
|
296
282
|
requirements:
|
297
|
-
- - ~>
|
283
|
+
- - "~>"
|
298
284
|
- !ruby/object:Gem::Version
|
299
285
|
version: 0.7.1
|
300
286
|
type: :development
|
301
287
|
prerelease: false
|
302
288
|
version_requirements: !ruby/object:Gem::Requirement
|
303
289
|
requirements:
|
304
|
-
- - ~>
|
290
|
+
- - "~>"
|
305
291
|
- !ruby/object:Gem::Version
|
306
292
|
version: 0.7.1
|
307
|
-
description:
|
293
|
+
description: 'Importer, year in reviews, videos, etc. - changes: bit.ly/vmme-0-2-0'
|
308
294
|
email:
|
309
295
|
- gawlista@gmail.com
|
310
296
|
executables: []
|
311
297
|
extensions: []
|
312
298
|
extra_rdoc_files: []
|
313
299
|
files:
|
300
|
+
- CHANGELOG.md
|
301
|
+
- LICENSE
|
302
|
+
- README.md
|
314
303
|
- Rakefile
|
315
304
|
- app/assets/javascripts/voluntary_music_metadata_enrichment/application.js
|
316
305
|
- app/assets/javascripts/voluntary_music_metadata_enrichment/groups/show.js.coffee
|
@@ -345,6 +334,7 @@ files:
|
|
345
334
|
- app/controllers/music_metadata_enrichment/tracks_controller.rb
|
346
335
|
- app/controllers/music_metadata_enrichment/videos_controller.rb
|
347
336
|
- app/controllers/product/music_metadata_enrichment_controller.rb
|
337
|
+
- app/controllers/voluntary/api/v1/music/artists_controller.rb
|
348
338
|
- app/controllers/voluntary/api/v1/music/releases_controller.rb
|
349
339
|
- app/controllers/voluntary/api/v1/music/tracks_controller.rb
|
350
340
|
- app/controllers/voluntary/api/v1/music/videos_controller.rb
|
@@ -506,19 +496,19 @@ require_paths:
|
|
506
496
|
- lib
|
507
497
|
required_ruby_version: !ruby/object:Gem::Requirement
|
508
498
|
requirements:
|
509
|
-
- -
|
499
|
+
- - ">="
|
510
500
|
- !ruby/object:Gem::Version
|
511
501
|
version: '0'
|
512
502
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
513
503
|
requirements:
|
514
|
-
- -
|
504
|
+
- - ">="
|
515
505
|
- !ruby/object:Gem::Version
|
516
506
|
version: '0'
|
517
507
|
requirements: []
|
518
508
|
rubyforge_project:
|
519
|
-
rubygems_version: 2.4.
|
509
|
+
rubygems_version: 2.4.5
|
520
510
|
signing_key:
|
521
511
|
specification_version: 4
|
522
|
-
summary: Music metadata enrichment plugin for crowdsourcing
|
512
|
+
summary: Music metadata enrichment plugin for crowdsourcing management system Voluntary.Software.
|
523
513
|
test_files: []
|
524
514
|
has_rdoc:
|