Working search! Weee!
This commit is contained in:
		
							parent
							
								
									16703a87ec
								
							
						
					
					
						commit
						fe7737574d
					
				@ -1,84 +1,51 @@
 | 
			
		||||
class window.Ajax
 | 
			
		||||
	
 | 
			
		||||
	referer: false
 | 
			
		||||
	
 | 
			
		||||
	loadArtistData: (name) ->
 | 
			
		||||
		_search.showSpinner()
 | 
			
		||||
		name = name.split(' ').join('+')
 | 
			
		||||
		$.get '/artist/' +name+ '/', (data) ->
 | 
			
		||||
			if data.status?
 | 
			
		||||
				if data.status is 'loading'
 | 
			
		||||
					_search.showArtistPics data.pics
 | 
			
		||||
					setTimeout () ->
 | 
			
		||||
						_ajax.loadArtistData name
 | 
			
		||||
					, 3000
 | 
			
		||||
				else if data.status is 'corrected'
 | 
			
		||||
					_ajax.loadArtistData data.page
 | 
			
		||||
				else if data.status is 'suggestions'
 | 
			
		||||
					_search.hideSpinner()
 | 
			
		||||
					_search.showSuggestions data.values
 | 
			
		||||
				else if data.status == 'loading_failed'
 | 
			
		||||
					_search.hideSpinner()
 | 
			
		||||
					_search.showError()
 | 
			
		||||
			else
 | 
			
		||||
				_ajax.setArchor '/artist/' +name+ '/'
 | 
			
		||||
				_pages.renderArtist data
 | 
			
		||||
		#_search.hideSpinner()
 | 
			
		||||
		false
 | 
			
		||||
	
 | 
			
		||||
	loadSearchPage: ->
 | 
			
		||||
		
 | 
			
		||||
		false
 | 
			
		||||
	
 | 
			
		||||
	loadSettingsPage: ->
 | 
			
		||||
		$.get '/templates/settings.html', (data) ->
 | 
			
		||||
			_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
 | 
			
		||||
  
 | 
			
		||||
  referer: false
 | 
			
		||||
  
 | 
			
		||||
  loadSettingsPage: ->
 | 
			
		||||
    $.get '/templates/settings.html', (data) ->
 | 
			
		||||
      _ajax.setArchor '/settings/'
 | 
			
		||||
      _page.renderSettings _beathaven.localizeHTML $(data)
 | 
			
		||||
    false
 | 
			
		||||
  
 | 
			
		||||
  load404Page: ->
 | 
			
		||||
    $.get '/404.html', (data) ->
 | 
			
		||||
      $('.data-container .inner').html data
 | 
			
		||||
    false
 | 
			
		||||
  
 | 
			
		||||
  loadAboutPage: ->
 | 
			
		||||
    $.get '/templates/about.html', (data) ->
 | 
			
		||||
      _page.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: () ->
 | 
			
		||||
		if m = _ajax.getAnchor().match /\/artist\/(.+)\//
 | 
			
		||||
			_ajax.loadArtistData m[1]
 | 
			
		||||
		else if _ajax.getAnchor() == '' or _ajax.getAnchor().match /\/search\//
 | 
			
		||||
			_ajax.loadSearchPage();
 | 
			
		||||
		else if _ajax.getAnchor().match /\/settings\//
 | 
			
		||||
			_ajax.loadSettingsPage()
 | 
			
		||||
		else if _ajax.getAnchor().match /\/about\//
 | 
			
		||||
			_ajax.loadAboutPage()
 | 
			
		||||
		else
 | 
			
		||||
			_ajax.loadSearchPage()
 | 
			
		||||
		false
 | 
			
		||||
  detectPage: () ->
 | 
			
		||||
    if m = _ajax.getAnchor().match /\/artist\/(.+)\//
 | 
			
		||||
      _search.loadArtistData m[1]
 | 
			
		||||
    else if _ajax.getAnchor() == '' or _ajax.getAnchor().match /\/search\//
 | 
			
		||||
      _ajax.loadSearchPage();
 | 
			
		||||
    else if _ajax.getAnchor().match /\/settings\//
 | 
			
		||||
      _ajax.loadSettingsPage()
 | 
			
		||||
    else if _ajax.getAnchor().match /\/about\//
 | 
			
		||||
      _ajax.loadAboutPage()
 | 
			
		||||
    else
 | 
			
		||||
      #_ajax.loadSearchPage()
 | 
			
		||||
    false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$('a.data.artist').live 'click', ->
 | 
			
		||||
	_ajax.loadArtistData $(this).html()
 | 
			
		||||
	false
 | 
			
		||||
