1
0
Fork 0

Search works so-so. Done for now. Close #45, close #56

This commit is contained in:
magnolia-fan 2011-06-18 05:09:07 +04:00
parent 24ca64a945
commit c9ea9c6a27
10 changed files with 167 additions and 79 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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);
}) })

View File

@ -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;
});
});

View File

@ -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;

View File

@ -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;
}