Working search! Weee!

This commit is contained in:
magnolia-fan 2011-09-10 02:13:02 +04:00
parent 16703a87ec
commit fe7737574d
14 changed files with 349 additions and 344 deletions

View File

@ -1,84 +1,51 @@
class window.Ajax class window.Ajax
referer: false referer: false
loadArtistData: (name) -> loadSettingsPage: ->
_search.showSpinner() $.get '/templates/settings.html', (data) ->
name = name.split(' ').join('+') _ajax.setArchor '/settings/'
$.get '/artist/' +name+ '/', (data) -> _page.renderSettings _beathaven.localizeHTML $(data)
if data.status? false
if data.status is 'loading'
_search.showArtistPics data.pics load404Page: ->
setTimeout () -> $.get '/404.html', (data) ->
_ajax.loadArtistData name $('.data-container .inner').html data
, 3000 false
else if data.status is 'corrected'
_ajax.loadArtistData data.page loadAboutPage: ->
else if data.status is 'suggestions' $.get '/templates/about.html', (data) ->
_search.hideSpinner() _page.renderTextpage data
_search.showSuggestions data.values _ajax.setTitle 'About'
else if data.status == 'loading_failed' false
_search.hideSpinner()
_search.showError() setArchor: (anchor) ->
else @referer = this.getAnchor()
_ajax.setArchor '/artist/' +name+ '/' window.location.hash = '#' +anchor
_pages.renderArtist data
#_search.hideSpinner() getAnchor: () ->
false window.location.hash.substring 1;
loadSearchPage: -> setTitle: (title) ->
document.title = title+ ' @ BeatHaven'
false
go: (url) ->
loadSettingsPage: -> this.setArchor url
$.get '/templates/settings.html', (data) -> false
_ajax.setArchor '/settings/'
_pages.renderSettings _beathaven.localizeHTML $(data)
false
load404Page: ->
$.get '/404.html', (data) ->
$('.data-container .inner').html data
_beathaven.redrawScrollbar()
false
loadAboutPage: ->
$.get '/templates/about.html', (data) ->
_pages.renderTextpage data
_ajax.setTitle 'About'
false
setArchor: (anchor) ->
@referer = this.getAnchor()
window.location.hash = '#' +anchor
getAnchor: () ->
window.location.hash.substring 1;
setTitle: (title) ->
document.title = title+ ' @ BeatHaven'
go: (url) ->
this.setArchor url
false
detectPage: () -> detectPage: () ->
if m = _ajax.getAnchor().match /\/artist\/(.+)\// if m = _ajax.getAnchor().match /\/artist\/(.+)\//
_ajax.loadArtistData m[1] _search.loadArtistData m[1]
else if _ajax.getAnchor() == '' or _ajax.getAnchor().match /\/search\// else if _ajax.getAnchor() == '' or _ajax.getAnchor().match /\/search\//
_ajax.loadSearchPage(); _ajax.loadSearchPage();
else if _ajax.getAnchor().match /\/settings\// else if _ajax.getAnchor().match /\/settings\//
_ajax.loadSettingsPage() _ajax.loadSettingsPage()
else if _ajax.getAnchor().match /\/about\// else if _ajax.getAnchor().match /\/about\//
_ajax.loadAboutPage() _ajax.loadAboutPage()
else else
_ajax.loadSearchPage() #_ajax.loadSearchPage()
false false
$('a.data.artist').live 'click', ->
_ajax.loadArtistData $(this).html()
false
$(window).bind 'hashchange', -> $(window).bind 'hashchange', ->
_ajax.detectPage() #_ajax.detectPage()
false false

View File

@ -2,12 +2,12 @@
//= require jquery/jplayer/jquery.jplayer/jquery.jplayer //= require jquery/jplayer/jquery.jplayer/jquery.jplayer
//= require locale //= require locale
//= require vkontakte
//= require session //= require session
//= require vkontakte
//= require ajax //= require ajax
//= require player //= require player
//= require search //= require search
//= require pages //= require page
//= require settings //= require settings
//= require beathaven //= require beathaven