$(window).bind 'hashchange', ->
 | 
			
		||||
	_ajax.detectPage()
 | 
			
		||||
	false
 | 
			
		||||
  #_ajax.detectPage()
 | 
			
		||||
  false
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,12 @@
 | 
			
		||||
//= require jquery/jplayer/jquery.jplayer/jquery.jplayer
 | 
			
		||||
 | 
			
		||||
//= require locale
 | 
			
		||||
//= require vkontakte
 | 
			
		||||
//= require session
 | 
			
		||||
//= require vkontakte
 | 
			
		||||
//= require ajax
 | 
			
		||||
//= require player
 | 
			
		||||
//= require search
 | 
			
		||||
//= require pages
 | 
			
		||||
//= require page
 | 
			
		||||
//= require settings
 | 
			
		||||
 | 
			
		||||
//= require beathaven
 | 
			
		||||
@ -5,7 +5,7 @@ window._vkontakte = null
 | 
			
		||||
window._ajax = null
 | 
			
		||||
window._player = null
 | 
			
		||||
window._search = null
 | 
			
		||||
window._pages = null
 | 
			
		||||
window._page = null
 | 
			
		||||
window._settings = null
 | 
			
		||||
 | 
			
		||||
$ ->
 | 
			
		||||
@ -16,7 +16,7 @@ $ ->
 | 
			
		||||
	window._beathaven = new BeatHaven()
 | 
			
		||||
	window._beathaven.init()
 | 
			
		||||
 | 
			
		||||
class BeatHaven
 | 
			
		||||
class window.BeatHaven
 | 
			
		||||
	
 | 
			
		||||
	last_height: false
 | 
			
		||||
	lang: 'ru'
 | 
			
		||||
@ -32,7 +32,7 @@ class BeatHaven
 | 
			
		||||
		
 | 
			
		||||
		window._search = new Search()
 | 
			
		||||
		
 | 
			
		||||
		window._pages = new Pages()
 | 
			
		||||
		window._page = new Page()
 | 
			
		||||
		
 | 
			
		||||
		window._settings = new Settings()
 | 
			
		||||
		
 | 
			
		||||
@ -53,34 +53,7 @@ class BeatHaven
 | 
			
		||||
			containerId: 'autocomplete-container'
 | 
			
		||||
			containerItemsId: 'autocomplete-items'
 | 
			
		||||
			onSelect: ->
 | 
			
		||||
				_ajax.loadArtistData $('#search').first().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
 | 
			
		||||
				_search.loadArtistData $('#search').val()
 | 
			
		||||
	
 | 
			
		||||
	localizeHTML: (obj, lang) ->
 | 
			
		||||
		unless obj?
 | 
			
		||||
