jam-cloud/ruby/lib/jam_ruby/models/musician_search.rb

262 lines
7.9 KiB
Ruby
Raw Normal View History

2015-02-23 06:21:36 +00:00
module JamRuby
class MusicianSearch < JsonStore
ANY_VAL_STR = 'any'
ANY_VAL_INT = -1
2015-02-23 06:21:36 +00:00
PER_PAGE = 10
2015-02-24 06:06:40 +00:00
PG_SMALLINT_MAX = 32767
2015-02-23 06:21:36 +00:00
2015-03-06 06:33:38 +00:00
KEY_GIGS = 'concert_gigs'
KEY_STUDIOS = 'studio_sessions'
2015-02-23 06:21:36 +00:00
KEY_AGES = 'ages'
2015-02-28 04:24:53 +00:00
KEY_SKILL = 'skill_level'
KEY_GENRES = 'genres'
KEY_INSTRUMENTS = 'instruments'
2015-02-28 21:18:43 +00:00
KEY_INTERESTS = 'interests'
2015-02-28 22:45:43 +00:00
KEY_SORT_ORDER = 'sort_order'
2015-02-23 06:21:36 +00:00
SORT_VALS = %W{ latency distance }
SORT_ORDERS = {
SORT_VALS[0] => 'Latency to Me',
SORT_VALS[1] => 'Distance to Me'
}
2015-02-28 04:24:53 +00:00
SKILL_VALS = [ANY_VAL_INT, 1, 2]
2015-02-23 06:21:36 +00:00
SKILL_LEVELS = {
SKILL_VALS[0] => 'Any',
2015-02-28 04:24:53 +00:00
SKILL_VALS[1] => 'Amateur',
SKILL_VALS[2] => 'Pro',
2015-02-23 06:21:36 +00:00
}
GIG_COUNTS = [ANY_VAL_INT, 0, 1, 2, 3, 4]
2015-02-23 06:21:36 +00:00
GIG_LABELS = {
GIG_COUNTS[0] => 'Any',
GIG_COUNTS[1] => 'More than 0',
GIG_COUNTS[2] => 'More than 10',
GIG_COUNTS[3] => 'More than 50',
GIG_COUNTS[4] => 'More than 100'
}
2015-02-24 06:06:40 +00:00
GIG_RANGES = [(GIG_COUNTS[1]...GIG_COUNTS[2]),
(GIG_COUNTS[2]...GIG_COUNTS[3]),
(GIG_COUNTS[3]...GIG_COUNTS[4]),
(GIG_COUNTS[4]...PG_SMALLINT_MAX)]
2015-02-23 06:21:36 +00:00
STUDIO_COUNTS = [ANY_VAL_INT, 0, 1, 2, 3, 4]
2015-02-23 06:21:36 +00:00
STUDIOS_LABELS = {
STUDIO_COUNTS[0] => 'Any',
STUDIO_COUNTS[1] => 'More than 0',
STUDIO_COUNTS[2] => 'More than 10',
STUDIO_COUNTS[3] => 'More than 50',
STUDIO_COUNTS[4] => 'More than 100'
}
2015-02-24 06:06:40 +00:00
STUDIO_RANGES = [(STUDIO_COUNTS[1]...STUDIO_COUNTS[2]),
(STUDIO_COUNTS[2]...STUDIO_COUNTS[3]),
(STUDIO_COUNTS[3]...STUDIO_COUNTS[4]),
(STUDIO_COUNTS[4]...PG_SMALLINT_MAX)]
2015-02-23 06:21:36 +00:00
AGE_COUNTS = [ANY_VAL_INT, 10, 20, 30, 40, 50]
AGES = {
AGE_COUNTS[0] => 'Any',
AGE_COUNTS[1] => 'Teens',
AGE_COUNTS[2] => "20's",
AGE_COUNTS[3] => "30's",
AGE_COUNTS[4] => "40's",
AGE_COUNTS[5] => "50+"
}
INTEREST_VALS = [ANY_VAL_STR,
GenrePlayer::VIRTUAL_BAND,
GenrePlayer::TRADITIONAL_BAND,
GenrePlayer::PAID_SESSION,
GenrePlayer::FREE_SESSION,
GenrePlayer::COWRITING,
]
INTERESTS = {
INTEREST_VALS[0] => 'Any',
INTEREST_VALS[1] => 'Virtual Band',
INTEREST_VALS[2] => 'Traditional Band',
INTEREST_VALS[3] => 'Paid Sessions',
INTEREST_VALS[4] => 'Free Sessions',
INTEREST_VALS[5] => 'Co-Writing'
}
JSON_SCHEMA = {
2015-02-28 22:45:43 +00:00
KEY_SORT_ORDER => SORT_VALS[0],
KEY_INSTRUMENTS => [],
2015-02-28 22:45:43 +00:00
KEY_INTERESTS => INTEREST_VALS[0],
KEY_GENRES => [],
KEY_GIGS => GIG_COUNTS[0].to_s,
KEY_STUDIOS => STUDIO_COUNTS[0].to_s,
KEY_SKILL => SKILL_VALS[0].to_s,
2015-02-28 22:45:43 +00:00
KEY_AGES => [AGE_COUNTS[0]]
2015-02-23 06:21:36 +00:00
}
2015-03-06 06:33:38 +00:00
JSON_SCHEMA_KEYS = JSON_SCHEMA.keys
MULTI_VALUE_KEYS = JSON_SCHEMA.collect { |kk,vv| vv.is_a?(Array) ? kk : nil }.compact
SINGLE_VALUE_KEYS = JSON_SCHEMA.keys - MULTI_VALUE_KEYS
2015-02-23 06:21:36 +00:00
SEARCH_FILTER_CONFIG = {
2015-03-07 06:19:14 +00:00
per_page: PER_PAGE,
filter_keys: {
keys: JSON_SCHEMA_KEYS,
multi: MULTI_VALUE_KEYS,
single: SINGLE_VALUE_KEYS,
},
2015-03-07 06:19:14 +00:00
sort_order: { keys: SORT_VALS, map: SORT_ORDERS },
interests: { keys: INTEREST_VALS, map: INTERESTS },
ages: { keys: AGE_COUNTS, map: AGES }
}
def self.user_search_filter(user)
unless ms = user.musician_search
ms = self.create_search(user)
end
2015-03-07 06:19:14 +00:00
ms
end
def self.search_filter_json(user)
self.user_search_filter(user).json
end
2015-02-23 06:21:36 +00:00
def self.create_search(user)
ms = self.new
ms.user = user
ms.data_blob = JSON_SCHEMA
ms.save!
ms
end
def _genres(rel)
gids = json[KEY_GENRES]
2015-02-23 06:21:36 +00:00
unless gids.blank?
gidsql = gids.join("','")
gpsql = "SELECT player_id FROM genre_players WHERE (player_type = 'JamRuby::User' AND genre_id IN ('#{gidsql}'))"
rel = rel.where("users.id IN (#{gpsql})")
2015-02-23 06:21:36 +00:00
end
rel
end
def _instruments(rel)
unless (instruments = json['instruments']).blank?
instsql = "SELECT user_id FROM musicians_instruments WHERE (("
instsql += instruments.collect do |inst|
"instrument_id = '#{inst['instrument_id']}' AND proficiency_level = #{inst['proficiency_level']}"
end.join(") OR (")
instsql += "))"
rel = rel.where("users.id IN (#{instsql})")
2015-02-23 06:21:36 +00:00
end
rel
end
def _ages(rel)
unless (vals = json[KEY_AGES]).blank?
return rel if vals.detect { |vv| ANY_VAL_INT == vv }
arels = []
vals.each do |val|
today = Date.today
case val
when 10
arels << User.where("birth_date >= ? AND birth_date < ?",
today - 20.years, today - 10.years)
when 20
arels << User.where("birth_date >= ? AND birth_date < ?",
today - 30.years, today - 20.years)
when 30
arels << User.where("birth_date >= ? AND birth_date < ?",
today - 40.years, today - 50.years)
when 40
arels << User.where("birth_date >= ? AND birth_date < ?",
today - 50.years, today - 40.years)
when 50
arels << User.where("birth_date <= ?", today - 50.years)
end
end
rel = rel.where("birth_date IS NOT NULL")
2015-02-24 06:06:40 +00:00
sql = "(#{arels.map(&:where_values).flatten.join(') OR (')})"
rel = rel.where(sql)
2015-02-23 06:21:36 +00:00
end
rel
end
def _studios(rel)
2015-02-24 06:06:40 +00:00
if 0 < (count = json[KEY_STUDIOS].to_i)
2015-02-23 06:21:36 +00:00
rel = rel.where('studio_session_count IS NOT NULL')
case count
when STUDIO_COUNTS[1]
2015-02-24 06:06:40 +00:00
rel = rel.where('studio_session_count >= ? AND studio_session_count < ?',
2015-02-23 06:21:36 +00:00
count, STUDIO_COUNTS[2])
when STUDIO_COUNTS[2]
2015-02-24 06:06:40 +00:00
rel = rel.where('studio_session_count >= ? AND studio_session_count < ?',
2015-02-23 06:21:36 +00:00
count, STUDIO_COUNTS[3])
when STUDIO_COUNTS[3]
2015-02-24 06:06:40 +00:00
rel = rel.where('studio_session_count >= ? AND studio_session_count < ?',
2015-02-23 06:21:36 +00:00
count, STUDIO_COUNTS[4])
when STUDIO_COUNTS[4]
rel = rel.where('studio_session_count >= ?', count)
end
end
rel
end
def _gigs(rel)
2015-02-24 06:06:40 +00:00
if 0 < (count = json[KEY_GIGS].to_i)
2015-02-23 06:21:36 +00:00
rel = rel.where('concert_count IS NOT NULL')
case count
when GIG_COUNTS[1]
2015-02-24 06:06:40 +00:00
rel = rel.where('concert_count >= ? AND concert_count < ?', count, GIG_COUNTS[2])
2015-02-23 06:21:36 +00:00
when GIG_COUNTS[2]
2015-02-24 06:06:40 +00:00
rel = rel.where('concert_count >= ? AND concert_count < ?', count, GIG_COUNTS[3])
2015-02-23 06:21:36 +00:00
when GIG_COUNTS[3]
2015-02-24 06:06:40 +00:00
rel = rel.where('concert_count >= ? AND concert_count < ?', count, GIG_COUNTS[4])
2015-02-23 06:21:36 +00:00
when GIG_COUNTS[4]
rel = rel.where('concert_count >= ?', count)
end
end
rel
end
def _skills(rel)
2015-02-28 04:24:53 +00:00
if 0 < (val = json['skill_level'].to_i)
rel = rel.where(['skill_level = ?', val])
2015-02-23 06:21:36 +00:00
end
rel
end
def _interests(rel)
val = json['interests']
if val.present? && ANY_VAL_STR != val
2015-02-28 21:18:43 +00:00
rel = rel.where("#{val} = ?", true)
2015-02-23 06:21:36 +00:00
end
rel
end
def pagination(rel, params)
perpage = [(params[:per_page] || PER_PAGE).to_i, 100].min
page = [params[:page].to_i, 1].max
[rel.paginate(:page => page, :per_page => perpage), page]
end
def do_search(params={})
rel = User.musicians
rel = self._genres(rel)
rel = self._ages(rel)
rel = self._studios(rel)
rel = self._gigs(rel)
rel = self._skills(rel)
rel = self._instruments(rel)
rel = self._interests(rel)
rel
end
def search_results_page(filter={}, page=1)
self.data_blob = filter
self.save
rel = do_search(filter)
rel, page = self.pagination(rel, filter)
rel.to_json
end
2015-02-23 06:21:36 +00:00
end
end