View File

@ -5,7 +5,7 @@ window._vkontakte = null
window._ajax = null window._ajax = null
window._player = null window._player = null
window._search = null window._search = null
window._pages = null window._page = null
window._settings = null window._settings = null
$ -> $ ->
@ -16,7 +16,7 @@ $ ->
window._beathaven = new BeatHaven() window._beathaven = new BeatHaven()
window._beathaven.init() window._beathaven.init()
class BeatHaven class window.BeatHaven
last_height: false last_height: false
lang: 'ru' lang: 'ru'
@ -32,7 +32,7 @@ class BeatHaven
window._search = new Search() window._search = new Search()
window._pages = new Pages() window._page = new Page()
window._settings = new Settings() window._settings = new Settings()
@ -53,34 +53,7 @@ class BeatHaven
containerId: 'autocomplete-container' containerId: 'autocomplete-container'
containerItemsId: 'autocomplete-items' containerItemsId: 'autocomplete-items'
onSelect: -> onSelect: ->
_ajax.loadArtistData $('#search').first().val() _search.loadArtistData $('#search').val()
adjustSizes: ->
$('.data-container').height $(window).height() - $('.header-container').height() - $('.pulldown').height()
$('.data-container').width $(window).width() - $('.player').width()
$('.player-container').height $(window).height()
$('.playlist').height $(window).height() - $('.player').height() - $('.player-container .additional-controls').height()
$('.data-container').scrollbar()
$('.playlist').scrollbar()
false
checkRedrawScrollbar: ->
focused_id = false
if document.activeElement.id?
focused_id = document.activeElement.id;
outer_height = $('.data-container > div').outerHeight()
if outer_height > 300 and outer_height != _beathaven.last_height
_beathaven.last_height = outer_height
_beathaven.redrawScrollbar()
if focused_id
document.getElementById(focused_id).focus()
focused_id = false
window.setTimeout ->
_beathaven.checkRedrawScrollbar()
false
, 500
false
localizeHTML: (obj, lang) -> localizeHTML: (obj, lang) ->
unless obj? unless obj?
@ -102,15 +75,6 @@ class BeatHaven
_locale[id][lang] _locale[id][lang]
else else
id id
pdShowSpinner: ->
$('.pulldown').html '<div class="pd-spinner"><img src="/images/loader.gif" alt=""/></div>'
false
pdHideSpinner: ->
$('.pulldown').html ''
false
String::htmlsafe = -> String::htmlsafe = ->
replaces = [ replaces = [

View File

@ -1,4 +1,8 @@
class window.Pages class window.Page
print: (html) ->
$('#content').html(html)
false
renderArtist: (data) -> renderArtist: (data) ->
$('#content').html(data) $('#content').html(data)

View File

@ -1,15 +1,37 @@
class window.Search class window.Search
showSpinner: -> showSpinner: ->
$('#search').val("").attr(disabled: 'disabled').blur() $('#search').attr(disabled: 'disabled').blur()
$('#autocomplete-container').hide() $('#autocomplete-container').hide()
$('#artist-load-spinner').show()
this.hideSuggestions() this.hideSuggestions()
false false
hideSpinner: -> hideSpinner: ->
$('#search').removeAttr 'disabled' $('#search').val("").removeAttr 'disabled'
$('.search_field').first().focus() $('#artist-load-spinner').hide()
$('.search-container img').first().hide() false
loadArtistData: (name) ->
_search.showSpinner()
name = name.split(' ').join('+')
$.get '/artist/' +name+ '/', (data) ->
if data.status in ['ok', 'loading']
_ajax.setArchor '/artist/' +name+ '/'
_page.print data.html
_search.hideSpinner()
if data.status is 'loading'
setTimeout () ->
_search.loadArtistData name
, 5000
else if data.status is 'corrected'
_search.loadArtistData data.correct_name
else if data.status is 'suggestions'
_search.hideSpinner()
_page.print data.html
else if data.status == 'fail'
_search.hideSpinner()
_page.print data.html
false false
showSuggestions: (values) -> showSuggestions: (values) ->
@ -59,13 +81,10 @@ $('.search').live 'click', ->
_beathaven.adjustSizes() _beathaven.adjustSizes()
_beathaven.redrawScrollbar() _beathaven.redrawScrollbar()
false false
$('.search_form').live 'submit', -> $('#search-form').live 'submit', ->
$('.autocomplete-container').remove() $('#autocomplete-container').remove()
_ajax.loadArtistData $('.search_field').first().val() _search.loadArtistData $('#search').val()
false
$('.suggestions a').live 'click', ->
$('.search_field').first().val $(this).text()
false false
$('.data.artist').live 'click', -> $('.data.artist').live 'click', ->
_ajax.go('/artist/'+$(this).text().replace(' ', '+')+'/'); _search.loadArtistData $(this).html()
false; false

View File

@ -1,140 +1,140 @@
class window.Vkontakte class window.Vkontakte
qr: null qr: null
api_id: null api_id: null
constructor: (@api_id) -> constructor: (@api_id) ->
getApiId: -> getApiId: ->
@api_id @api_id
init: -> init: ->
@qr = [] @qr = []
window.vkAsyncInit = -> window.vkAsyncInit = ->
VK.init apiId: _vkontakte.getApiId() VK.init apiId: _vkontakte.getApiId()
VK.Auth.getLoginStatus (response) -> VK.Auth.getLoginStatus (response) ->
_vkontakte.authInfo(response) _vkontakte.authInfo(response)
setTimeout -> setTimeout ->
$('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>') $('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>')
, 0 , 0
authInfo: (response) -> authInfo: (response) ->
if typeof response isnt 'undefined' and response.session if typeof response isnt 'undefined' and response.session
_session = new Session(response.session) _session = new Session(response.session)
$('#vk_login, .auth-notice').hide() $('#vk_login, .auth-notice').hide()
_session.query '/user/auth', {}, (ar) -> _session.query '/user/auth', {}, (ar) ->
if ar.newbie if ar.newbie
VK.Api.call 'getVariable', key: 1281, (r) -> VK.Api.call 'getVariable', key: 1281, (r) ->
_session.query '/user/update', name: r.response, (ar2) -> _session.query '/user/update', name: r.response, (ar2) ->
_session.setUser ar2.user _session.setUser ar2.user
$('.header-container .hello .greating') $('.header-container .hello .greating')
.html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!' .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
$('.fullscreen').hide(); $('.fullscreen').hide();
else else
_session.setUser ar.user _session.setUser ar.user
$('.header-container .hello').show() $('.header-container .hello').show()
$('.header-container .hello .greating') $('.header-container .hello .greating')
.html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!' .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
$('.fullscreen').hide(); $('.fullscreen').hide();
if response.session.expire? if response.session.expire?
setTimeout -> setTimeout ->
_vkontakte.auth() _vkontakte.auth()
false false
, response.session.expire * 1000 - new Date().getTime() + 1000 , response.session.expire * 1000 - new Date().getTime() + 1000
else else
_session = new Session({}) _session = new Session({})
_session.setUser {} _session.setUser {}
$('#vk_login').css display: 'block' $('#vk_login').css display: 'block'
$('.auth-notice').css('left', $('#vk_login').offset().left).show() $('.auth-notice').css('left', $('#vk_login').offset().left).show()
$('.header-container .hello').hide() $('.header-container .hello').hide()
window._session = _session window._session = _session
_ajax.detectPage() _ajax.detectPage()
$('.fullscreen').hide(); $('.fullscreen').hide();
auth: -> auth: ->
VK.Auth.getLoginStatus (response) -> VK.Auth.getLoginStatus (response) ->
_vkontakte.authInfo(response) _vkontakte.authInfo(response)
false false
, 8 , 8
false false
loadTracksData: (artist, track, duration, callback) -> loadTracksData: (artist, track, duration, callback) ->
track_prepared = track.replace(/\(.*\)/i, '').split('/')[0]; track_prepared = track.replace(/\(.*\)/i, '').split('/')[0];
query = artist+' '+track_prepared; query = artist+' '+track_prepared;
if url = _vkontakte.getQR query if url = _vkontakte.getQR query
callback url callback url
else else
VK.Api.call 'audio.search', q: query, (r) -> VK.Api.call 'audio.search', q: query, (r) ->
url = _vkontakte.matchPerfectResult r.response, artist, track, duration url = _vkontakte.matchPerfectResult r.response, artist, track, duration
_vkontakte.addQR query, url _vkontakte.addQR query, url
callback url callback url
matchPerfectResult: (data, artist, track, duration) -> matchPerfectResult: (data, artist, track, duration) ->
duration = duration.split ':' duration = duration.split ':'
duration = parseInt(duration[0], 10) * 60 + parseInt(duration[1], 10) duration = parseInt(duration[0], 10) * 60 + parseInt(duration[1], 10)
best_score = 0; best_score = 0;
best_result = null; best_result = null;
for item in data for item in data
if typeof item is 'object' if typeof item is 'object'
score = 0; score = 0;
item.artist = item.artist.trim(); item.artist = item.artist.trim();
item.title = item.title.trim(); item.title = item.title.trim();
if item.artist == artist if item.artist == artist
score += 10 score += 10
else if item.artist.split(artist).length is 2 else if item.artist.split(artist).length is 2
score += 5 score += 5
else if item.title.split(artist).length is 2 else if item.title.split(artist).length is 2
score += 4 score += 4
if item.title == track if item.title == track
score += 10 score += 10
else if item.title.split(track).length is 2 else if item.title.split(track).length is 2
score += 5 score += 5
if parseInt(item.duration, 10) == duration if parseInt(item.duration, 10) == duration
score += 15 score += 15
else else
delta = Math.abs parseInt(item.duration, 10) - duration delta = Math.abs parseInt(item.duration, 10) - duration
score += (10 - delta) if delta < 10 score += (10 - delta) if delta < 10
if score > best_score if score > best_score
best_score = score best_score = score
best_result = item best_result = item
if score is 35 if score is 35
return best_result.url return best_result.url
return best_result.url return best_result.url
addQR: (query, url) -> addQR: (query, url) ->
@qr[query] = url; @qr[query] = url;
getQR: (query) -> getQR: (query) ->
if @qr[query]? if @qr[query]?
@qr[query] @qr[query]
false false
$('#vk_login, .auth-notice').live 'click', -> $('#vk_login, .auth-notice').live 'click', ->
VK.Auth.login (response) -> VK.Auth.login (response) ->
_vkontakte.authInfo(response) _vkontakte.authInfo(response)
false false
, 8 , 8
false false
$('#vk_logout').live 'click', -> $('#vk_logout').live 'click', ->
_ajax.go '/search/'; _ajax.go '/search/';
VK.Auth.logout (response) -> VK.Auth.logout (response) ->
_vkontakte.authInfo(response) _vkontakte.authInfo(response)
false false
false false

View File

@ -15,9 +15,4 @@
left: 50%; left: 50%;
margin: -32px 0 0 -32px; margin: -32px 0 0 -32px;
} }
}
.artist-loader {
float: right;
margin: -26px 0 0 10px;
} }