@ -102,15 +75,6 @@ class BeatHaven
 | 
			
		||||
			_locale[id][lang]
 | 
			
		||||
		else
 | 
			
		||||
			id
 | 
			
		||||
	
 | 
			
		||||
	pdShowSpinner: ->
 | 
			
		||||
		$('.pulldown').html '<div class="pd-spinner"><img src="/images/loader.gif" alt=""/></div>'
 | 
			
		||||
		false
 | 
			
		||||
	
 | 
			
		||||
	pdHideSpinner: ->
 | 
			
		||||
		$('.pulldown').html ''
 | 
			
		||||
		false
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
String::htmlsafe = ->
 | 
			
		||||
	replaces = [
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,8 @@
 | 
			
		||||
class window.Pages
 | 
			
		||||
class window.Page
 | 
			
		||||
  
 | 
			
		||||
  print: (html) ->
 | 
			
		||||
    $('#content').html(html)
 | 
			
		||||
    false
 | 
			
		||||
	
 | 
			
		||||
	renderArtist: (data) ->
 | 
			
		||||
		$('#content').html(data)
 | 
			
		||||
@ -1,15 +1,37 @@
 | 
			
		||||
class window.Search
 | 
			
		||||
  
 | 
			
		||||
  showSpinner: ->
 | 
			
		||||
    $('#search').val("").attr(disabled: 'disabled').blur()
 | 
			
		||||
    $('#search').attr(disabled: 'disabled').blur()
 | 
			
		||||
    $('#autocomplete-container').hide()
 | 
			
		||||
    $('#artist-load-spinner').show()
 | 
			
		||||
    this.hideSuggestions()
 | 
			
		||||
    false
 | 
			
		||||
  
 | 
			
		||||
  hideSpinner: ->
 | 
			
		||||
    $('#search').removeAttr 'disabled'
 | 
			
		||||
    $('.search_field').first().focus()
 | 
			
		||||
    $('.search-container img').first().hide()
 | 
			
		||||
    $('#search').val("").removeAttr 'disabled'
 | 
			
		||||
    $('#artist-load-spinner').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
 | 
			
		||||
  
 | 
			
		||||
  showSuggestions: (values) ->
 | 
			
		||||
@ -59,13 +81,10 @@ $('.search').live 'click', ->
 | 
			
		||||
      _beathaven.adjustSizes()
 | 
			
		||||
      _beathaven.redrawScrollbar()
 | 
			
		||||
  false
 | 
			
		||||
$('.search_form').live 'submit', ->
 | 
			
		||||
  $('.autocomplete-container').remove()
 | 
			
		||||
  _ajax.loadArtistData $('.search_field').first().val()
 | 
			
		||||
  false
 | 
			
		||||
$('.suggestions a').live 'click', ->
 | 
			
		||||
  $('.search_field').first().val $(this).text()
 | 
			
		||||
$('#search-form').live 'submit', ->
 | 
			
		||||
  $('#autocomplete-container').remove()
 | 
			
		||||
  _search.loadArtistData $('#search').val()
 | 
			
		||||
  false
 | 
			
		||||
$('.data.artist').live 'click', ->
 | 
			
		||||
  _ajax.go('/artist/'+$(this).text().replace(' ', '+')+'/');
 | 
			
		||||
  false;
 | 
			
		||||
  _search.loadArtistData $(this).html()
 | 
			
		||||
  false
 | 
			
		||||
@ -1,140 +1,140 @@
 | 
			
		||||
class window.Vkontakte
 | 
			
		||||
	
 | 
			
		||||
	qr: null
 | 
			
		||||
	api_id: null
 | 
			
		||||
	
 | 
			
		||||
	constructor: (@api_id) ->
 | 
			
		||||
	
 | 
			
		||||
	getApiId: ->
 | 
			
		||||
		@api_id
 | 
			
		||||
	
 | 
			
		||||
	init: ->
 | 
			
		||||
		@qr = []
 | 
			
		||||
		
 | 
			
		||||
		window.vkAsyncInit = ->
 | 
			
		||||
			VK.init apiId: _vkontakte.getApiId()
 | 
			
		||||
			VK.Auth.getLoginStatus (response) ->
 | 
			
		||||
				_vkontakte.authInfo(response)
 | 
			
		||||
  
 | 
			
		||||
  qr: null
 | 
			
		||||
  api_id: null
 | 
			
		||||
  
 | 
			
		||||
  constructor: (@api_id) ->
 | 
			
		||||
  
 | 
			
		||||
  getApiId: ->
 | 
			
		||||
    @api_id
 | 
			
		||||
  
 | 
			
		||||
  init: ->
 | 
			
		||||
    @qr = []
 | 
			
		||||
    
 | 
			
		||||
    window.vkAsyncInit = ->
 | 
			
		||||
      VK.init apiId: _vkontakte.getApiId()
 | 
			
		||||
      VK.Auth.getLoginStatus (response) ->
 | 
			
		||||
        _vkontakte.authInfo(response)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		setTimeout ->
 | 
			
		||||
			$('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>')
 | 
			
		||||
		, 0
 | 
			
		||||
	
 | 
			
		||||
	authInfo: (response) ->
 | 
			
		||||
		if typeof response isnt 'undefined' and response.session			
 | 
			
		||||
			_session = new Session(response.session)
 | 
			
		||||
    setTimeout ->
 | 
			
		||||
      $('#vk_api_transport').append('<script async="async" type="text/javascript" src="http://vkontakte.ru/js/api/openapi.js"></script>')
 | 
			
		||||
    , 0
 | 
			
		||||
  
 | 
			
		||||
  authInfo: (response) ->
 | 
			
		||||
    if typeof response isnt 'undefined' and response.session      
 | 
			
		||||
      _session = new Session(response.session)
 | 
			
		||||
 | 
			
		||||
			$('#vk_login, .auth-notice').hide()
 | 
			
		||||
				
 | 
			
		||||
			_session.query '/user/auth', {}, (ar) ->
 | 
			
		||||
				if ar.newbie
 | 
			
		||||
					VK.Api.call 'getVariable', key: 1281, (r) ->
 | 
			
		||||
						_session.query '/user/update', name: r.response, (ar2) ->
 | 
			
		||||
							_session.setUser ar2.user
 | 
			
		||||
							$('.header-container .hello .greating')
 | 
			
		||||
								.html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
 | 
			
		||||
							window._session = _session
 | 
			
		||||
							_ajax.detectPage()
 | 
			
		||||
							$('.fullscreen').hide();
 | 
			
		||||
				else
 | 
			
		||||
					_session.setUser ar.user
 | 
			
		||||
				
 | 
			
		||||
				$('.header-container .hello').show()
 | 
			
		||||
				$('.header-container .hello .greating')
 | 
			
		||||
					.html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
 | 
			
		||||
				window._session = _session
 | 
			
		||||
				_ajax.detectPage()
 | 
			
		||||
				$('.fullscreen').hide();
 | 
			
		||||
			
 | 
			
		||||
			if response.session.expire?
 | 
			
		||||
				setTimeout ->
 | 
			
		||||
					_vkontakte.auth()
 | 
			
		||||
					false
 | 
			
		||||
				, response.session.expire * 1000 - new Date().getTime() + 1000
 | 
			
		||||
		else
 | 
			
		||||
			_session = new Session({})
 | 
			
		||||
			_session.setUser {}
 | 
			
		||||
			$('#vk_login').css display: 'block'
 | 
			
		||||
			$('.auth-notice').css('left', $('#vk_login').offset().left).show()
 | 
			
		||||
			$('.header-container .hello').hide()
 | 
			
		||||
			window._session = _session
 | 
			
		||||
			_ajax.detectPage()
 | 
			
		||||
			$('.fullscreen').hide();
 | 
			
		||||
	
 | 
			
		||||
	auth: ->
 | 
			
		||||
		VK.Auth.getLoginStatus (response) ->
 | 
			
		||||
			_vkontakte.authInfo(response)
 | 
			
		||||
			false
 | 
			
		||||
		, 8
 | 
			
		||||
		false
 | 
			
		||||
	
 | 
			
		||||
	loadTracksData: (artist, track, duration, callback) ->
 | 
			
		||||
		track_prepared = track.replace(/\(.*\)/i, '').split('/')[0];
 | 
			
		||||
		query = artist+' '+track_prepared;
 | 
			
		||||
		if url = _vkontakte.getQR query
 | 
			
		||||
			callback url
 | 
			
		||||
		else
 | 
			
		||||
			VK.Api.call 'audio.search', q: query, (r) ->
 | 
			
		||||
				url = _vkontakte.matchPerfectResult r.response, artist, track, duration
 | 
			
		||||
				_vkontakte.addQR query, url
 | 
			
		||||
				callback url
 | 
			
		||||
	
 | 
			
		||||
	matchPerfectResult: (data, artist, track, duration) ->
 | 
			
		||||
		duration = duration.split ':'
 | 
			
		||||
		duration = parseInt(duration[0], 10) * 60 + parseInt(duration[1], 10)
 | 
			
		||||
		best_score = 0;
 | 
			
		||||
		best_result = null;
 | 
			
		||||
		for item in data
 | 
			
		||||
			if typeof item is 'object'
 | 
			
		||||
				score = 0;
 | 
			
		||||
				item.artist = item.artist.trim();
 | 
			
		||||
				item.title = item.title.trim();
 | 
			
		||||
			
 | 
			
		||||
				if item.artist == artist
 | 
			
		||||
					score += 10
 | 
			
		||||
				else if item.artist.split(artist).length is 2
 | 
			
		||||
					score += 5
 | 
			
		||||
				else if item.title.split(artist).length is 2
 | 
			
		||||
					score += 4
 | 
			
		||||
			
 | 
			
		||||
				if item.title == track
 | 
			
		||||
					score += 10
 | 
			
		||||
				else if item.title.split(track).length is 2
 | 
			
		||||
					score += 5
 | 
			
		||||
			
 | 
			
		||||
				if parseInt(item.duration, 10) == duration
 | 
			
		||||
					score += 15
 | 
			
		||||
				else
 | 
			
		||||
					delta = Math.abs parseInt(item.duration, 10) - duration
 | 
			
		||||
					score += (10 - delta) if delta < 10
 | 
			
		||||
			
 | 
			
		||||
				if score > best_score
 | 
			
		||||
					best_score = score
 | 
			
		||||
					best_result = item
 | 
			
		||||
			
 | 
			
		||||
				if score is 35
 | 
			
		||||
					return best_result.url
 | 
			
		||||
      $('#vk_login, .auth-notice').hide()
 | 
			
		||||
        
 | 
			
		||||
      _session.query '/user/auth', {}, (ar) ->
 | 
			
		||||
        if ar.newbie
 | 
			
		||||
          VK.Api.call 'getVariable', key: 1281, (r) ->
 | 
			
		||||
            _session.query '/user/update', name: r.response, (ar2) ->
 | 
			
		||||
              _session.setUser ar2.user
 | 
			
		||||
              $('.header-container .hello .greating')
 | 
			
		||||
                .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
 | 
			
		||||
              window._session = _session
 | 
			
		||||
              _ajax.detectPage()
 | 
			
		||||
              $('.fullscreen').hide();
 | 
			
		||||
        else
 | 
			
		||||
          _session.setUser ar.user
 | 
			
		||||
        
 | 
			
		||||
        $('.header-container .hello').show()
 | 
			
		||||
        $('.header-container .hello .greating')
 | 
			
		||||
          .html _beathaven.ls('HELLO')+', <span class="settings">' +(if _session.getUser().name then _session.getUser().name else '%username%')+ '</span>!'
 | 
			
		||||
        window._session = _session
 | 
			
		||||
        _ajax.detectPage()
 | 
			
		||||
        $('.fullscreen').hide();
 | 
			
		||||
      
 | 
			
		||||
      if response.session.expire?
 | 
			
		||||
        setTimeout ->
 | 
			
		||||
          _vkontakte.auth()
 | 
			
		||||
          false
 | 
			
		||||
        , response.session.expire * 1000 - new Date().getTime() + 1000
 | 
			
		||||
    else
 | 
			
		||||
      _session = new Session({})
 | 
			
		||||
      _session.setUser {}
 | 
			
		||||
      $('#vk_login').css display: 'block'
 | 
			
		||||
      $('.auth-notice').css('left', $('#vk_login').offset().left).show()
 | 
			
		||||
      $('.header-container .hello').hide()
 | 
			
		||||
      window._session = _session
 | 
			
		||||
      _ajax.detectPage()
 | 
			
		||||
      $('.fullscreen').hide();
 | 
			
		||||
  
 | 
			
		||||
  auth: ->
 | 
			
		||||
    VK.Auth.getLoginStatus (response) ->
 | 
			
		||||
      _vkontakte.authInfo(response)
 | 
			
		||||
      false
 | 
			
		||||
    , 8
 | 
			
		||||
    false
 | 
			
		||||
  
 | 
			
		||||
  loadTracksData: (artist, track, duration, callback) ->
 | 
			
		||||
    track_prepared = track.replace(/\(.*\)/i, '').split('/')[0];
 | 
			
		||||
    query = artist+' '+track_prepared;
 | 
			
		||||
    if url = _vkontakte.getQR query
 | 
			
		||||
      callback url
 | 
			
		||||
    else
 | 
			
		||||
      VK.Api.call 'audio.search', q: query, (r) ->
 | 
			
		||||
        url = _vkontakte.matchPerfectResult r.response, artist, track, duration
 | 
			
		||||
        _vkontakte.addQR query, url
 | 
			
		||||
        callback url
 | 
			
		||||
  
 | 
			
		||||
  matchPerfectResult: (data, artist, track, duration) ->
 | 
			
		||||
    duration = duration.split ':'
 | 
			
		||||
    duration = parseInt(duration[0], 10) * 60 + parseInt(duration[1], 10)
 | 
			
		||||
    best_score = 0;
 | 
			
		||||
    best_result = null;
 | 
			
		||||
    for item in data
 | 
			
		||||
      if typeof item is 'object'
 | 
			
		||||
        score = 0;
 | 
			
		||||
        item.artist = item.artist.trim();
 | 
			
		||||
        item.title = item.title.trim();
 | 
			
		||||
      
 | 
			
		||||
        if item.artist == artist
 | 
			
		||||
          score += 10
 | 
			
		||||
        else if item.artist.split(artist).length is 2
 | 
			
		||||
          score += 5
 | 
			
		||||
        else if item.title.split(artist).length is 2
 | 
			
		||||
          score += 4
 | 
			
		||||
      
 | 
			
		||||
        if item.title == track
 | 
			
		||||
          score += 10
 | 
			
		||||
        else if item.title.split(track).length is 2
 | 
			
		||||
          score += 5
 | 
			
		||||
      
 | 
			
		||||
        if parseInt(item.duration, 10) == duration
 | 
			
		||||
          score += 15
 | 
			
		||||
        else
 | 
			
		||||
          delta = Math.abs parseInt(item.duration, 10) - duration
 | 
			
		||||
          score += (10 - delta) if delta < 10
 | 
			
		||||
      
 | 
			
		||||
        if score > best_score
 | 
			
		||||
          best_score = score
 | 
			
		||||
          best_result = item
 | 
			
		||||
      
 | 
			
		||||
        if score is 35
 | 
			
		||||
          return best_result.url
 | 
			
		||||
 | 
			
		||||
		return best_result.url
 | 
			
		||||
	
 | 
			
		||||
	addQR: (query, url) ->
 | 
			
		||||
		@qr[query] = url;
 | 
			
		||||
	
 | 
			
		||||
	getQR: (query) ->
 | 
			
		||||
		if @qr[query]?
 | 
			
		||||
			@qr[query]
 | 
			
		||||
		false
 | 
			
		||||
    return best_result.url
 | 
			
		||||
  
 | 
			
		||||
  addQR: (query, url) ->
 | 
			
		||||
    @qr[query] = url;
 | 
			
		||||
  
 | 
			
		||||
  getQR: (query) ->
 | 
			
		||||
    if @qr[query]?
 | 
			
		||||
      @qr[query]
 | 
			
		||||
    false
 | 
			
		||||
 | 
			
		||||
$('#vk_login, .auth-notice').live 'click', ->
 | 
			
		||||
	VK.Auth.login (response) ->
 | 
			
		||||
		_vkontakte.authInfo(response)
 | 
			
		||||
		false
 | 
			
		||||
	, 8
 | 
			
		||||
	false
 | 
			
		||||
  VK.Auth.login (response) ->
 | 
			
		||||
    _vkontakte.authInfo(response)
 | 
			
		||||
    false
 | 
			
		||||
  , 8
 | 
			
		||||
  false
 | 
			
		||||
$('#vk_logout').live 'click', ->
 | 
			
		||||
	_ajax.go '/search/';
 | 
			
		||||
	VK.Auth.logout (response) ->
 | 
			
		||||
		_vkontakte.authInfo(response)
 | 
			
		||||
		false
 | 
			
		||||
	false
 | 
			
		||||
  _ajax.go '/search/';
 | 
			
		||||
  VK.Auth.logout (response) ->
 | 
			
		||||
    _vkontakte.authInfo(response)
 | 
			
		||||
    false
 | 
			
		||||
  false
 | 
			
		||||
 | 
			
		||||
@ -15,9 +15,4 @@
 | 
			
		||||
    left: 50%;
 | 
			
		||||
    margin: -32px 0 0 -32px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.artist-loader {
 | 
			
		||||
  float: right;
 | 
			
		||||
  margin: -26px 0 0 10px;
 | 
			
		||||
}
 | 
			
		||||
@ -18,4 +18,14 @@
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#artist-load-spinner {
 | 
			
		||||
  display: none;
 | 
			
		||||
  float: right;
 | 
			
		||||
  margin: -26px 0 0 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.suggestions a {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
@ -3,82 +3,114 @@ require 'open-uri'
 | 
			
		||||
class ArtistController < ApplicationController
 | 
			
		||||
  @@default_album_types = ['Album', 'Soundtrack']
 | 
			
		||||
  def data
 | 
			
		||||
    data = {}
 | 
			
		||||
    @data = {
 | 
			
		||||
      :status => '',
 | 
			
		||||
      :correct_name => '',
 | 
			
		||||
      :html => ''
 | 
			
		||||
    }
 | 
			
		||||
    @loading = false
 | 
			
		||||
    
 | 
			
		||||
    # Bad params
 | 
			
		||||
    if params[:name].nil? or params[:name].length == 0
 | 
			
		||||
      render :json => {status: 'loading_failed', pics: []}
 | 
			
		||||
      @data[:status] = 'loading_failed';
 | 
			
		||||
      render :json => @data
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    # Searching for artist
 | 
			
		||||
    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
 | 
			
		||||
    @artist = Artist.find_by_name(name)
 | 
			
		||||
    
 | 
			
		||||
    # Artist not found
 | 
			
		||||
    unless @artist
 | 
			
		||||
      results = ArtistController.musicBrainzExactSearch(name)
 | 
			
		||||
      if results.empty?
 | 
			
		||||
        render :json => {status: 'not found'}
 | 
			
		||||
        return
 | 
			
		||||
        @data[:status] = 'not_found'
 | 
			
		||||
        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
 | 
			
		||||
        # Saving artist and queueing job
 | 
			
		||||
        artist = Artist.new
 | 
			
		||||
        artist.name = name
 | 
			
		||||
        artist.status = 0
 | 
			
		||||
        artist.save
 | 
			
		||||
        @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
 | 
			
		||||
        # Rendering loading info
 | 
			
		||||
        @artist = { :artist => @artist, :albums => [] }
 | 
			
		||||
        @loading = true
 | 
			
		||||
        @data[:status] = 'loading'
 | 
			
		||||
        @data[:html] = (render_to_string :partial => 'page').gsub(/\n\s+/, '').gsub(/\n/, '')
 | 
			
		||||
        render :json => @data
 | 
			
		||||
      else
 | 
			
		||||
        render :json => {status: 'suggestions', values: results.take(5)}
 | 
			
		||||
        return
 | 
			
		||||
        @suggestions = results.take(5)
 | 
			
		||||
        @data[:status] = 'suggestions'
 | 
			
		||||
        @data[:html] = (render_to_string :partial => 'suggestions').gsub(/\n\s+/, '').gsub(/\n/, '')
 | 
			
		||||
        render :json => @data
 | 
			
		||||
      end
 | 
			
		||||
      return
 | 
			
		||||
    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 @artist and @artist.status == 2
 | 
			
		||||
      @data[:status] = 'fail'
 | 
			
		||||
      @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
 | 
			
		||||
        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
 | 
			
		||||
          tmp_track[:duration] = formatTrackDuration(track.length)
 | 
			
		||||
          (track.bonus == 0 ? album_tracks : bonus_tracks) << tmp_track
 | 
			
		||||
        end
 | 
			
		||||
        tmp_album[:tracks] = {album: album_tracks, bonus: bonus_tracks}
 | 
			
		||||
        data[:albums] << tmp_album
 | 
			
		||||
        @artist[:albums] << tmp_album
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    @data = data
 | 
			
		||||
    respond_to do |format|
 | 
			
		||||
      format.html { render :partial => 'data' }
 | 
			
		||||
      format.json { render :json => @data }
 | 
			
		||||
    
 | 
			
		||||
    (render_to_string :partial => 'page').gsub(/\n\s+/, '').gsub(/\n/, '')
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  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
 | 
			
		||||
  
 | 
			
		||||
  def autocomplete
 | 
			
		||||
  	autocomplete = ArtistController.getLastFmAutocomplete(params[:query])
 | 
			
		||||
  	autocomplete = getLastFmAutocomplete(params[:query])
 | 
			
		||||
  	return	render :nothing => true if autocomplete.nil?
 | 
			
		||||
  	suggestions = []
 | 
			
		||||
    autocomplete["response"]["docs"].each do |doc|
 | 
			
		||||
@ -90,16 +122,16 @@ class ArtistController < ApplicationController
 | 
			
		||||
		}
 | 
			
		||||
	end
 | 
			
		||||
	
 | 
			
		||||
	def self.getLastFmAutocomplete query
 | 
			
		||||
	def 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
 | 
			
		||||
    json.empty? ? nil : json
 | 
			
		||||
	end
 | 
			
		||||
	
 | 
			
		||||
	def self.musicBrainzSearch(query)
 | 
			
		||||
	def 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 = []
 | 
			
		||||
@ -108,7 +140,7 @@ class ArtistController < ApplicationController
 | 
			
		||||
	    end
 | 
			
		||||
	    artists.take(10)
 | 
			
		||||
	  rescue
 | 
			
		||||
	    return {}
 | 
			
		||||
	    {}
 | 
			
		||||
	  end
 | 
			
		||||
	end
 | 
			
		||||
	
 | 
			
		||||
@ -140,7 +172,7 @@ class ArtistController < ApplicationController
 | 
			
		||||
	    artists.sort! { |a, b| b[:weight] <=> a[:weight] }
 | 
			
		||||
	    artists.take(10)
 | 
			
		||||
	  rescue
 | 
			
		||||
	    return {}
 | 
			
		||||
	    {}
 | 
			
		||||
	  end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
@ -18,9 +18,8 @@ class ImportController < ApplicationController
 | 
			
		||||
    lastfm = Lastfm.new(@@lastfm_api_key, @@lastfm_secret)
 | 
			
		||||
    
 | 
			
		||||
    artist = Artist.find_or_create_by_name(name)
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
    
 | 
			
		||||
    begin
 | 
			
		||||
      # Get artist info
 | 
			
		||||
      artist_mb_data = ArtistController.musicBrainzExactSearch(name).first
 | 
			
		||||
      begin
 | 
			
		||||
@ -30,13 +29,16 @@ class ImportController < ApplicationController
 | 
			
		||||
        ap e.message
 | 
			
		||||
        ap e.backtrace
 | 
			
		||||
      end
 | 
			
		||||
    
 | 
			
		||||
  
 | 
			
		||||
      # Save artist
 | 
			
		||||
      artist.desc = artist_lastfm['bio']['summary']
 | 
			
		||||
      artist.pic_url = artist_lastfm['image'][3]['content']
 | 
			
		||||
      artist.artist_type = artist_mb['artist']['type']
 | 
			
		||||
      artist.mbid = artist_mb_data[:mbid]
 | 
			
		||||
    
 | 
			
		||||
      artist.save! unless dry_run
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    begin
 | 
			
		||||
      # Get albums from MB
 | 
			
		||||
      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|
 | 
			
		||||
                    unless ['[silence]', '[untitled]'].include? mb_track['recording']['title']
 | 
			
		||||
                      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.position = mb_track['position']
 | 
			
		||||
                      track.length = mb_track['length'] unless mb_track['length'].nil?
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								app/views/artist/_fail.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/artist/_fail.html.haml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
.alert-message.error
 | 
			
		||||
  %p Something very bad happened, sorry :(
 | 
			
		||||
@ -1,11 +1,15 @@
 | 
			
		||||
- if @loading
 | 
			
		||||
  .alert-message.warning
 | 
			
		||||
    %p Artist info is loading for the first time. Please, be patient! :)
 | 
			
		||||
.row.artist-info
 | 
			
		||||
  .span4.columns.pic
 | 
			
		||||
    %img{ :src => @data[:artist][:pic] }
 | 
			
		||||
    = image_tag @artist[:artist][:pic] unless @artist[:artist][:pic].nil?
 | 
			
		||||
  .span7.columns.desc
 | 
			
		||||
    %h2= @data[:artist][:name]
 | 
			
		||||
    = @data[:artist][:desc]
 | 
			
		||||
    %h2= @artist[:artist][:name]
 | 
			
		||||
    = @artist[:artist][:desc] unless @artist[:artist][:desc].nil?
 | 
			
		||||
 | 
			
		||||
- @data[:albums].each do |album|
 | 
			
		||||
 | 
			
		||||
- @artist[:albums].each do |album|
 | 
			
		||||
  .row.album
 | 
			
		||||
    .span4.columns.art
 | 
			
		||||
      %img{ :src => album[:pic] }
 | 
			
		||||
@ -17,4 +21,4 @@
 | 
			
		||||
        - album[:tracks][:album].each do |track|
 | 
			
		||||
          %tr
 | 
			
		||||
            %td.song-title= track[:name]
 | 
			
		||||
            %td.song-duration= track[:duration]
 | 
			
		||||
            %td.song-duration= track[:duration]
 | 
			
		||||
							
								
								
									
										12
									
								
								app/views/artist/_suggestions.html.haml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/views/artist/_suggestions.html.haml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
.alert-message.warning
 | 
			
		||||
  %p Made a typo?
 | 
			
		||||
 | 
			
		||||
%ul.suggestions
 | 
			
		||||
  - @suggestions.each do |artist|
 | 
			
		||||
    %li
 | 
			
		||||
      %a.data.artist= artist[:name]
 | 
			
		||||
       (
 | 
			
		||||
      = artist[:type]
 | 
			
		||||
      )
 | 
			
		||||
      %br
 | 
			
		||||
      %p= artist[:desc]
 | 
			
		||||
@ -21,9 +21,9 @@
 | 
			
		||||
                %a{ :href => "http://blog.beathaven.org/", :"data-ls" => "NEWS" } Blog
 | 
			
		||||
              %li
 | 
			
		||||
                %a.about{ :href => "#/about/" } About 
 | 
			
		||||
            %form{ :action => "" }
 | 
			
		||||
            %form#search-form{ :action => "" }
 | 
			
		||||
              %input#search{ :type => "text", :placeholder => "Search" }
 | 
			
		||||
              .artist-loader
 | 
			
		||||
              #artist-load-spinner
 | 
			
		||||
                = image_tag "artist_loader.gif"
 | 
			
		||||
            %ul.nav.secondary-nav
 | 
			
		||||
              %li.dropdown
 | 
			
		||||
@ -86,9 +86,3 @@
 | 
			
		||||
        = image_tag "loader.gif"
 | 
			
		||||
    
 | 
			
		||||
    #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 -->
 | 
			
		||||
    
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user