require 'open-uri' class ArtistController < ApplicationController @@default_album_types = ['Album', 'Soundtrack'] def data data = {} if params[:name].nil? or params[:name].length == 0 render :json => {status: 'loading_failed', pics: []} return end name = params[:name].gsub('%20', ' ').gsub('+', ' ').gsub('.html', '') artist = Artist.find_by_name(name) if artist and artist.status == 0 pics = [] pics << artist.pic_url unless artist.pic_url.nil? unless artist.albums.empty? artist.albums.each do |album| pics << album.pic_url unless album.pic_url.nil? or album.pic_url.empty? end end render :json => {status: 'loading', pics: pics} return elsif artist and artist.status == 2 render :json => {status: 'loading_failed', pics: []} return end unless artist results = ArtistController.musicBrainzExactSearch(name) if results.empty? render :json => {status: 'not found'} return elsif results[0][:name] == name # Saving artist and queueing job artist = Artist.new artist.name = name artist.status = 0 artist.save Delayed::Job.enqueue LoadArtistJob.new(name) render :json => {status: 'loading', pics: []} return elsif results[0][:name].downcase == name.downcase or results[0][:name].downcase == 'the '+ name.downcase render :json => {status: 'corrected', page: results[0][:name]} return else render :json => {status: 'suggestions', values: results.take(5)} return end end data[:artist] = {id: artist.id, name: artist.name, desc: ActionController::Base.helpers.strip_tags(artist.desc), pic: artist.pic_url} data[:albums] = [] albums = artist.albums albums.each do |album| if @@default_album_types.include? album.album_type tmp_album = {id: album.id, name: album.name, year: album.year, pic: album.pic_url} album_tracks = [] bonus_tracks = [] album.tracks.each do |track| tmp_track = {id: track.id, name: track.name, live: track.live, acoustic: track.acoustic} if track.length time = (track.length / 1000).round time_m = (time / 60).floor time_s = time - time_m * 60 tmp_track[:duration] = time_m.to_s + ':' + (time_s < 10 ? '0' : '') + time_s.to_s else tmp_track[:duration] = '0:00' end (track.bonus == 0 ? album_tracks : bonus_tracks) << tmp_track end tmp_album[:tracks] = {album: album_tracks, bonus: bonus_tracks} data[:albums] << tmp_album end end @data = data respond_to do |format| format.html { render :partial => 'data' } format.json { render :json => @data } end end def autocomplete autocomplete = ArtistController.getLastFmAutocomplete(params[:query]) return render :nothing => true if autocomplete.nil? suggestions = [] autocomplete["response"]["docs"].each do |doc| suggestions << doc["artist"] unless suggestions.include?(doc["artist"]) or doc["artist"].nil? or doc['restype'] != 6 end render :json => { :query => params[:query], :suggestions => suggestions.take(5) } end def self.getLastFmAutocomplete query return nil if query.nil? or query.strip.empty? json = ActiveSupport::JSON.decode(open( 'http://www.last.fm/search/autocomplete' << '?rows=30&q=' << URI.escape(query) ).read) return json.empty? ? nil : json end def self.musicBrainzSearch(query) begin response = ActiveSupport::JSON.decode(open('http://search.test.musicbrainz.org/ws/2/artist/?fmt=json&query='+ URI.escape(query).gsub(/\&/, '%26').gsub(/\?/, '%3F') +'~&limit=100').read) artists = [] response['artist-list']['artist'].each do |artist| artists << artist['name'] unless artist['type'] == 'unknown' end artists.take(10) rescue return {} end end def self.musicBrainzExactSearch(query) begin response = ActiveSupport::JSON.decode(open('http://search.test.musicbrainz.org/ws/2/artist/?fmt=json&query='+ URI.escape(query).gsub(/\&/, '%26').gsub(/\?/, '%3F') +'~&limit=50', 'User-Agent' => 'BeatHaven.org' ).read) artists = [] i = 0 response['artist-list']['artist'].each do |artist| i++ artist['weight'] = (response['artist-list']['artist'].length - i) unless artist['alias-list'].nil? artist['weight'] += 20 if artist['alias-list']['alias'].include?(query) artist['alias-list']['alias'].each do |aliass| artist['weight'] += 10 if aliass.downcase == query.downcase artist['weight'] += 3 if aliass.downcase.include?(query.downcase) end end unless artist['tag-list'].nil? artist['weight'] += artist['tag-list']['tag'].length * 4 end end response['artist-list']['artist'].each do |artist| artists << {name: artist['name'], weight: artist['weight'], desc: artist['disambiguation'], type: artist['type'].capitalize, mbid: artist['id']} unless artist['type'] == 'unknown' end artists.sort! { |a, b| b[:weight] <=> a[:weight] } artists.take(10) rescue return {} end end end