139 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
require 'open-uri'
 | 
						|
 | 
						|
class ArtistController < ApplicationController
 | 
						|
  @@default_album_types = ['Album', 'Soundtrack']
 | 
						|
  def data
 | 
						|
    data = {}
 | 
						|
    name = params[:name].gsub('%20', ' ').gsub('+', ' ')
 | 
						|
    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'] = {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 = {name: album.name, year: album.year, pic: album.pic_url}
 | 
						|
        album_tracks = []
 | 
						|
        bonus_tracks = []
 | 
						|
        album.tracks.each do |track|
 | 
						|
          tmp_track = {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
 | 
						|
    render :json => data
 | 
						|
  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(10)
 | 
						|
		}
 | 
						|
	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
 |