View File

@ -18,4 +18,14 @@
} }
} }
} }
}
#artist-load-spinner {
display: none;
float: right;
margin: -26px 0 0 10px;
}
.suggestions a {
cursor: pointer;
} }

View File

@ -3,82 +3,114 @@ require 'open-uri'
class ArtistController < ApplicationController class ArtistController < ApplicationController
@@default_album_types = ['Album', 'Soundtrack'] @@default_album_types = ['Album', 'Soundtrack']
def data def data
data = {} @data = {
:status => '',
:correct_name => '',
:html => ''
}
@loading = false
# Bad params
if params[:name].nil? or params[:name].length == 0 if params[:name].nil? or params[:name].length == 0
render :json => {status: 'loading_failed', pics: []} @data[:status] = 'loading_failed';
render :json => @data
return return
end end
# Searching for artist
name = params[:name].gsub('%20', ' ').gsub('+', ' ').gsub('.html', '') name = params[:name].gsub('%20', ' ').gsub('+', ' ').gsub('.html', '')
artist = Artist.find_by_name(name) @artist = Artist.find_by_name(name)
if artist and artist.status == 0
pics = [] # Artist not found
pics << artist.pic_url unless artist.pic_url.nil? unless @artist
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) results = ArtistController.musicBrainzExactSearch(name)
if results.empty? if results.empty?
render :json => {status: 'not found'} @data[:status] = 'not_found'
return render :json => @data
elsif results[0][:name] != name and (results[0][:name].downcase == name.downcase or results[0][:name].downcase == 'the '+ name.downcase)
@data[:status] = 'corrected'
@data[:correct_name] = results[0][:name]
render :json => @data
elsif results[0][:name] == name elsif results[0][:name] == name
# Saving artist and queueing job # Saving artist and queueing job
artist = Artist.new @artist = Artist.new
artist.name = name @artist.name = name
artist.status = 0 @artist.status = 0
artist.save @artist.save
Delayed::Job.enqueue LoadArtistJob.new(name) Delayed::Job.enqueue LoadArtistJob.new(name)
render :json => {status: 'loading', pics: []} # Rendering loading info
return @artist = { :artist => @artist, :albums => [] }
elsif results[0][:name].downcase == name.downcase or results[0][:name].downcase == 'the '+ name.downcase @loading = true
render :json => {status: 'corrected', page: results[0][:name]} @data[:status] = 'loading'
return @data[:html] = (render_to_string :partial => 'page').gsub(/\n\s+/, '').gsub(/\n/, '')
render :json => @data
else else
render :json => {status: 'suggestions', values: results.take(5)} @suggestions = results.take(5)
return @data[:status] = 'suggestions'
@data[:html] = (render_to_string :partial => 'suggestions').gsub(/\n\s+/, '').gsub(/\n/, '')
render :json => @data
end end
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] = [] if @artist and @artist.status == 2
albums = artist.albums @data[:status] = 'fail'
albums.each do |album| @data[:html] = (render_to_string :partial => 'fail').gsub(/\n\s+/, '').gsub(/\n/, '')
render :json => @data
return
end
if @artist.status == 1
@data[:status] = 'ok'
else
@data[:status] = 'loading'
@loading = true
end
ap @artist
@data[:html] = buildArtistHTML(@artist)
render :json => @data
end
def buildArtistHTML artist
@artist[:artist] = {
id: artist.id,
name: artist.name,
desc: ActionController::Base.helpers.strip_tags(artist.desc),
pic: artist.pic_url
}
@artist[:albums] = []
artist.albums.each do |album|
if @@default_album_types.include? album.album_type if @@default_album_types.include? album.album_type
tmp_album = {id: album.id, name: album.name, year: album.year, pic: album.pic_url} tmp_album = {id: album.id, name: album.name, year: album.year, pic: album.pic_url}
album_tracks = [] album_tracks = []
bonus_tracks = [] bonus_tracks = []
album.tracks.each do |track| album.tracks.each do |track|
tmp_track = {id: track.id, name: track.name, live: track.live, acoustic: track.acoustic} tmp_track = {id: track.id, name: track.name, live: track.live, acoustic: track.acoustic}
if track.length tmp_track[:duration] = formatTrackDuration(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 (track.bonus == 0 ? album_tracks : bonus_tracks) << tmp_track
end end
tmp_album[:tracks] = {album: album_tracks, bonus: bonus_tracks} tmp_album[:tracks] = {album: album_tracks, bonus: bonus_tracks}
data[:albums] << tmp_album @artist[:albums] << tmp_album
end end
end end
@data = data
respond_to do |format| (render_to_string :partial => 'page').gsub(/\n\s+/, '').gsub(/\n/, '')
format.html { render :partial => 'data' } end
format.json { render :json => @data }
def formatTrackDuration length
if length
time = (length / 1000).round
time_m = (time / 60).floor
time_s = time - time_m * 60
time_m.to_s + ':' + (time_s < 10 ? '0' : '') + time_s.to_s
else
'0:00'
end end
end end
def autocomplete def autocomplete
autocomplete = ArtistController.getLastFmAutocomplete(params[:query]) autocomplete = getLastFmAutocomplete(params[:query])
return render :nothing => true if autocomplete.nil? return render :nothing => true if autocomplete.nil?
suggestions = [] suggestions = []
autocomplete["response"]["docs"].each do |doc| autocomplete["response"]["docs"].each do |doc|
@ -90,16 +122,16 @@ class ArtistController < ApplicationController
} }
end end
def self.getLastFmAutocomplete query def getLastFmAutocomplete query
return nil if query.nil? or query.strip.empty? return nil if query.nil? or query.strip.empty?
json = ActiveSupport::JSON.decode(open( json = ActiveSupport::JSON.decode(open(
'http://www.last.fm/search/autocomplete' << 'http://www.last.fm/search/autocomplete' <<
'?rows=30&q=' << URI.escape(query) '?rows=30&q=' << URI.escape(query)
).read) ).read)
return json.empty? ? nil : json json.empty? ? nil : json
end end
def self.musicBrainzSearch(query) def musicBrainzSearch(query)
begin 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) 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 = [] artists = []
@ -108,7 +140,7 @@ class ArtistController < ApplicationController
end end
artists.take(10) artists.take(10)
rescue rescue
return {} {}
end end
end end
@ -140,7 +172,7 @@ class ArtistController < ApplicationController
artists.sort! { |a, b| b[:weight] <=> a[:weight] } artists.sort! { |a, b| b[:weight] <=> a[:weight] }
artists.take(10) artists.take(10)
rescue rescue
return {} {}
end end
end end
end end

