vrfs-774: impl musician searches

This commit is contained in:
Jonathan Kolyer 2013-10-28 21:42:36 -05:00
parent dd5be13e9f
commit e1bce5eed8
6 changed files with 74 additions and 47 deletions

View File

@ -6,7 +6,6 @@
var logger = context.JK.logger;
var musicians = {};
var musicianCounts = [0, 0, 0];
var musicianList;
function removeSpinner() {
@ -26,7 +25,7 @@
$.ajax({
type: "GET",
url: "/api/musicians?" + queryString,
url: "/api/users?" + queryString,
async: true,
success: afterLoadMusicians,
complete: removeSpinner,
@ -37,21 +36,34 @@
function search() {
logger.debug("Searching for musicians...");
clearResults();
var queryString = '';
var queryString = 'musicians=1&';
// instrument filter
var instruments = context.JK.InstrumentSelectorHelper.getSelectedInstruments('#find-musician-instrument');
if (instruments !== null && instruments.length > 0) {
queryString += "instruments=" + instruments.join(',');
// order by
var orderby = $('.musician-order-by').val();
if (orderby !== null && orderby.length() > 0) {
queryString += "orderby=" + orderby + '&';
}
// keyword filter
var keyword = $('#musician-keyword-srch').val();
if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') {
if (queryString.length > 0) {
queryString += "&";
}
queryString += "keyword=" + $('#musician-keyword-srch').val();
// instrument filter
var instrument = $('.instrument-list').val();
if (instruments !== null && instruments.length() > 0) {
queryString += "instrument=" + instrument;
}
// distance filter
var query_param = $('#musician-query-distance').val();
if (query_param !== null && query_param.length > 0) {
var matches = query_param.match(/(\d)/);
if (0 < matches.length()) {
var distance = matches[0];
query_param = $('#musician-query-center').val();
if (query_param !== null && query_param.length > 0) {
matches = query_param.match(/\\d{5}(-\\d{4})?/);
if (0 < matches.length()) {
var zip = matches[0];
queryString += "zip=" + query_param + '&';
queryString += "distance=" + query_param + '&';
}
}
}
}
loadMusicians(queryString);
}

View File

@ -55,3 +55,21 @@
font-size: 90%;
}
.query-distance-params {
float:left;
width:140px;
margin-left: 10px;
-webkit-border-radius: 6px;
border-radius: 6px;
background-color:$ColorTextBoxBackground;
border: none;
color:#333;
font-weight:400;
padding:0px 0px 0px 8px;
height:18px;
line-height:18px;
overflow:hidden;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
}

View File

@ -14,8 +14,15 @@ class ApiUsersController < ApiController
respond_to :json
def index
@users = User.paginate(page: params[:page])
respond_with @users, responder: ApiResponder, :status => 200
if 1 == params[:musicians].to_i
query = params.clone
query[:remote_ip] = request.remote_ip
@users = User.musician_search(query, current_user)
respond_with @users, responder: ApiResponder, :status => 200
else
@users = User.paginate(page: params[:page])
respond_with @users, responder: ApiResponder, :status => 200
end
end
def show

View File

@ -1,3 +0,0 @@
<select class="instrument-list" name="instruments">
<option value="">Select Instrument</option>
</select>

View File

@ -1,18 +1,20 @@
<div style="min-width:770px;">
<div class="left ml35" style="padding-top:3px;">Filter Musician List:</div>
<select class="musician_filter_by" name="musician_filter_by">
<option value="">Most Liked</option>
<option value="">Most Followed</option>
<option value="">Playing Now</option>
</select>
<!-- order by filter -->
<%= select_tag(:musician_order_by, options_for_select(Search::ORDERINGS), {:class => 'musician-order-by'} ) %>
<!-- instrument filter -->
<div id="find-musician-instrument" class="left ml10">
<%= render "instrumentSelector" %>
<div id="find-musician-instrument" class="right ml10">
<%= select_tag(:instrument,
options_for_select(['Select Instrument', ''].concat(JamRuby::Instrument.all.collect { |ii| [ii.description, ii.id] })),
{:class => 'instrument-list'} ) %>
</div>
<!-- keyword filter -->
<div class="search-box" style="height:25px;">
<input id="musician-keyword-srch" type="text" name="search" placeholder="Search by Keyword" />
<!-- distance filter -->
<div class="query-distance-params" style="height:25px;">
Within
<input id="musician-query-distance" type="text" name="query-distance" placeholder="100" />
miles of
<input id="musician-query-zip" type="text" name="query-zip" placeholder="zip" />
</div>
<div class="right mr10">
<a id="btn-refresh" href="#/findMusician" style="text-decoration:none;" class="button-grey">REFRESH</a>

View File

@ -14,8 +14,7 @@ class MaxMindManager < BaseManager
unless ip_address.nil? || ip_address !~ /^\d+\.\d+\.\d+\.\d+$/
ActiveRecord::Base.connection_pool.with_connection do |connection|
pg_conn = connection.instance_variable_get("@connection")
ip_as_int = ip_address_to_int(ip_address)
pg_conn.exec("SELECT country, region, city FROM max_mind_geo WHERE ip_bottom <= $1 AND ip_top >= $2", [ip_as_int, ip_as_int]) do |result|
pg_conn.exec("SELECT country, region, city FROM max_mind_geo WHERE ip_start <= $1 AND ip_end >= $2", [ip_address, ip_address]) do |result|
if !result.nil? && result.ntuples > 0
country = result.getvalue(0, 0)
state = result[0]['region']
@ -40,8 +39,7 @@ class MaxMindManager < BaseManager
unless ip_address.nil? || ip_address !~ /^\d+\.\d+\.\d+\.\d+$/
ActiveRecord::Base.connection_pool.with_connection do |connection|
pg_conn = connection.instance_variable_get("@connection")
ip_as_int = ip_address_to_int(ip_address)
pg_conn.exec("SELECT isp FROM max_mind_isp WHERE ip_bottom <= $1 AND ip_top >= $2", [ip_as_int, ip_as_int]) do |result|
pg_conn.exec("SELECT isp FROM max_mind_isp WHERE ip_star <= $1 AND ip_end >= $2", [ip_address, ip_address]) do |result|
if !result.nil? && result.ntuples > 0
isp = result.getvalue(0, 0)
end
@ -95,10 +93,10 @@ class MaxMindManager < BaseManager
def create_phony_database()
clear_location_table
(0..255).each do |top_octet|
@pg_conn.exec("INSERT INTO max_mind_geo (ip_bottom, ip_top, country, region, city) VALUES ($1, $2, $3, $4, $5)",
@pg_conn.exec("INSERT INTO max_mind_geo (ip_start, ip_end, country, region, city) VALUES ($1, $2, $3, $4, $5)",
[
self.class.ip_address_to_int("#{top_octet}.0.0.0"),
self.class.ip_address_to_int("#{top_octet}.255.255.255"),
"#{top_octet}.0.0.0",
"#{top_octet}.255.255.255",
"US",
"Region #{(top_octet / 2).floor}",
"City #{top_octet}"
@ -107,10 +105,10 @@ class MaxMindManager < BaseManager
clear_isp_table
(0..255).each do |top_octet|
@pg_conn.exec("INSERT INTO max_mind_isp (ip_bottom, ip_top, isp, country) VALUES ($1, $2, $3, $4)",
@pg_conn.exec("INSERT INTO max_mind_isp (ip_start, ip_end, isp, country) VALUES ($1, $2, $3, $4)",
[
self.class.ip_address_to_int("#{top_octet}.0.0.0"),
self.class.ip_address_to_int("#{top_octet}.255.255.255"),
"#{top_octet}.0.0.0",
"#{top_octet}.255.255.255",
"ISP #{top_octet}",
"US"
]).clear
@ -120,13 +118,6 @@ class MaxMindManager < BaseManager
end
private
# Make an IP address fit in a signed int. Just divide it by 2, as the least significant part
# just can't possibly matter. We can verify this if needed. My guess is the entire bottom octet is
# actually irrelevant
def self.ip_address_to_int(ip)
ip.split('.').inject(0) {|total,value| (total << 8 ) + value.to_i} / 2
end
def clear_location_table
@pg_conn.exec("DELETE FROM max_mind_geo").clear