From af662fa7146d3d1fb43387c44fb15c610284c41b Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 2 Aug 2015 03:05:57 +0000 Subject: [PATCH] VRFS-3389 jamtrack search --- ruby/lib/jam_ruby.rb | 1 + ruby/lib/jam_ruby/models/jam_track_search.rb | 114 ++++++++++++++++++ .../jam_ruby/models/jam_track_search_spec.rb | 75 ++++++++++++ web/app/controllers/api_search_controller.rb | 24 +--- 4 files changed, 194 insertions(+), 20 deletions(-) create mode 100644 ruby/lib/jam_ruby/models/jam_track_search.rb create mode 100644 ruby/spec/jam_ruby/models/jam_track_search_spec.rb diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 8f62cecf9..0d462a929 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -248,6 +248,7 @@ require "jam_ruby/models/base_search" require "jam_ruby/models/musician_search" require "jam_ruby/models/band_search" require "jam_ruby/import/tency_stem_mapping" +require "jam_ruby/models/jam_track_search" include Jampb diff --git a/ruby/lib/jam_ruby/models/jam_track_search.rb b/ruby/lib/jam_ruby/models/jam_track_search.rb new file mode 100644 index 000000000..2051981a9 --- /dev/null +++ b/ruby/lib/jam_ruby/models/jam_track_search.rb @@ -0,0 +1,114 @@ +module JamRuby + class JamTrackSearch < BaseSearch + + cattr_accessor :jschema, :search_meta + attr_accessor :user_counters + + KEY_SEARCH_STR = 'search_str' + KEY_RESULT_TYPES = 'result_types' + KEY_SONGS = 'songs' + KEY_ARTISTS = 'artists' + + def self.json_schema + return @@jschema if @@jschema + @@jschema = { + KEY_SEARCH_STR => '', + KEY_INSTRUMENTS => [], + KEY_GENRES => [], + KEY_RESULT_TYPES => [], + KEY_SONGS => { + 'page_num' => 0, + 'page_count' => 0, + 'results' => [] + }, + KEY_ARTISTS => { + 'page_num' => 0, + 'page_count' => 0, + 'results' => [] + } + } + end + + def self.search_target_class + JamTrack + end + + def do_search(filter) + rel = JamTrack.unscoped + + unless (vals=filter[KEY_GENRES]).blank? + rel = rel.where("jam_tracks.genre_id IN ('#{vals.join("','")}')") + end + + unless (vals=filter[KEY_INSTRUMENTS]).blank? + rel = rel.join(:jam_track_tracks) + rel = rel.where("jam_track_tracks.instrument_id IN ('#{vals.join("','")}')") + rel = rel.where("jam_track_tracks.track_type != 'Master'") + end + + rel + end + + def search_includes(rel) + rel.includes([:instruments, :genres]) + end + + SONGS_PER_PAGE = 20 + ARTISTS_PER_PAGE = 20 + + def search_results_page(filter=nil) + if filter + self.data_blob = filter + self.save + else + filter = self.data_blob + end + + result_types = filter[KEY_RESULT_TYPES] + has_songs, has_artists = result_types.index(KEY_SONGS), result_types.index(KEY_ARTISTS) + + if has_songs + rel = do_search(filter) + rel = rel.where("name LIKE ?","%#{filter[KEY_SEARCH_STR]}%") + + pgnum = [filter[KEY_SONGS]['page_num'].to_i, 1].max + rel = rel.paginate(:page => pgnum, :per_page => SONGS_PER_PAGE) + + results = rel.all.collect do |jt| + { + 'id' => jt.id, + 'song_name' => jt.name, + 'artist' => jt.original_artist, + 'genre' => jt.genre.description, + 'year' => '' + } + end + filter[KEY_SONGS] = { + 'page_num' => pgnum, + 'page_count' => rel.total_pages, + 'results' => results + } + end + + if has_artists + rel = do_search(filter) + rel = rel.where("original_artist LIKE ?","%#{filter[KEY_SEARCH_STR]}%") + + pgnum = [filter[KEY_ARTISTS]['page_num'].to_i, 1].max + rel = rel.paginate(:page => pgnum, :per_page => ARTISTS_PER_PAGE) + + results = rel.all.collect do |jt| + { 'id' => jt.id, 'artist' => jt.original_artist } + end + filter[KEY_ARTISTS] = { + 'page_num' => pgnum, + 'page_count' => rel.total_pages, + 'results' => results + } + end + + filter + end + + end +end diff --git a/ruby/spec/jam_ruby/models/jam_track_search_spec.rb b/ruby/spec/jam_ruby/models/jam_track_search_spec.rb new file mode 100644 index 000000000..d99f8c73c --- /dev/null +++ b/ruby/spec/jam_ruby/models/jam_track_search_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +describe 'JamTrack Search Model' do + + let(:artist_filter) { + filter = JamTrackSearch.json_schema.clone + filter[JamTrackSearch::KEY_RESULT_TYPES] = [JamTrackSearch::KEY_ARTISTS] + filter + } + let(:song_filter) { + filter = JamTrackSearch.json_schema.clone + filter[JamTrackSearch::KEY_RESULT_TYPES] = [JamTrackSearch::KEY_SONGS] + filter + } + + before :each do + JamTrack.delete_all + jam_track1 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'jim bob', name: 'stairway to heaven') + jam_track2 = FactoryGirl.create(:jam_track_with_tracks, original_artist: 'jim bob', name: 'freebird') + end + + describe "Search filter" do + it "finds by artist" do + filter = artist_filter.clone + filter[JamTrackSearch::KEY_SEARCH_STR] = 'jim bob' + filter = JamTrackSearch.new.search_results_page(filter) + expect(filter[JamTrackSearch::KEY_ARTISTS]['results'].count).to be(2) + end + + it "paginates by artist" do + JamTrackSearch::ARTISTS_PER_PAGE.times do |nn| + FactoryGirl.create(:jam_track_with_tracks, + original_artist: 'jim bob', + name: 'abc'+nn.to_s) + end + filter = artist_filter.clone + filter[JamTrackSearch::KEY_SEARCH_STR] = 'jim bob' + out_filter = JamTrackSearch.new.search_results_page(filter.clone) + expect(out_filter[JamTrackSearch::KEY_ARTISTS]['results'].count).to be([JamTrackSearch::ARTISTS_PER_PAGE, JamTrack.count].min) + num_page = (JamTrack.count / JamTrackSearch::ARTISTS_PER_PAGE) + 1 + expect(out_filter[JamTrackSearch::KEY_ARTISTS]['page_count']).to be(num_page) + + filter[JamTrackSearch::KEY_ARTISTS]['page_num'] = 2 + out_filter = JamTrackSearch.new.search_results_page(filter.clone) + expect(out_filter[JamTrackSearch::KEY_ARTISTS]['results'].count).to be(2) + end + + it "finds by song" do + filter = song_filter.clone + filter[JamTrackSearch::KEY_SEARCH_STR] = 'freebird' + filter = JamTrackSearch.new.search_results_page(filter.clone) + expect(filter[JamTrackSearch::KEY_SONGS]['results'].count).to be(1) + end + + it "paginates by song" do + JamTrackSearch::SONGS_PER_PAGE.times do |nn| + FactoryGirl.create(:jam_track_with_tracks, + original_artist: 'jim bob', + name: 'abc'+nn.to_s) + end + filter = song_filter.clone + filter[JamTrackSearch::KEY_SEARCH_STR] = 'abc' + out_filter = JamTrackSearch.new.search_results_page(filter.clone) + expect(out_filter[JamTrackSearch::KEY_SONGS]['results'].count).to be([JamTrackSearch::SONGS_PER_PAGE, JamTrack.count].min) + num_page = (JamTrack.count / JamTrackSearch::SONGS_PER_PAGE) + 1 + expect(out_filter[JamTrackSearch::KEY_SONGS]['page_count']).to be(num_page) + + filter[JamTrackSearch::KEY_SONGS]['page_num'] = 2 + out_filter = JamTrackSearch.new.search_results_page(filter.clone) + expect(out_filter[JamTrackSearch::KEY_SONGS]['results'].count).to be(2) + end + + end + +end diff --git a/web/app/controllers/api_search_controller.rb b/web/app/controllers/api_search_controller.rb index ea6e0df65..424ebd51a 100644 --- a/web/app/controllers/api_search_controller.rb +++ b/web/app/controllers/api_search_controller.rb @@ -68,27 +68,11 @@ class ApiSearchController < ApiController def jam_tracks if request.get? - if params[:results] - @search = JamTrackSearch.user_search_filter(current_user).search_results_page(params[:subtype]) - respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/index' - elsif params[:genres] - - elsif params[:instruments] - - else - render :json => JamTrackSearch.search_filter_json(current_user, params[:subtype]), :status => 200 - end - elsif request.post? - sobj = JamTrackSearch.user_search_filter(current_user) - filter = params[:filter] - if filter == 'reset' - @search = sobj.reset_search_results(params[:subtype]) - else - json = JSON.parse(filter, :create_additions => false) - @search = sobj.search_results_page(params[:subtype], json, [params[:page].to_i, 1].max) - end - respond_with @search, responder: ApiResponder, status: 201, template: 'api_search/index' + json = JSON.parse(request.body) + result = JamTrackSearch.search_results_page(json) + + render json: result.to_json, status: 200 end end