View File

@ -18,9 +18,8 @@ class ImportController < ApplicationController
lastfm = Lastfm.new(@@lastfm_api_key, @@lastfm_secret) lastfm = Lastfm.new(@@lastfm_api_key, @@lastfm_secret)
artist = Artist.find_or_create_by_name(name) artist = Artist.find_or_create_by_name(name)
begin
begin
# Get artist info # Get artist info
artist_mb_data = ArtistController.musicBrainzExactSearch(name).first artist_mb_data = ArtistController.musicBrainzExactSearch(name).first
begin begin
@ -30,13 +29,16 @@ class ImportController < ApplicationController
ap e.message ap e.message
ap e.backtrace ap e.backtrace
end end
# Save artist # Save artist
artist.desc = artist_lastfm['bio']['summary'] artist.desc = artist_lastfm['bio']['summary']
artist.pic_url = artist_lastfm['image'][3]['content'] artist.pic_url = artist_lastfm['image'][3]['content']
artist.artist_type = artist_mb['artist']['type'] artist.artist_type = artist_mb['artist']['type']
artist.mbid = artist_mb_data[:mbid] artist.mbid = artist_mb_data[:mbid]
artist.save! unless dry_run
end
begin
# Get albums from MB # Get albums from MB
release_groups_mb = brainz.release_group(nil, :artist => artist_mb_data[:mbid], :limit => 500) release_groups_mb = brainz.release_group(nil, :artist => artist_mb_data[:mbid], :limit => 500)
@ -167,7 +169,7 @@ class ImportController < ApplicationController
tracks_mb.each do |mb_track| tracks_mb.each do |mb_track|
unless ['[silence]', '[untitled]'].include? mb_track['recording']['title'] unless ['[silence]', '[untitled]'].include? mb_track['recording']['title']
track = Track.new track = Track.new
track.name = mb_track['recording']['title'].gsub(/\s\\\s\[.*?\]/, '') track.name = mb_track['recording']['title'].gsub(/\s\/\s\[.*?\]/, '')
track.album_id = album.id track.album_id = album.id
track.position = mb_track['position'] track.position = mb_track['position']
track.length = mb_track['length'] unless mb_track['length'].nil? track.length = mb_track['length'] unless mb_track['length'].nil?

