module JamRuby class JamTrackSearch < BaseSearch cattr_accessor :jschema, :search_meta attr_accessor :user_counters KEY_QUERY = 'query' KEY_SEARCH_STR = 'search_str' KEY_RESULT_TYPES = 'result_types' KEY_SONGS = 'songs' KEY_ARTISTS = 'artists' KEY_RESULTS = 'results' KEY_RESULT_SETS = 'result_sets' KEY_PAGE_NUM = 'page_num' KEY_TOTAL_COUNT = 'total_count' KEY_PAGE_COUNT = 'page_count' KEY_PER_PAGE = 'per_page' PER_PAGE = 'development'==Rails.env ? 8 : 20 KEY_GENRES = 'genres' KEY_INSTRUMENTS = 'instruments' KEY_LANGUAGE = 'language' KEY_ORIGINAL_ARTIST = 'original_artist' def self.json_schema return @@jschema ||= { KEY_QUERY => { KEY_SEARCH_STR => '', KEY_INSTRUMENTS => [], KEY_GENRES => [], KEY_LANGUAGE => '', KEY_ORIGINAL_ARTIST => '', KEY_RESULT_TYPES => [], KEY_PAGE_NUM => 1, KEY_PER_PAGE => PER_PAGE, }, KEY_RESULT_SETS => { KEY_SONGS => { KEY_RESULTS => [], KEY_PAGE_NUM => 1, KEY_TOTAL_COUNT => 0, KEY_PAGE_COUNT => 0, }, KEY_ARTISTS => { KEY_RESULTS => [], KEY_PAGE_NUM => 1, KEY_TOTAL_COUNT => 0, KEY_PAGE_COUNT => 0, }, }, } end def self.search_target_class JamTrack end def do_search(query) rel = JamTrack.unscoped unless (gids = query[KEY_GENRES]).blank? allgids = self.class.genre_ids gids = gids.select { |gg| allgids.has_key?(gg) } unless gids.blank? sqlstr = "'#{gids.join("','")}'" rel = rel.joins(:genres_jam_tracks) rel = rel.where("genres_jam_tracks.genre_id IN (#{sqlstr})") end end unless (instruments = query[KEY_INSTRUMENTS]).blank? instrids = self.class.instrument_ids instruments = instruments.select { |ii| instrids.has_key?(ii['instrument_id']) } unless instruments.blank? sqlstr = "'#{instruments.join("','")}'" rel = rel.joins(:jam_track_tracks) rel = rel.where("jam_track_tracks.instrument_id IN (#{sqlstr})") rel = rel.where("jam_track_tracks.track_type = 'Track'") end end unless (artist_name = query[KEY_ORIGINAL_ARTIST]).blank? rel = rel.where(original_artist: artist_name) end rel end def search_results_page(query=nil) filter = { KEY_QUERY => query, } result_types = query[KEY_RESULT_TYPES] if result_types has_songs, has_artists = result_types.index(KEY_SONGS), result_types.index(KEY_ARTISTS) else has_songs, has_artists = true, true end result_sets = filter[KEY_RESULT_SETS] = self.class.json_schema[KEY_RESULT_SETS].clone if has_songs rel = do_search(query) unless (val = query[KEY_SEARCH_STR]).blank? tsquery = Search.create_tsquery(val) rel = rel.where("(search_tsv @@ to_tsquery('jamenglish', ?))", tsquery) if tsquery end rel = rel.order(:name).includes(:genres) pgnum = [query[KEY_PAGE_NUM].to_i, 1].max rel = rel.paginate(:page => pgnum, :per_page => query[KEY_PER_PAGE]) results = rel.all.collect do |jt| { 'id' => jt.id, 'name' => jt.name, 'artist' => jt.original_artist, 'genre' => jt.genres.map(&:description).join(', '), 'plan_code' => jt.plan_code, 'year' => jt.year } end result_sets[KEY_SONGS] = { KEY_RESULTS => results, KEY_PAGE_NUM => pgnum, KEY_TOTAL_COUNT => rel.total_entries, KEY_PAGE_COUNT => rel.total_pages, } end if has_artists rel = do_search(query) counter = rel.select("DISTINCT(jam_tracks.original_artist)") rel = rel.select("DISTINCT ON(jam_tracks.original_artist) jam_tracks.id, jam_tracks.original_artist") unless (val = query[KEY_SEARCH_STR]).blank? rel = rel.where("original_artist ILIKE ?","%#{val}%") counter = counter.where("original_artist ILIKE ?","%#{val}%") end rel = rel.order(:original_artist) pgnum = [query[KEY_PAGE_NUM].to_i, 1].max rel = rel.paginate(:page => pgnum, :per_page => query[KEY_PER_PAGE]) results = rel.all.collect do |jt| { 'id' => jt.id, 'artist' => jt.original_artist } end artist_count = counter.count result_sets[KEY_ARTISTS] = { KEY_RESULTS => results, KEY_PAGE_NUM => pgnum, KEY_TOTAL_COUNT => artist_count, KEY_PAGE_COUNT => (artist_count / query[KEY_PER_PAGE].to_f).ceil, } end filter end def self.all_languages JamTrack.select("SELECT DISTINCT(language)").order(:language).collect do |lang| { description: ISO_639.find_by_code(lang), id: lang } end end end end