parent
24ca64a945
commit
c9ea9c6a27
|
@ -1,4 +1,3 @@
|
||||||
require 'uri'
|
|
||||||
require 'open-uri'
|
require 'open-uri'
|
||||||
|
|
||||||
class ArtistController < ApplicationController
|
class ArtistController < ApplicationController
|
||||||
|
@ -8,15 +7,15 @@ class ArtistController < ApplicationController
|
||||||
artist = Artist.find_by_name(name)
|
artist = Artist.find_by_name(name)
|
||||||
unless artist
|
unless artist
|
||||||
results = ArtistController.musicBrainzSearch(name)
|
results = ArtistController.musicBrainzSearch(name)
|
||||||
if results[0].downcase == name.downcase and results[0] != name
|
if results[0] == name
|
||||||
render :json => {correct: results[0]}
|
|
||||||
return
|
|
||||||
elsif results[0] == name
|
|
||||||
ImportController.importArtist(name)
|
ImportController.importArtist(name)
|
||||||
render :json => {status: 'loading'}
|
render :json => {status: 'loaded'}
|
||||||
|
return
|
||||||
|
elsif (results[0].downcase == name.downcase or results[0].downcase == 'the '+ name.downcase) and results[0] != name
|
||||||
|
render :json => {status: 'corrected', page: results[0]}
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
render :json => {suggestions: results}
|
render :json => {status: 'suggestions', values: results}
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -71,12 +70,12 @@ class ArtistController < ApplicationController
|
||||||
|
|
||||||
def self.musicBrainzSearch(query)
|
def self.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') +'~').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 = []
|
||||||
response['artist-list']['artist'].each do |artist|
|
response['artist-list']['artist'].each do |artist|
|
||||||
artists << artist['name']
|
artists << artist['name'] unless artist['type'] == 'unknown'
|
||||||
end
|
end
|
||||||
return artists
|
artists.take(10)
|
||||||
rescue
|
rescue
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,21 +5,28 @@ class ImportController < ApplicationController
|
||||||
|
|
||||||
# Get artist info
|
# Get artist info
|
||||||
artist_mb_xml = open(
|
artist_mb_xml = open(
|
||||||
'http://musicbrainz.org/ws/2/artist/?query='+ URI.escape(name).gsub(/\&/, '%26').gsub(/\?/, '%3F') +'&limit=1',
|
'http://musicbrainz.org/ws/2/artist/?query='+ URI.escape(name).gsub(/\&/, '%26').gsub(/\?/, '%3F') +'&limit=5',
|
||||||
'User-Agent' => @@user_agent
|
'User-Agent' => @@user_agent
|
||||||
).read
|
).read
|
||||||
artist_mb_data = artist_mb_xml.scan(/<artist.*?type=\"(.+?)\"\sid=\"([a-f0-9-]+?)\">.*?<name>(.+?)<\/name>/m)
|
artist_mb_data = artist_mb_xml.scan(/<artist.*?type=\"(.+?)\"\sid=\"([a-f0-9-]+?)\">.*?<name>(.+?)<\/name>/m)
|
||||||
|
begin
|
||||||
artist_lastfm_xml = open(
|
artist_lastfm_xml = open(
|
||||||
'http://ws.audioscrobbler.com/2.0/'+
|
'http://ws.audioscrobbler.com/2.0/'+
|
||||||
'?method=artist.getinfo&api_key='+ @@lastfm_api_key +
|
'?method=artist.getinfo&api_key='+ @@lastfm_api_key +
|
||||||
'&artist='+ URI.escape(name).gsub(/\&/, '%26').gsub(/\?/, '%3F')
|
'&artist='+ URI.escape(name).gsub(/\&/, '%26').gsub(/\?/, '%3F')
|
||||||
).read
|
).read
|
||||||
|
artist_desc = artist_lastfm_xml.scan(/<summary><\!\[CDATA\[?(.*)\]\]><\/summary>/m)[0][0]
|
||||||
|
artist_pic = artist_lastfm_xml.scan(/<image\ssize=\"extralarge\">?(.*)<\/image>/)[0][0]
|
||||||
|
rescue
|
||||||
|
artist_desc = ''
|
||||||
|
artist_pic = ''
|
||||||
|
end
|
||||||
|
|
||||||
# Save artist
|
# Save artist
|
||||||
artist = Artist.new
|
artist = Artist.new
|
||||||
artist.name = artist_mb_data[0][2]
|
artist.name = artist_mb_data[0][2]
|
||||||
artist.desc = artist_lastfm_xml.scan(/<summary><\!\[CDATA\[?(.*)\]\]><\/summary>/m)[0][0]
|
artist.desc = artist_desc
|
||||||
artist.pic_url = artist_lastfm_xml.scan(/<image\ssize=\"extralarge\">?(.*)<\/image>/)[0][0]
|
artist.pic_url = artist_pic
|
||||||
artist.artist_type = artist_mb_data[0][0]
|
artist.artist_type = artist_mb_data[0][0]
|
||||||
artist.mbid = artist_mb_data[0][1]
|
artist.mbid = artist_mb_data[0][1]
|
||||||
artist.save
|
artist.save
|
||||||
|
@ -42,6 +49,8 @@ class ImportController < ApplicationController
|
||||||
releases_mb_data.each do |item|
|
releases_mb_data.each do |item|
|
||||||
if item[2].length == 4
|
if item[2].length == 4
|
||||||
item[2] += '-01-01'
|
item[2] += '-01-01'
|
||||||
|
elsif item[2].length == 7
|
||||||
|
item[2] += '-01'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,5 @@ Beathaven::Application.routes.draw do
|
||||||
# match ':controller(/:action(/:id(.:format)))'
|
# match ':controller(/:action(/:id(.:format)))'
|
||||||
|
|
||||||
match 'artist/autocomplete' => 'artist#autocomplete'
|
match 'artist/autocomplete' => 'artist#autocomplete'
|
||||||
match 'artist/search' => 'artist#search'
|
|
||||||
match 'artist/(:name)/' => 'artist#data', :constraints => { :name => /[^\/]*/ }
|
match 'artist/(:name)/' => 'artist#data', :constraints => { :name => /[^\/]*/ }
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'open-uri'
|
||||||
namespace :db do
|
namespace :db do
|
||||||
desc 'Imports test data from MusicBrainz database'
|
desc 'Imports test data from MusicBrainz database'
|
||||||
task :import => :environment do
|
task :import => :environment do
|
||||||
ati = ['Jet']
|
ati = ['The White Stripes']
|
||||||
ati.each do |name|
|
ati.each do |name|
|
||||||
ImportController.importArtist(name)
|
ImportController.importArtist(name)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<title>BetaHaven</title>
|
<title>BetaHaven</title>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/layout.css" />
|
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/layout.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/search.css" />
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/misc.css" />
|
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/misc.css" />
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/player.css" />
|
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/player.css" />
|
||||||
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/albums.css" />
|
<link rel="stylesheet" type="text/css" media="screen" href="/stylesheets/albums.css" />
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/jquery/jquery.contentchange.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/jquery/jquery.contentchange.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/layout.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/layout.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/ajax.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/ajax.js"></script>
|
||||||
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/search.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/pages.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/pages.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/audio.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/audio.js"></script>
|
||||||
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/player.js"></script>
|
<script type="text/javascript" charset="utf-8" src="/javascripts/beathaven/player.js"></script>
|
||||||
|
|
|
@ -4,4 +4,19 @@
|
||||||
<input type="submit" value="Search" id="search_button"/>
|
<input type="submit" value="Search" id="search_button"/>
|
||||||
</form>
|
</form>
|
||||||
<img src="/images/loader.gif" alt="" />
|
<img src="/images/loader.gif" alt="" />
|
||||||
|
<div class="suggestions">
|
||||||
|
<div>Misspelled?</div>
|
||||||
|
<ul>
|
||||||
|
<li><a class="data artist">The Raconters</a></li>
|
||||||
|
<li>The Raconteurs</li>
|
||||||
|
<li>The Encounters</li>
|
||||||
|
<li>Encounters</li>
|
||||||
|
<li>The Encounter</li>
|
||||||
|
<li>Carpenters</li>
|
||||||
|
<li>The Dearhunters</li>
|
||||||
|
<li>Jamhunters</li>
|
||||||
|
<li>The Go Go Haunters</li>
|
||||||
|
<li>The Beathunters</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,20 +1,25 @@
|
||||||
var Ajax = {
|
var Ajax = {
|
||||||
loadArtistData: function(name) {
|
loadArtistData: function(name) {
|
||||||
$('#search-container input').attr('disabled', 'disabled').blur();
|
Search.showSpinner();
|
||||||
$('#search-container img').show();
|
|
||||||
name = name.split(' ').join('+');
|
name = name.split(' ').join('+');
|
||||||
Ajax.setArchor('/artist/'+ name +'/');
|
|
||||||
$.get('/artist/'+ name +'/', function(data){
|
$.get('/artist/'+ name +'/', function(data){
|
||||||
if (typeof data.error != 'undefined') {
|
if (typeof data.status != 'undefined') {
|
||||||
if (data.error == 'loading') {
|
if (data.status == 'loaded') {
|
||||||
Ajax.loadArtistData(name);
|
Ajax.loadArtistData(name);
|
||||||
} else if (data.error == 404) {
|
} else if (data.status == 'corrected') {
|
||||||
|
Ajax.loadArtistData(data.page);
|
||||||
|
} else if (data.status == 'suggestions') {
|
||||||
|
Search.hideSpinner();
|
||||||
|
Search.showSuggestions(data.values);
|
||||||
|
} else if (data.status == 'error') {
|
||||||
Ajax.load404Page();
|
Ajax.load404Page();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
|
Ajax.setArchor('/artist/'+ name +'/');
|
||||||
Pages.renderArtist(data);
|
Pages.renderArtist(data);
|
||||||
beathaven.redrawScrollbar();
|
beathaven.redrawScrollbar();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -75,14 +80,5 @@ $(function(){
|
||||||
Ajax.loadArtistData($(this).html());
|
Ajax.loadArtistData($(this).html());
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$('.search').live('click', function(){
|
|
||||||
Ajax.loadSearchPage();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
$('#search_form').live('submit', function(){
|
|
||||||
$('.autocomplete-container').remove();
|
|
||||||
Ajax.loadArtistData($('#search_field').val());
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
$(window).bind('hashchange', Ajax.detectPage);
|
$(window).bind('hashchange', Ajax.detectPage);
|
||||||
})
|
})
|
|
@ -0,0 +1,46 @@
|
||||||
|
var Search = {
|
||||||
|
|
||||||
|
showSpinner: function() {
|
||||||
|
$('#search-container input').attr('disabled', 'disabled').blur();
|
||||||
|
$('#search-container img').show();
|
||||||
|
Search.hideSuggestions();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideSpinner: function() {
|
||||||
|
$('#search-container input').removeAttr('disabled');
|
||||||
|
$('#search_field').focus();
|
||||||
|
$('#search-container img').hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
showSuggestions: function(values) {
|
||||||
|
for (var i = 0; i < values.length; i++) {
|
||||||
|
$('.suggestions ul').append('\
|
||||||
|
<li>\
|
||||||
|
<a class="data artist">'+ values[i] +'</a>\
|
||||||
|
</li>\
|
||||||
|
');
|
||||||
|
}
|
||||||
|
$('.suggestions').show();
|
||||||
|
},
|
||||||
|
|
||||||
|
hideSuggestions: function() {
|
||||||
|
$('.suggestions ul li').remove();
|
||||||
|
$('.suggestions').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$('.search').live('click', function(){
|
||||||
|
Ajax.loadSearchPage();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$('#search_form').live('submit', function(){
|
||||||
|
$('.autocomplete-container').remove();
|
||||||
|
Ajax.loadArtistData($('#search_field').val());
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$('.suggestions a').live('click', function(){
|
||||||
|
$('#search_field').val($(this).text());
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
|
@ -79,48 +79,6 @@
|
||||||
background: #AAA;
|
background: #AAA;
|
||||||
}
|
}
|
||||||
|
|
||||||
#search-container {
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
#search-container #search_field {
|
|
||||||
width: 300px;
|
|
||||||
font-size: 24px;
|
|
||||||
padding: 4px;
|
|
||||||
border: #CCC 1px solid;
|
|
||||||
-webkit-border-radius: 3px;
|
|
||||||
-moz-border-radius: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
#search-container #search_button {
|
|
||||||
width: 100px;
|
|
||||||
font-size: 24px;
|
|
||||||
padding: 4px;
|
|
||||||
background-color: #DDD;
|
|
||||||
border: #CCC 1px solid;
|
|
||||||
-webkit-border-radius: 3px;
|
|
||||||
-moz-border-radius: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
#search-container img {
|
|
||||||
margin-top: 30px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autocomplete {
|
|
||||||
margin: 4px 0 0 -1px;
|
|
||||||
}
|
|
||||||
.autocomplete div {
|
|
||||||
font-size: 24px;
|
|
||||||
padding: 6px 5px;
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
margin-bottom: 1px;
|
|
||||||
}
|
|
||||||
.autocomplete div.selected {
|
|
||||||
background-color: #EAEAEA;
|
|
||||||
}
|
|
||||||
|
|
||||||
#error_page {
|
#error_page {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 600px;
|
width: 600px;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#search-container {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
#search-container #search_field {
|
||||||
|
width: 300px;
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 4px;
|
||||||
|
border: #CCC 1px solid;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
#search-container #search_button {
|
||||||
|
width: 100px;
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 4px;
|
||||||
|
background-color: #DDD;
|
||||||
|
border: #CCC 1px solid;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
#search-container img {
|
||||||
|
margin-top: 30px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete {
|
||||||
|
margin: 4px 0 0 -1px;
|
||||||
|
}
|
||||||
|
.autocomplete div {
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 6px 5px;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
.autocomplete div.selected {
|
||||||
|
background-color: #EAEAEA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.suggestions {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin: 30px 0 0 -380px;
|
||||||
|
width: 400px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.suggestions div {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.suggestions ul li {
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.suggestions .data.artist {
|
||||||
|
color: #04F;
|
||||||
|
border-bottom: #04F 1px dotted;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
Loading…
Reference in New Issue