View File

@ -0,0 +1,2 @@
.alert-message.error
%p Something very bad happened, sorry :(

View File

@ -1,11 +1,15 @@
- if @loading
.alert-message.warning
%p Artist info is loading for the first time. Please, be patient! :)
.row.artist-info .row.artist-info
.span4.columns.pic .span4.columns.pic
%img{ :src => @data[:artist][:pic] } = image_tag @artist[:artist][:pic] unless @artist[:artist][:pic].nil?
.span7.columns.desc .span7.columns.desc
%h2= @data[:artist][:name] %h2= @artist[:artist][:name]
= @data[:artist][:desc] = @artist[:artist][:desc] unless @artist[:artist][:desc].nil?
- @data[:albums].each do |album|
- @artist[:albums].each do |album|
.row.album .row.album
.span4.columns.art .span4.columns.art
%img{ :src => album[:pic] } %img{ :src => album[:pic] }
@ -17,4 +21,4 @@
- album[:tracks][:album].each do |track| - album[:tracks][:album].each do |track|
%tr %tr
%td.song-title= track[:name] %td.song-title= track[:name]
%td.song-duration= track[:duration] %td.song-duration= track[:duration]

View File

@ -0,0 +1,12 @@
.alert-message.warning
%p Made a typo?
%ul.suggestions
- @suggestions.each do |artist|
%li
%a.data.artist= artist[:name]
&nbsp;(
= artist[:type]
)
%br
%p= artist[:desc]

View File

@ -21,9 +21,9 @@
%a{ :href => "http://blog.beathaven.org/", :"data-ls" => "NEWS" } Blog %a{ :href => "http://blog.beathaven.org/", :"data-ls" => "NEWS" } Blog
%li %li
%a.about{ :href => "#/about/" } About %a.about{ :href => "#/about/" } About
%form{ :action => "" } %form#search-form{ :action => "" }
%input#search{ :type => "text", :placeholder => "Search" } %input#search{ :type => "text", :placeholder => "Search" }
.artist-loader #artist-load-spinner
= image_tag "artist_loader.gif" = image_tag "artist_loader.gif"
%ul.nav.secondary-nav %ul.nav.secondary-nav
%li.dropdown %li.dropdown
@ -86,9 +86,3 @@
= image_tag "loader.gif" = image_tag "loader.gif"
#vk_api_transport #vk_api_transport
<!-- Yandex.Metrika counter -->
<script type="text/javascript">var yaParams = {};</script><div style="display:none;"><script type="text/javascript">(function(w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter7596904 = new Ya.Metrika({id:7596904, enableAll: true,params:window.yaParams||{ }}); } catch(e) { } }); })(window, "yandex_metrika_callbacks");</script></div><script src="//mc.yandex.ru/metrika/watch.js" type="text/javascript" defer="defer"></script><noscript><div><img src="//mc.yandex.ru/watch/7596904" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->