From 3d75f8dd972956eb1fd25e18eaae9fa8d847c436 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 06:26:40 -0600 Subject: [PATCH 01/41] vrfs-988: refactoring search as text by entity, rather than site-wide --- ruby/lib/jam_ruby/models/band.rb | 17 --- ruby/lib/jam_ruby/models/search.rb | 106 +++++++----------- ruby/lib/jam_ruby/models/user.rb | 26 +---- .../models/band_filter_search_spec.rb | 68 +++++------ ruby/spec/jam_ruby/models/band_search_spec.rb | 38 +++---- .../jam_ruby/models/musician_search_spec.rb | 70 ++++++------ 6 files changed, 130 insertions(+), 195 deletions(-) diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index 3ce6fee36..de6546f84 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -111,23 +111,6 @@ module JamRuby return recordings end - def self.search(query, options = { :limit => 10 }) - - # only issue search if at least 2 characters are specified - if query.nil? || query.length < 2 - return [] - end - - # create 'anded' statement - query = Search.create_tsquery(query) - - if query.nil? || query.length == 0 - return [] - end - - return Band.where("name_tsv @@ to_tsquery('jamenglish', ?)", query).limit(options[:limit]) - end - # helper method for creating / updating a Band def self.save(id, name, website, biography, city, state, country, genres, user_id, photo_url, logo_url) user = User.find(user_id) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 930bb109c..5ca1db50c 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -1,73 +1,51 @@ module JamRuby - # not a active_record model; just a search result + # not a active_record model; just a search result container class Search - attr_accessor :bands, :musicians, :fans, :recordings, :friends, :search_type - attr_accessor :bands_filter, :musicians_filter + attr_accessor :filter_results, :text_results LIMIT = 10 - # performs a site-white search - def self.search(query, user_id = nil) + SEARCH_TEXT_TYPES = [:musicians, :bands, :fans] + SEARCH_TEXT_TYPE_ID = :search_text_type - users = User.search(query, :limit => LIMIT) - bands = Band.search(query, :limit => LIMIT) - # NOTE: I removed recordings from search here. This is because we switched - # to "claimed_recordings" so it's not clear what should be searched. - - friends = Friendship.search(query, user_id, :limit => LIMIT) - - return Search.new(users + bands + friends) + def self.band_search(txt, user = nil) + self.text_search({ SEARCH_TEXT_TYPE_ID => :bands, :query => txt }, user) end - # performs a friend search scoped to a specific user - # def self.search_by_user(query, user_id) - # friends = Friendship.search(query, user_id, :limit => LIMIT) - # return Search.new(friends) - # end + def self.fan_search(txt, user = nil) + self.text_search({ SEARCH_TEXT_TYPE_ID => :fans, :query => txt }, user) + end + + def self.musicians_search(txt, user = nil) + self.text_search({ SEARCH_TEXT_TYPE_ID => :musicians, :query => txt }, user) + end + + def self.text_search(params, user = nil) + return [] if params.blank? || params[:query].blank? || 2 >= params[:query].length + + tsquery = Search.create_tsquery(params[:query]) + return [] if tsquery.blank? + + rel = case params[SEARCH_TEXT_TYPE_ID] || SEARCH_TEXT_TYPES[0].to_s + when 'bands' + Band.where("name_tsv @@ to_tsquery('jamenglish', ?)", tsquery) + when 'fans' + User.fans.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery) + else + User.musicians.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery) + end + @text_results = rel.limit(10) + end - # search_results - results from a Tire search across band/user/recording def initialize(search_results=nil) - @bands = [] - @musicians = [] - @fans = [] - @recordings = [] - @friends = [] - @musicians_filter = [] - @bands_filter = [] - - if search_results.nil? - return - end - - search_results.take(LIMIT).each do |result| - if result.class == User - if result.musician - @musicians.push(result) - else - @fans.push(result) - end - elsif result.class == Band - @bands.push(result) - elsif result.class == Recording - @recordings.push(result) - elsif result.class == Friendship - @friends.push(result.friend) - else - raise Exception, "unknown class #{result.class} returned in search results" - end - end + @text_results, @filter_results = [], [] + self end def self.create_tsquery(query) - # empty queries don't hit back to elasticsearch - if query.nil? || query.length == 0 - return nil - end + return nil if query.nil? || query.length == 0 search_terms = query.split - - if search_terms.length == 0 - return nil - end + return nil if search_terms.length == 0 args = nil search_terms.each do |search_term| @@ -76,11 +54,9 @@ module JamRuby else args = args + " & " + search_term end - end args = args + ":*" - - return args + args end attr_accessor :user_counters, :page_num, :page_count @@ -105,7 +81,7 @@ module JamRuby ordering.blank? ? keys[0] : keys.detect { |oo| oo.to_s == ordering } end - def self.musician_search(params={}, current_user=nil) + def self.musician_filter(params={}, current_user=nil) rel = User.musicians unless (instrument = params[:instrument]).blank? rel = rel.joins("RIGHT JOIN musicians_instruments AS minst ON minst.user_id = users.id") @@ -160,10 +136,10 @@ module JamRuby COUNTERS = [COUNT_FRIEND, COUNT_FOLLOW, COUNT_RECORD, COUNT_SESSION] def musician_results_for_user(results, user) - @search_type, @musicians_filter = PARAM_MUSICIAN, results + @filter_results = results if user @user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh } - mids = "'#{@musicians_filter.map(&:id).join("','")}'" + mids = "'#{@filter_results.map(&:id).join("','")}'" # this gets counts for each search result on friends/follows/records/sessions results.each do |uu| @@ -247,7 +223,7 @@ module JamRuby end end - def self.band_search(params={}, current_user=nil) + def self.band_filter(params={}, current_user=nil) rel = Band.scoped unless (genre = params[:genre]).blank? @@ -287,10 +263,10 @@ module JamRuby end def band_results_for_user(results, user) - @search_type, @bands_filter = PARAM_BAND, results + @filter_results = results if user @user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh } - mids = "'#{@bands_filter.map(&:id).join("','")}'" + mids = "'#{@filter_results.map(&:id).join("','")}'" # this gets counts for each search result results.each do |bb| diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 60a3b4dd6..024838e72 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -140,6 +140,7 @@ module JamRuby validate :update_email_case_insensitive_uniqueness, :if => :updating_email scope :musicians, where(:musician => true) + scope :fans, where(:musician => false) scope :geocoded_users, where(['lat IS NOT NULL AND lng IS NOT NULL']) scope :musicians_geocoded, musicians.geocoded_users @@ -924,31 +925,6 @@ module JamRuby end end - def self.search(query, options = { :limit => 10 }) - - # only issue search if at least 2 characters are specified - if query.nil? || query.length < 2 - return [] - end - - # save query for use in instrument search - search_criteria = query - - # create 'anded' statement - query = Search.create_tsquery(query) - - if query.nil? || query.length == 0 - return [] - end - - # remove email_confirmed restriction due to VRFS-378 - # .where("email_confirmed = true AND (name_tsv @@ to_tsquery('jamenglish', ?) OR users.id in (select user_id from musicians_instruments where instrument_id like '%#{search_criteria.downcase}%'))", query) - - return query = User - .where("(name_tsv @@ to_tsquery('jamenglish', ?) OR users.id in (select user_id from musicians_instruments where instrument_id like '%#{search_criteria.downcase}%'))", query) - .limit(options[:limit]) - end - def provides_location? !self.city.blank? && (!self.state.blank? || !self.country.blank?) end diff --git a/ruby/spec/jam_ruby/models/band_filter_search_spec.rb b/ruby/spec/jam_ruby/models/band_filter_search_spec.rb index 51e43f403..ebfb57e08 100644 --- a/ruby/spec/jam_ruby/models/band_filter_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_filter_search_spec.rb @@ -25,15 +25,15 @@ describe 'Band search' do it "finds all bands" do # expects all the bands num = Band.count - results = Search.band_search({ :per_page => num }) - expect(results.bands_filter.count).to eq(num) + results = Search.band_filter({ :per_page => num }) + expect(results.filter_results.count).to eq(num) end it "finds bands with proper ordering" do # the ordering should be create_at since no followers exist expect(BandFollower.count).to eq(0) - results = Search.band_search({ :per_page => Band.count }) - results.bands_filter.each_with_index do |uu, idx| + results = Search.band_filter({ :per_page => Band.count }) + results.filter_results.each_with_index do |uu, idx| expect(uu.id).to eq(@bands.reverse[idx].id) end end @@ -53,11 +53,11 @@ describe 'Band search' do # refresh the order to ensure it works right @band2.followers.concat(users[1..-1]) - results = Search.band_search({ :per_page => @bands.size }, users[0]) - expect(results.bands_filter[0].id).to eq(@band2.id) + results = Search.band_filter({ :per_page => @bands.size }, users[0]) + expect(results.filter_results[0].id).to eq(@band2.id) # check the follower count for given entry - expect(results.bands_filter[0].search_follow_count.to_i).not_to eq(0) + expect(results.filter_results[0].search_follow_count.to_i).not_to eq(0) # check the follow relationship between current_user and result expect(results.is_follower?(@band2)).to be true end @@ -65,8 +65,8 @@ describe 'Band search' do it 'paginates properly' do # make sure pagination works right params = { :per_page => 2, :page => 1 } - results = Search.band_search(params) - expect(results.bands_filter.count).to be 2 + results = Search.band_filter(params) + expect(results.filter_results.count).to be 2 end end @@ -87,8 +87,8 @@ describe 'Band search' do # establish sorting order @band1.followers.concat(users) - results = Search.band_search({},@band1) - uu = results.bands_filter.detect { |mm| mm.id == @band1.id } + results = Search.band_filter({},@band1) + uu = results.filter_results.detect { |mm| mm.id == @band1.id } expect(uu).to_not be_nil expect(results.follow_count(uu)).to eq(users.count) end @@ -96,8 +96,8 @@ describe 'Band search' do it "session stat shows session count" do make_session(@band1) @band1.reload - results = Search.band_search({},@band1) - uu = results.bands_filter.detect { |mm| mm.id == @band1.id } + results = Search.band_filter({},@band1) + uu = results.filter_results.detect { |mm| mm.id == @band1.id } expect(uu).to_not be_nil expect(results.session_count(uu)).to be 1 end @@ -112,9 +112,9 @@ describe 'Band search' do make_session(@band2) make_session(@band1) # order results by num recordings - results = Search.band_search({ :orderby => 'plays' }) - expect(results.bands_filter[0].id).to eq(@band2.id) - expect(results.bands_filter[1].id).to eq(@band1.id) + results = Search.band_filter({ :orderby => 'plays' }) + expect(results.filter_results[0].id).to eq(@band2.id) + expect(results.filter_results[1].id).to eq(@band1.id) end it "by now playing" do @@ -122,18 +122,18 @@ describe 'Band search' do session = make_session(@band3) FactoryGirl.create(:music_session_history, :music_session => session) - results = Search.band_search({ :orderby => 'playing' }) - expect(results.bands_filter.count).to be 1 - expect(results.bands_filter.first.id).to eq(@band3.id) + results = Search.band_filter({ :orderby => 'playing' }) + expect(results.filter_results.count).to be 1 + expect(results.filter_results.first.id).to eq(@band3.id) # should get 2 results with 2 active sessions # sort order should be created_at DESC session = make_session(@band4) FactoryGirl.create(:music_session_history, :music_session => session) - results = Search.band_search({ :orderby => 'playing' }) - expect(results.bands_filter.count).to be 2 - expect(results.bands_filter[0].id).to eq(@band4.id) - expect(results.bands_filter[1].id).to eq(@band3.id) + results = Search.band_filter({ :orderby => 'playing' }) + expect(results.filter_results.count).to be 2 + expect(results.filter_results[0].id).to eq(@band4.id) + expect(results.filter_results[1].id).to eq(@band3.id) end end @@ -146,40 +146,40 @@ describe 'Band search' do @band1.reload ggg = @band1.genres.detect { |gg| gg.id == genre.id } expect(ggg).to_not be_nil - results = Search.band_search({ :genre => ggg.id }) - results.bands_filter.each do |rr| + results = Search.band_filter({ :genre => ggg.id }) + results.filter_results.each do |rr| expect(rr.genres.detect { |gg| gg.id==ggg.id }.id).to eq(genre.id) end - expect(results.bands_filter.count).to be 1 + expect(results.filter_results.count).to be 1 end it "finds bands within a given distance of given location" do num = Band.count expect(@band1.lat).to_not be_nil # short distance - results = Search.band_search({ :per_page => num, + results = Search.band_filter({ :per_page => num, :distance => 10, :city => 'Apex' }, @band1) - expect(results.bands_filter.count).to be num + expect(results.filter_results.count).to be num # long distance - results = Search.band_search({ :per_page => num, + results = Search.band_filter({ :per_page => num, :distance => 1000, :city => 'Miami', :state => 'FL' }, @band1) - expect(results.bands_filter.count).to be num + expect(results.filter_results.count).to be num end it "finds bands within a given distance of bands location" do expect(@band1.lat).to_not be_nil # uses the location of @band1 - results = Search.band_search({ :distance => 10, :per_page => Band.count }, @band1) - expect(results.bands_filter.count).to be Band.count + results = Search.band_filter({ :distance => 10, :per_page => Band.count }, @band1) + expect(results.filter_results.count).to be Band.count end it "finds no bands within a given distance of location" do expect(@band1.lat).to_not be_nil - results = Search.band_search({ :distance => 10, :city => 'San Francisco' }, @band1) - expect(results.bands_filter.count).to be 0 + results = Search.band_filter({ :distance => 10, :city => 'San Francisco' }, @band1) + expect(results.filter_results.count).to be 0 end end diff --git a/ruby/spec/jam_ruby/models/band_search_spec.rb b/ruby/spec/jam_ruby/models/band_search_spec.rb index 40e26d50f..6d3c07d1c 100644 --- a/ruby/spec/jam_ruby/models/band_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_search_spec.rb @@ -13,7 +13,7 @@ describe User do end it "should allow search of one band with an exact match" do - ws = Band.search("Example Band") + ws = Search.band_search("Example Band") ws.length.should == 1 band_result = ws[0] band_result.name.should == @band.name @@ -22,61 +22,61 @@ describe User do end it "should allow search of one band with partial matches" do - ws = Band.search("Ex") + ws = Search.band_search("Ex") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Exa") + ws = Search.band_search("Exa") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Exam") + ws = Search.band_search("Exam") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Examp") + ws = Search.band_search("Examp") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Exampl") + ws = Search.band_search("Exampl") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Example") + ws = Search.band_search("Example") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Ba") + ws = Search.band_search("Ba") ws.length.should == 1 ws[0].id.should == @band.id - ws = Band.search("Ban") + ws = Search.band_search("Ban") ws.length.should == 1 ws[0].id.should == @band.id end it "should not match mid-word searchs" do - ws = Band.search("xa") + ws = Search.band_search("xa") ws.length.should == 0 - ws = Band.search("le") + ws = Search.band_search("le") ws.length.should == 0 end it "should delete band" do - ws = Band.search("Example Band") + ws = Search.band_search("Example Band") ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @band.destroy # delete doesn't work; you have to use destroy. - ws = Band.search("Example Band") + ws = Search.band_search("Example Band") ws.length.should == 0 end it "should update band" do - ws = Band.search("Example Band") + ws = Search.band_search("Example Band") ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -84,10 +84,10 @@ describe User do @band.name = "bonus-stuff" @band.save - ws = Band.search("Example Band") + ws = Search.band_search("Example Band") ws.length.should == 0 - ws = Band.search("Bonus") + ws = Search.band_search("Bonus") ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -96,7 +96,7 @@ describe User do it "should tokenize correctly" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Band.search("pea") + ws = Search.band_search("pea") ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id @@ -105,12 +105,12 @@ describe User do it "should not return anything with a 1 character search" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Band.search("pe") + ws = Search.band_search("pe") ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id - ws = Band.search("p") + ws = Search.band_search("p") ws.length.should == 0 end end diff --git a/ruby/spec/jam_ruby/models/musician_search_spec.rb b/ruby/spec/jam_ruby/models/musician_search_spec.rb index 955b2f04f..5459b8b62 100644 --- a/ruby/spec/jam_ruby/models/musician_search_spec.rb +++ b/ruby/spec/jam_ruby/models/musician_search_spec.rb @@ -17,15 +17,15 @@ describe 'Musician search' do it "finds all musicians" do # expects all the users num = User.musicians.count - results = Search.musician_search({ :per_page => num }) - expect(results.musicians_filter.count).to eq(num) + results = Search.musician_filter({ :per_page => num }) + expect(results.filter_results.count).to eq(num) end it "finds musicians with proper ordering" do # the ordering should be create_at since no followers exist expect(UserFollower.count).to eq(0) - results = Search.musician_search({ :per_page => User.musicians.count }) - results.musicians_filter.each_with_index do |uu, idx| + results = Search.musician_filter({ :per_page => User.musicians.count }) + results.filter_results.each_with_index do |uu, idx| expect(uu.id).to eq(@users.reverse[idx].id) end end @@ -40,11 +40,11 @@ describe 'Musician search' do # refresh the order to ensure it works right @user2.followers.concat([@user3, @user4, @user2]) - results = Search.musician_search({ :per_page => @users.size }, @user3) - expect(results.musicians_filter[0].id).to eq(@user2.id) + results = Search.musician_filter({ :per_page => @users.size }, @user3) + expect(results.filter_results[0].id).to eq(@user2.id) # check the follower count for given entry - expect(results.musicians_filter[0].search_follow_count.to_i).not_to eq(0) + expect(results.filter_results[0].search_follow_count.to_i).not_to eq(0) # check the follow relationship between current_user and result expect(results.is_follower?(@user2)).to be true end @@ -52,8 +52,8 @@ describe 'Musician search' do it 'paginates properly' do # make sure pagination works right params = { :per_page => 2, :page => 1 } - results = Search.musician_search(params) - expect(results.musicians_filter.count).to be 2 + results = Search.musician_filter(params) + expect(results.filter_results.count).to be 2 end end @@ -95,8 +95,8 @@ describe 'Musician search' do # create friendship record Friendship.save(@user1.id, @user2.id) # search on user2 - results = Search.musician_search({}, @user2) - friend = results.musicians_filter.detect { |mm| mm.id == @user1.id } + results = Search.musician_filter({}, @user2) + friend = results.filter_results.detect { |mm| mm.id == @user1.id } expect(friend).to_not be_nil expect(results.friend_count(friend)).to be 1 @user1.reload @@ -114,8 +114,8 @@ describe 'Musician search' do expect(recording.claimed_recordings.length).to be 1 expect(@user1.recordings.detect { |rr| rr == recording }).to_not be_nil - results = Search.musician_search({},@user1) - uu = results.musicians_filter.detect { |mm| mm.id == @user1.id } + results = Search.musician_filter({},@user1) + uu = results.filter_results.detect { |mm| mm.id == @user1.id } expect(uu).to_not be_nil expect(results.record_count(uu)).to be 1 @@ -129,29 +129,29 @@ describe 'Musician search' do it "by plays" do make_recording(@user1) # order results by num recordings - results = Search.musician_search({ :orderby => 'plays' }, @user2) - expect(results.musicians_filter[0].id).to eq(@user1.id) + results = Search.musician_filter({ :orderby => 'plays' }, @user2) + expect(results.filter_results[0].id).to eq(@user1.id) # add more data and make sure order still correct make_recording(@user2); make_recording(@user2) - results = Search.musician_search({ :orderby => 'plays' }, @user2) - expect(results.musicians_filter[0].id).to eq(@user2.id) + results = Search.musician_filter({ :orderby => 'plays' }, @user2) + expect(results.filter_results[0].id).to eq(@user2.id) end it "by now playing" do # should get 1 result with 1 active session make_session(@user3) - results = Search.musician_search({ :orderby => 'playing' }, @user2) - expect(results.musicians_filter.count).to be 1 - expect(results.musicians_filter.first.id).to eq(@user3.id) + results = Search.musician_filter({ :orderby => 'playing' }, @user2) + expect(results.filter_results.count).to be 1 + expect(results.filter_results.first.id).to eq(@user3.id) # should get 2 results with 2 active sessions # sort order should be created_at DESC make_session(@user4) - results = Search.musician_search({ :orderby => 'playing' }, @user2) - expect(results.musicians_filter.count).to be 2 - expect(results.musicians_filter[0].id).to eq(@user4.id) - expect(results.musicians_filter[1].id).to eq(@user3.id) + results = Search.musician_filter({ :orderby => 'playing' }, @user2) + expect(results.filter_results.count).to be 2 + expect(results.filter_results[0].id).to eq(@user4.id) + expect(results.filter_results[1].id).to eq(@user3.id) end end @@ -165,40 +165,40 @@ describe 'Musician search' do @user1.reload ii = @user1.instruments.detect { |inst| inst.id == 'tuba' } expect(ii).to_not be_nil - results = Search.musician_search({ :instrument => ii.id }) - results.musicians_filter.each do |rr| + results = Search.musician_filter({ :instrument => ii.id }) + results.filter_results.each do |rr| expect(rr.instruments.detect { |inst| inst.id=='tuba' }.id).to eq(ii.id) end - expect(results.musicians_filter.count).to be 1 + expect(results.filter_results.count).to be 1 end it "finds musicians within a given distance of given location" do num = User.musicians.count expect(@user1.lat).to_not be_nil # short distance - results = Search.musician_search({ :per_page => num, + results = Search.musician_filter({ :per_page => num, :distance => 10, :city => 'Apex' }, @user1) - expect(results.musicians_filter.count).to be num + expect(results.filter_results.count).to be num # long distance - results = Search.musician_search({ :per_page => num, + results = Search.musician_filter({ :per_page => num, :distance => 1000, :city => 'Miami', :state => 'FL' }, @user1) - expect(results.musicians_filter.count).to be num + expect(results.filter_results.count).to be num end it "finds musicians within a given distance of users location" do expect(@user1.lat).to_not be_nil # uses the location of @user1 - results = Search.musician_search({ :distance => 10, :per_page => User.musicians.count }, @user1) - expect(results.musicians_filter.count).to be User.musicians.count + results = Search.musician_filter({ :distance => 10, :per_page => User.musicians.count }, @user1) + expect(results.filter_results.count).to be User.musicians.count end it "finds no musicians within a given distance of location" do expect(@user1.lat).to_not be_nil - results = Search.musician_search({ :distance => 10, :city => 'San Francisco' }, @user1) - expect(results.musicians_filter.count).to be 0 + results = Search.musician_filter({ :distance => 10, :city => 'San Francisco' }, @user1) + expect(results.filter_results.count).to be 0 end end From 2229babf68226fe8145afcaf1864f6fa7fada440 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 06:27:05 -0600 Subject: [PATCH 02/41] vrfs-988: refactoring search as text by entity, rather than site-wide --- web/app/assets/javascripts/sidebar.js | 2 +- web/app/controllers/api_search_controller.rb | 15 +++++++-------- web/app/views/clients/_sidebar.html.erb | 10 ++-------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index 618e88d39..fe7976ecb 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -432,8 +432,8 @@ if (query === '') { return hideSearchResults(); } - if (query.length > 2) { + query += '&srch_t='+$('#search_text_type').val(); emptySearchResults(); search(query); } diff --git a/web/app/controllers/api_search_controller.rb b/web/app/controllers/api_search_controller.rb index 63c0ff8d9..ca68d8c1a 100644 --- a/web/app/controllers/api_search_controller.rb +++ b/web/app/controllers/api_search_controller.rb @@ -6,18 +6,17 @@ class ApiSearchController < ApiController respond_to :json def index - if 1 == params[Search::PARAM_MUSICIAN].to_i + if 1 == params[Search::PARAM_MUSICIAN].to_i || 1 == params[Search::PARAM_BAND].to_i query = params.clone query[:remote_ip] = request.remote_ip - @search = Search.musician_search(query, current_user) - respond_with @search, responder: ApiResponder, :status => 200 - elsif 1 == params[Search::PARAM_BAND].to_i - query = params.clone - query[:remote_ip] = request.remote_ip - @search = Search.band_search(query, current_user) + if 1 == params[Search::PARAM_MUSICIAN].to_i + @search = Search.musician_filter(query, current_user) + else + @search = Search.band_filter(query, current_user) + end respond_with @search, responder: ApiResponder, :status => 200 else - @search = Search.search(params[:query], current_user.id) + @search = Search.text_search(params, current_user) end end end diff --git a/web/app/views/clients/_sidebar.html.erb b/web/app/views/clients/_sidebar.html.erb index 4ac3fb7f7..4b9732765 100644 --- a/web/app/views/clients/_sidebar.html.erb +++ b/web/app/views/clients/_sidebar.html.erb @@ -25,13 +25,7 @@
- Show: - + Show: <%= select_tag(Search::SEARCH_TEXT_TYPE_ID, options_for_select(Search::SEARCH_TEXT_TYPES.collect { |ii| [ii.to_s.titleize, ii] })) %>
@@ -200,4 +194,4 @@
- \ No newline at end of file + From fa0b3eeb70fffa00e5009437094c27d90a071321 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 06:37:55 -0600 Subject: [PATCH 03/41] vrfs-988: ran band_search tests --- ruby/lib/jam_ruby/models/search.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 5ca1db50c..58cca06bd 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -20,12 +20,13 @@ module JamRuby end def self.text_search(params, user = nil) - return [] if params.blank? || params[:query].blank? || 2 >= params[:query].length + return [] if params.blank? || params[:query].blank? || 2 > params[:query].length tsquery = Search.create_tsquery(params[:query]) return [] if tsquery.blank? - rel = case params[SEARCH_TEXT_TYPE_ID] || SEARCH_TEXT_TYPES[0].to_s + srch_type = params[SEARCH_TEXT_TYPE_ID].present? ? params[SEARCH_TEXT_TYPE_ID].to_s : '' + rel = case srch_type when 'bands' Band.where("name_tsv @@ to_tsquery('jamenglish', ?)", tsquery) when 'fans' From ac100e08983dd621ad119818c4713d868a7b1470 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 06:50:51 -0600 Subject: [PATCH 04/41] vtfs-988: fixing user text search to use musician --- ruby/lib/jam_ruby/models/search.rb | 13 +++++----- ruby/spec/jam_ruby/models/user_search_spec.rb | 26 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 58cca06bd..0395a3475 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -15,7 +15,7 @@ module JamRuby self.text_search({ SEARCH_TEXT_TYPE_ID => :fans, :query => txt }, user) end - def self.musicians_search(txt, user = nil) + def self.musician_search(txt, user = nil) self.text_search({ SEARCH_TEXT_TYPE_ID => :musicians, :query => txt }, user) end @@ -25,16 +25,15 @@ module JamRuby tsquery = Search.create_tsquery(params[:query]) return [] if tsquery.blank? - srch_type = params[SEARCH_TEXT_TYPE_ID].present? ? params[SEARCH_TEXT_TYPE_ID].to_s : '' - rel = case srch_type + rel = case params[SEARCH_TEXT_TYPE_ID].to_s when 'bands' - Band.where("name_tsv @@ to_tsquery('jamenglish', ?)", tsquery) + Band.scoped when 'fans' - User.fans.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery) + User.fans else - User.musicians.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery) + User.musicians end - @text_results = rel.limit(10) + @text_results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10) end def initialize(search_results=nil) diff --git a/ruby/spec/jam_ruby/models/user_search_spec.rb b/ruby/spec/jam_ruby/models/user_search_spec.rb index c45b37200..305493f23 100644 --- a/ruby/spec/jam_ruby/models/user_search_spec.rb +++ b/ruby/spec/jam_ruby/models/user_search_spec.rb @@ -9,7 +9,8 @@ describe User do end it "should allow search of one user" do - ws = User.search("Example User") + uu = FactoryGirl.create(:user, :musician => false) + ws = Search.musician_search("Example User") ws.length.should == 1 user_result = ws[0] user_result.first_name.should == @user.first_name @@ -19,20 +20,27 @@ describe User do user_result.musician.should == true end + it "should allow search of one fan" do + uu = FactoryGirl.create(:user, :musician => false) + ws = Search.fan_search(uu.name) + expect(ws.length).to be(1) + expect(ws[0].id).to eq(uu.id) + end + it "should delete user" do - ws = User.search("Example User") + ws = Search.musician_search("Example User") ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @user.destroy - ws = User.search("Example User") + ws = Search.musician_search("Example User") ws.length.should == 0 end it "should update user" do - ws = User.search("Example User") + ws = Search.musician_search("Example User") ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -41,10 +49,10 @@ describe User do @user.last_name = "more-junk" @user.save - ws = User.search("Example User") + ws = Search.musician_search("Example User") ws.length.should == 0 - ws = User.search("Bonus") + ws = Search.musician_search("Bonus") ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -55,7 +63,7 @@ describe User do @user2 = FactoryGirl.create(:user, first_name: "peaches", last_name: "test", email: "peach@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: true, city: "Apex", state: "NC", country: "US") - ws = User.search("pea") + ws = Search.musician_search("pea") ws.length.should == 1 user_result = ws[0] user_result.id.should == @user2.id @@ -65,14 +73,14 @@ describe User do @user3 = FactoryGirl.create(:user, first_name: "unconfirmed", last_name: "unconfirmed", email: "unconfirmed@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: false, city: "Apex", state: "NC", country: "US") - ws = User.search("unconfirmed") + ws = Search.musician_search("unconfirmed") ws.length.should == 1 # Ok, confirm the user, and see them show up @user3.email_confirmed = true @user3.save - ws = User.search("unconfirmed") + ws = Search.musician_search("unconfirmed") ws.length.should == 1 user_result = ws[0] user_result.id.should == @user3.id From 0279b05454fbfd478f1341c06f94ea5bad840264 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 08:59:09 -0600 Subject: [PATCH 05/41] vrfs-988: fixed text search return value --- ruby/lib/jam_ruby/models/search.rb | 43 ++++++++++++++++--- ruby/spec/jam_ruby/models/band_search_spec.rb | 38 ++++++++-------- ruby/spec/jam_ruby/models/user_search_spec.rb | 20 ++++----- web/app/views/api_search/index.rabl | 23 +++------- 4 files changed, 71 insertions(+), 53 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 0395a3475..15493e19c 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -1,7 +1,10 @@ module JamRuby + # not a active_record model; just a search result container class Search - attr_accessor :filter_results, :text_results + attr_accessor :filter_results, :text_results, :search_type + attr_accessor :user_counters, :page_num, :page_count + LIMIT = 10 SEARCH_TEXT_TYPES = [:musicians, :bands, :fans] @@ -20,18 +23,27 @@ module JamRuby end def self.text_search(params, user = nil) - return [] if params.blank? || params[:query].blank? || 2 > params[:query].length + srch = Search.new + unless (params.blank? || params[:query].blank? || 2 > params[:query].length) + srch.text_search(params, user) + end + srch + end + def text_search(params, user = nil) tsquery = Search.create_tsquery(params[:query]) return [] if tsquery.blank? rel = case params[SEARCH_TEXT_TYPE_ID].to_s when 'bands' - Band.scoped + @search_type = :bands + Band.scoped when 'fans' - User.fans + @search_type = :fans + User.fans else - User.musicians + @search_type = :musicians + User.musicians end @text_results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10) end @@ -59,8 +71,6 @@ module JamRuby args end - attr_accessor :user_counters, :page_num, :page_count - PARAM_MUSICIAN = :srch_m PARAM_BAND = :srch_b @@ -82,6 +92,8 @@ module JamRuby end def self.musician_filter(params={}, current_user=nil) + @search_type = :musicians_filter + rel = User.musicians unless (instrument = params[:instrument]).blank? rel = rel.joins("RIGHT JOIN musicians_instruments AS minst ON minst.user_id = users.id") @@ -180,6 +192,22 @@ module JamRuby public + def musicians_text? + :musicians == @search_type + end + + def fans_text? + :fans == @search_type + end + + def bands_text? + :bands == @search_type + end + + def is_filter? + @search_type == :musicians_filter || @search_type == :band_filter + end + def follow_count(musician) _count(musician, COUNT_FOLLOW) end @@ -224,6 +252,7 @@ module JamRuby end def self.band_filter(params={}, current_user=nil) + @search_type = :band_filter rel = Band.scoped unless (genre = params[:genre]).blank? diff --git a/ruby/spec/jam_ruby/models/band_search_spec.rb b/ruby/spec/jam_ruby/models/band_search_spec.rb index 6d3c07d1c..0a5c0f84a 100644 --- a/ruby/spec/jam_ruby/models/band_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_search_spec.rb @@ -13,7 +13,7 @@ describe User do end it "should allow search of one band with an exact match" do - ws = Search.band_search("Example Band") + ws = Search.band_search("Example Band").text_results ws.length.should == 1 band_result = ws[0] band_result.name.should == @band.name @@ -22,61 +22,61 @@ describe User do end it "should allow search of one band with partial matches" do - ws = Search.band_search("Ex") + ws = Search.band_search("Ex").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exa") + ws = Search.band_search("Exa").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exam") + ws = Search.band_search("Exam").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Examp") + ws = Search.band_search("Examp").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exampl") + ws = Search.band_search("Exampl").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Example") + ws = Search.band_search("Example").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Ba") + ws = Search.band_search("Ba").text_results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Ban") + ws = Search.band_search("Ban").text_results ws.length.should == 1 ws[0].id.should == @band.id end it "should not match mid-word searchs" do - ws = Search.band_search("xa") + ws = Search.band_search("xa").text_results ws.length.should == 0 - ws = Search.band_search("le") + ws = Search.band_search("le").text_results ws.length.should == 0 end it "should delete band" do - ws = Search.band_search("Example Band") + ws = Search.band_search("Example Band").text_results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @band.destroy # delete doesn't work; you have to use destroy. - ws = Search.band_search("Example Band") + ws = Search.band_search("Example Band").text_results ws.length.should == 0 end it "should update band" do - ws = Search.band_search("Example Band") + ws = Search.band_search("Example Band").text_results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -84,10 +84,10 @@ describe User do @band.name = "bonus-stuff" @band.save - ws = Search.band_search("Example Band") + ws = Search.band_search("Example Band").text_results ws.length.should == 0 - ws = Search.band_search("Bonus") + ws = Search.band_search("Bonus").text_results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -96,7 +96,7 @@ describe User do it "should tokenize correctly" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Search.band_search("pea") + ws = Search.band_search("pea").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id @@ -105,12 +105,12 @@ describe User do it "should not return anything with a 1 character search" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Search.band_search("pe") + ws = Search.band_search("pe").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id - ws = Search.band_search("p") + ws = Search.band_search("p").text_results ws.length.should == 0 end end diff --git a/ruby/spec/jam_ruby/models/user_search_spec.rb b/ruby/spec/jam_ruby/models/user_search_spec.rb index 305493f23..76662cdba 100644 --- a/ruby/spec/jam_ruby/models/user_search_spec.rb +++ b/ruby/spec/jam_ruby/models/user_search_spec.rb @@ -10,7 +10,7 @@ describe User do it "should allow search of one user" do uu = FactoryGirl.create(:user, :musician => false) - ws = Search.musician_search("Example User") + ws = Search.musician_search("Example User").text_results ws.length.should == 1 user_result = ws[0] user_result.first_name.should == @user.first_name @@ -22,25 +22,25 @@ describe User do it "should allow search of one fan" do uu = FactoryGirl.create(:user, :musician => false) - ws = Search.fan_search(uu.name) + ws = Search.fan_search(uu.name).text_results expect(ws.length).to be(1) expect(ws[0].id).to eq(uu.id) end it "should delete user" do - ws = Search.musician_search("Example User") + ws = Search.musician_search("Example User").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @user.destroy - ws = Search.musician_search("Example User") + ws = Search.musician_search("Example User").text_results ws.length.should == 0 end it "should update user" do - ws = Search.musician_search("Example User") + ws = Search.musician_search("Example User").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -49,10 +49,10 @@ describe User do @user.last_name = "more-junk" @user.save - ws = Search.musician_search("Example User") + ws = Search.musician_search("Example User").text_results ws.length.should == 0 - ws = Search.musician_search("Bonus") + ws = Search.musician_search("Bonus").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -63,7 +63,7 @@ describe User do @user2 = FactoryGirl.create(:user, first_name: "peaches", last_name: "test", email: "peach@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: true, city: "Apex", state: "NC", country: "US") - ws = Search.musician_search("pea") + ws = Search.musician_search("pea").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user2.id @@ -73,14 +73,14 @@ describe User do @user3 = FactoryGirl.create(:user, first_name: "unconfirmed", last_name: "unconfirmed", email: "unconfirmed@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: false, city: "Apex", state: "NC", country: "US") - ws = Search.musician_search("unconfirmed") + ws = Search.musician_search("unconfirmed").text_results ws.length.should == 1 # Ok, confirm the user, and see them show up @user3.email_confirmed = true @user3.save - ws = Search.musician_search("unconfirmed") + ws = Search.musician_search("unconfirmed").text_results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user3.id diff --git a/web/app/views/api_search/index.rabl b/web/app/views/api_search/index.rabl index e7102cee9..e3dc98bb9 100644 --- a/web/app/views/api_search/index.rabl +++ b/web/app/views/api_search/index.rabl @@ -1,13 +1,13 @@ object @search -if @search.bands.present? - child(:bands => :bands) { +if @search.bands_text.present? + child(:bands => @search.text_results) { attributes :id, :name, :location, :photo_url, :logo_url } end -if @search.musicians.present? - child(:musicians => :musicians) { +if @search.musicians_text? + child(:musicians => @search.text_results) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |musician| @@ -88,8 +88,8 @@ if @search.bands_filter.present? } end -unless @search.fans.nil? || @search.fans.size == 0 - child(:fans => :fans) { +if @search.fans_text? + child(:fans => @search.text_results) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |fan| @@ -98,14 +98,3 @@ unless @search.fans.nil? || @search.fans.size == 0 } end -unless @search.recordings.nil? || @search.recordings.size == 0 - child(:recordings => :recordings) { - attributes :id, :name - } -end - -unless @search.friends.nil? || @search.friends.size == 0 - child(:friends => :friends) { - attributes :id, :first_name, :last_name, :name, :location, :email, :online, :photo_url, :musician - } -end From ecdfde2cdbb8dac55d5fb6cc7dae382276cd1ee9 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 09:12:26 -0600 Subject: [PATCH 06/41] vrfs988: sync api wrapper with search model --- ruby/lib/jam_ruby/models/search.rb | 14 +++++++++----- web/app/views/api_search/index.rabl | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 15493e19c..70761e4d8 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -192,20 +192,24 @@ module JamRuby public - def musicians_text? + def musicians_text_search? :musicians == @search_type end - def fans_text? + def fans_text_search? :fans == @search_type end - def bands_text? + def bands_text_search? :bands == @search_type end - def is_filter? - @search_type == :musicians_filter || @search_type == :band_filter + def musicians_filter_search? + :musicians_filter == @search_type + end + + def bands_filter_search? + :band_filter == @search_type end def follow_count(musician) diff --git a/web/app/views/api_search/index.rabl b/web/app/views/api_search/index.rabl index e3dc98bb9..040825576 100644 --- a/web/app/views/api_search/index.rabl +++ b/web/app/views/api_search/index.rabl @@ -1,13 +1,13 @@ object @search -if @search.bands_text.present? - child(:bands => @search.text_results) { +if @search.bands_text_search? + child(:text_results => :bands) { attributes :id, :name, :location, :photo_url, :logo_url } end -if @search.musicians_text? - child(:musicians => @search.text_results) { +if @search.musicians_text_search? + child(:text_results => :musicians) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |musician| @@ -20,7 +20,7 @@ if @search.musicians_text? } end -if @search.musicians_filter.present? +if @search.musicians_filter_search? node :city do |user| current_user.try(:location) @@ -30,7 +30,7 @@ if @search.musicians_filter.present? @search.page_count end - child(:musicians_filter => :musicians) { + child(:filter_results => :musicians) { attributes :id, :first_name, :last_name, :name, :city, :state, :country, :email, :online, :musician, :photo_url, :biography node :is_friend do |musician| @@ -58,13 +58,13 @@ if @search.musicians_filter.present? } end -if @search.bands_filter.present? +if @search.bands_filter_search? node :page_count do |foo| @search.page_count end - child(:bands_filter => :bands) { + child(:filter_results => :bands) { attributes :id, :name, :city, :state, :country, :email, :photo_url, :biography, :logo_url node :is_following do |band| @@ -88,8 +88,8 @@ if @search.bands_filter.present? } end -if @search.fans_text? - child(:fans => @search.text_results) { +if @search.fans_text_search? + child(:text_results => :fans) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |fan| From 87ae9d97dfb268c456901872d3965c0de950d585 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 09:27:56 -0600 Subject: [PATCH 07/41] vrfs988: refactored search with one accessor for text and filter type searches --- ruby/lib/jam_ruby/models/search.rb | 28 +++++++------- ruby/spec/jam_ruby/models/band_search_spec.rb | 38 +++++++++---------- ruby/spec/jam_ruby/models/user_search_spec.rb | 20 +++++----- web/app/views/api_search/index.rabl | 10 ++--- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index 70761e4d8..ec9bba695 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -2,7 +2,7 @@ module JamRuby # not a active_record model; just a search result container class Search - attr_accessor :filter_results, :text_results, :search_type + attr_accessor :results, :search_type attr_accessor :user_counters, :page_num, :page_count LIMIT = 10 @@ -45,16 +45,16 @@ module JamRuby @search_type = :musicians User.musicians end - @text_results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10) + @results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10) end def initialize(search_results=nil) - @text_results, @filter_results = [], [] + @results = [] self end def self.create_tsquery(query) - return nil if query.nil? || query.length == 0 + return nil if query.blank? search_terms = query.split return nil if search_terms.length == 0 @@ -147,14 +147,14 @@ module JamRuby COUNT_SESSION = :count_session COUNTERS = [COUNT_FRIEND, COUNT_FOLLOW, COUNT_RECORD, COUNT_SESSION] - def musician_results_for_user(results, user) - @filter_results = results + def musician_results_for_user(_results, user) + @results = _results if user - @user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh } - mids = "'#{@filter_results.map(&:id).join("','")}'" + @user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh } + mids = "'#{@results.map(&:id).join("','")}'" # this gets counts for each search result on friends/follows/records/sessions - results.each do |uu| + @results.each do |uu| counters = { } counters[COUNT_FRIEND] = Friendship.where(:user_id => uu.id).count counters[COUNT_FOLLOW] = UserFollowing.where(:user_id => uu.id).count @@ -295,14 +295,14 @@ module JamRuby srch.band_results_for_user(objs, current_user) end - def band_results_for_user(results, user) - @filter_results = results + def band_results_for_user(_results, user) + @results = _results if user - @user_counters = results.inject({}) { |hh,val| hh[val.id] = []; hh } - mids = "'#{@filter_results.map(&:id).join("','")}'" + @user_counters = @results.inject({}) { |hh,val| hh[val.id] = []; hh } + mids = "'#{@results.map(&:id).join("','")}'" # this gets counts for each search result - results.each do |bb| + @results.each do |bb| counters = { } counters[COUNT_FOLLOW] = BandFollowing.where(:band_id => bb.id).count counters[COUNT_RECORD] = Recording.where(:band_id => bb.id).count diff --git a/ruby/spec/jam_ruby/models/band_search_spec.rb b/ruby/spec/jam_ruby/models/band_search_spec.rb index 0a5c0f84a..5d693ba5f 100644 --- a/ruby/spec/jam_ruby/models/band_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_search_spec.rb @@ -13,7 +13,7 @@ describe User do end it "should allow search of one band with an exact match" do - ws = Search.band_search("Example Band").text_results + ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] band_result.name.should == @band.name @@ -22,61 +22,61 @@ describe User do end it "should allow search of one band with partial matches" do - ws = Search.band_search("Ex").text_results + ws = Search.band_search("Ex").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exa").text_results + ws = Search.band_search("Exa").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exam").text_results + ws = Search.band_search("Exam").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Examp").text_results + ws = Search.band_search("Examp").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Exampl").text_results + ws = Search.band_search("Exampl").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Example").text_results + ws = Search.band_search("Example").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Ba").text_results + ws = Search.band_search("Ba").results ws.length.should == 1 ws[0].id.should == @band.id - ws = Search.band_search("Ban").text_results + ws = Search.band_search("Ban").results ws.length.should == 1 ws[0].id.should == @band.id end it "should not match mid-word searchs" do - ws = Search.band_search("xa").text_results + ws = Search.band_search("xa").results ws.length.should == 0 - ws = Search.band_search("le").text_results + ws = Search.band_search("le").results ws.length.should == 0 end it "should delete band" do - ws = Search.band_search("Example Band").text_results + ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @band.destroy # delete doesn't work; you have to use destroy. - ws = Search.band_search("Example Band").text_results + ws = Search.band_search("Example Band").results ws.length.should == 0 end it "should update band" do - ws = Search.band_search("Example Band").text_results + ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -84,10 +84,10 @@ describe User do @band.name = "bonus-stuff" @band.save - ws = Search.band_search("Example Band").text_results + ws = Search.band_search("Example Band").results ws.length.should == 0 - ws = Search.band_search("Bonus").text_results + ws = Search.band_search("Bonus").results ws.length.should == 1 band_result = ws[0] band_result.id.should == @band.id @@ -96,7 +96,7 @@ describe User do it "should tokenize correctly" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Search.band_search("pea").text_results + ws = Search.band_search("pea").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id @@ -105,12 +105,12 @@ describe User do it "should not return anything with a 1 character search" do @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - ws = Search.band_search("pe").text_results + ws = Search.band_search("pe").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @band2.id - ws = Search.band_search("p").text_results + ws = Search.band_search("p").results ws.length.should == 0 end end diff --git a/ruby/spec/jam_ruby/models/user_search_spec.rb b/ruby/spec/jam_ruby/models/user_search_spec.rb index 76662cdba..d9c70f743 100644 --- a/ruby/spec/jam_ruby/models/user_search_spec.rb +++ b/ruby/spec/jam_ruby/models/user_search_spec.rb @@ -10,7 +10,7 @@ describe User do it "should allow search of one user" do uu = FactoryGirl.create(:user, :musician => false) - ws = Search.musician_search("Example User").text_results + ws = Search.musician_search("Example User").results ws.length.should == 1 user_result = ws[0] user_result.first_name.should == @user.first_name @@ -22,25 +22,25 @@ describe User do it "should allow search of one fan" do uu = FactoryGirl.create(:user, :musician => false) - ws = Search.fan_search(uu.name).text_results + ws = Search.fan_search(uu.name).results expect(ws.length).to be(1) expect(ws[0].id).to eq(uu.id) end it "should delete user" do - ws = Search.musician_search("Example User").text_results + ws = Search.musician_search("Example User").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @user.destroy - ws = Search.musician_search("Example User").text_results + ws = Search.musician_search("Example User").results ws.length.should == 0 end it "should update user" do - ws = Search.musician_search("Example User").text_results + ws = Search.musician_search("Example User").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -49,10 +49,10 @@ describe User do @user.last_name = "more-junk" @user.save - ws = Search.musician_search("Example User").text_results + ws = Search.musician_search("Example User").results ws.length.should == 0 - ws = Search.musician_search("Bonus").text_results + ws = Search.musician_search("Bonus").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user.id @@ -63,7 +63,7 @@ describe User do @user2 = FactoryGirl.create(:user, first_name: "peaches", last_name: "test", email: "peach@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: true, city: "Apex", state: "NC", country: "US") - ws = Search.musician_search("pea").text_results + ws = Search.musician_search("pea").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user2.id @@ -73,14 +73,14 @@ describe User do @user3 = FactoryGirl.create(:user, first_name: "unconfirmed", last_name: "unconfirmed", email: "unconfirmed@example.com", password: "foobar", password_confirmation: "foobar", musician: true, email_confirmed: false, city: "Apex", state: "NC", country: "US") - ws = Search.musician_search("unconfirmed").text_results + ws = Search.musician_search("unconfirmed").results ws.length.should == 1 # Ok, confirm the user, and see them show up @user3.email_confirmed = true @user3.save - ws = Search.musician_search("unconfirmed").text_results + ws = Search.musician_search("unconfirmed").results ws.length.should == 1 user_result = ws[0] user_result.id.should == @user3.id diff --git a/web/app/views/api_search/index.rabl b/web/app/views/api_search/index.rabl index 040825576..a2e6e218d 100644 --- a/web/app/views/api_search/index.rabl +++ b/web/app/views/api_search/index.rabl @@ -1,13 +1,13 @@ object @search if @search.bands_text_search? - child(:text_results => :bands) { + child(:results => :bands) { attributes :id, :name, :location, :photo_url, :logo_url } end if @search.musicians_text_search? - child(:text_results => :musicians) { + child(:results => :musicians) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |musician| @@ -30,7 +30,7 @@ if @search.musicians_filter_search? @search.page_count end - child(:filter_results => :musicians) { + child(:results => :musicians) { attributes :id, :first_name, :last_name, :name, :city, :state, :country, :email, :online, :musician, :photo_url, :biography node :is_friend do |musician| @@ -64,7 +64,7 @@ if @search.bands_filter_search? @search.page_count end - child(:filter_results => :bands) { + child(:results => :bands) { attributes :id, :name, :city, :state, :country, :email, :photo_url, :biography, :logo_url node :is_following do |band| @@ -89,7 +89,7 @@ if @search.bands_filter_search? end if @search.fans_text_search? - child(:text_results => :fans) { + child(:results => :fans) { attributes :id, :first_name, :last_name, :name, :location, :photo_url node :is_friend do |fan| From cdb2b9fab93288251fa5f0455adcd7bc9ac9ac83 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 20:18:20 -0600 Subject: [PATCH 08/41] vrfs988: sidebar/searchresults --- web/app/assets/javascripts/searchResults.js | 135 +++++++++++------- web/app/assets/javascripts/sidebar.js | 38 +++-- web/app/assets/javascripts/utils.js | 1 + .../stylesheets/client/searchResults.css.scss | 1 + web/app/views/api_search/index.rabl | 2 + web/app/views/clients/_searchResults.html.erb | 20 ++- 6 files changed, 128 insertions(+), 69 deletions(-) diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index 3d164fdce..32e335ab5 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -8,6 +8,14 @@ var instrument_logo_map = context.JK.getInstrumentIconMap24(); + function initializeSearchNavLinks() { + $('.search-nav').click(function() { + $('.search-nav.active').removeClass('active'); + $(this).addClass('active'); + setTimeout(search, 100); + }); + } + function beforeShow(data) { var query = data.query; } @@ -15,20 +23,31 @@ function afterShow(data) { } - function search(evt) { - evt.stopPropagation(); + function selectedSearchType() { + var srchtype = $('.search-nav.active').data('search_text_type'); + if (srchtype === undefined) { + srchtype = $('#search_text_type').val(); + } + return srchtype; + } + function search(evt) { + if (evt) { + evt.stopPropagation(); + } $('#search-results').empty(); var query = $('#search-input').val(); - context.location = '#/searchResults/:' + query; + if (query) { + context.location = '#/searchResults/:' + query; + } else { + query = $('#query').html(); + } - logger.debug('query=' + query); if (query !== '') { - $('#query').html(query + "\""); + $('#query').html(query); + query += '&search_text_type='+selectedSearchType(); context.JK.search(query, app, onSearchSuccess); - } - - else { + } else { $('#result-count').html(''); $('#query').html(''); } @@ -37,53 +56,70 @@ } function onSearchSuccess(response) { + var resultCount=0; + if (response.search_type === 'musicians') { + resultCount = response.musicians.length; + // TODO: generalize this for each search result type (band, musician, et. al.) + $.each(response.musicians, function(index, val) { + // fill in template for Connect pre-click + var template = $('#template-search-musicians-result').html(); + var searchResultHtml = context.JK.fillTemplate(template, { + userId: val.id, + avatar_url: context.JK.resolveAvatarUrl(val.photo_url), + profile_url: "/#/profile/" + val.id, + userName: val.name, + location: val.location, + instruments: getInstrumentHtml(val.instruments) + }); - // TODO: generalize this for each search result type (band, musician, recordings, et. al.) - $.each(response.musicians, function(index, val) { - // fill in template for Connect pre-click - var template = $('#template-search-result').html(); - var searchResultHtml = context.JK.fillTemplate(template, { - userId: val.id, - avatar_url: context.JK.resolveAvatarUrl(val.photo_url), - profile_url: "/#/profile/" + val.id, - userName: val.name, - location: val.location, - instruments: getInstrumentHtml(val.instruments) - }); + $('#search-results').append(searchResultHtml); - $('#search-results').append(searchResultHtml); + // fill in template for Connect post-click + template = $('#template-invitation-sent').html(); + var invitationSentHtml = context.JK.fillTemplate(template, { + userId: val.id, + first_name: val.first_name, + profile_url: "/#/profile/" + val.id + }); - // fill in template for Connect post-click - template = $('#template-invitation-sent').html(); - var invitationSentHtml = context.JK.fillTemplate(template, { - userId: val.id, - first_name: val.first_name, - profile_url: "/#/profile/" + val.id - }); + $('#search-results').append(invitationSentHtml); - $('#search-results').append(invitationSentHtml); + // initialize visibility of the divs + $('div[user-id=' + val.id + '].search-connected').hide(); + $('div[user-id=' + val.id + '].search-result').show(); - // initialize visibility of the divs - $('div[user-id=' + val.id + '].search-connected').hide(); - $('div[user-id=' + val.id + '].search-result').show(); - - // wire up button click handler if search result is not a friend or the current user - if (!val.is_friend && val.id !== context.JK.currentUserId) { - $('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest); - } - else { - $('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide(); - } - }); - - var resultCount = response.musicians.length; - $('#result-count').html(resultCount); - - if (resultCount === 1) { - $('#result-count').append(" Result for \""); + // wire up button click handler if search result is not a friend or the current user + if (!val.is_friend && val.id !== context.JK.currentUserId) { + $('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest); + } + else { + $('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide(); + } + }); + } else if (response.search_type === 'bands') { + } else if (response.search_type === 'fans') { + resultCount = response.fans.length; + $.each(response.fans, function(index, val) { + // fill in template for Connect pre-click + var template = $('#template-search-fans-result').html(); + var searchResultHtml = context.JK.fillTemplate(template, { + userId: val.id, + avatar_url: context.JK.resolveAvatarUrl(val.photo_url), + profile_url: "/#/profile/" + val.id, + userName: val.name, + location: val.location + }); + $('#search-results').append(searchResultHtml); + // initialize visibility of the divs + $('div[user-id=' + val.id + '].search-result').show(); + }); } - else { - $('#result-count').append(" Results for \""); + + $('#result-count').html(resultCount); + if (resultCount === 1) { + $('#result-count').append(" Result for: "); + } else { + $('#result-count').append(" Results for: "); } } @@ -124,6 +160,7 @@ }; app.bindScreen('searchResults', screenBindings); events(); + initializeSearchNavLinks(); }; }; diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index fe7976ecb..21ca0f8d2 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -9,6 +9,12 @@ var rest = context.JK.Rest(); var invitationDialog = null; + function initializeSearchPanel() { + $('#search_text_type').change(function() { + searchForInput(); + }); + } + function initializeFriendsPanel() { ///////////////////////////////////////////////////////////// @@ -260,7 +266,7 @@ } function onSearchSuccess(response) { - + logger.debug(response); // TODO: generalize this for each search result type (band, musician, recordings, et. al.) $.each(response.musicians, function(index, val) { // fill in template for Connect pre-click @@ -412,6 +418,19 @@ function inviteHoverOut() { $('.invitation-button-holder').slideUp(); } + + function searchForInput() { + var query = $('#search-input').val(); + // logger.debug("query=" + query); + if (query === '') { + return hideSearchResults(); + } + if (query.length > 2) { + query += '&search_text_type='+$('#search_text_type').val(); + emptySearchResults(); + search(query); + } + } function events() { $('#search-input').keyup(function(evt) { @@ -420,24 +439,12 @@ if (evt.which === 13) { return hideSearchResults(); } - // ESCAPE KEY if (evt.which === 27) { return hideSearchResults(); } - - var query = $('#search-input').val(); - logger.debug("query=" + query); - - if (query === '') { - return hideSearchResults(); - } - if (query.length > 2) { - query += '&srch_t='+$('#search_text_type').val(); - emptySearchResults(); - search(query); - } - }, 1000); + searchForInput(); + }, 500); }); $('#sidebar-search-expand').click(function(evt) { @@ -923,6 +930,7 @@ this.initialize = function(invitationDialogInstance) { events(); + initializeSearchPanel(); initializeFriendsPanel(); initializeChatPanel(); initializeNotificationsPanel(); diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 2d9ec36a1..030e94dfb 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -287,6 +287,7 @@ } context.JK.search = function(query, app, callback) { + logger.debug("search: "+query) $.ajax({ type: "GET", dataType: "json", diff --git a/web/app/assets/stylesheets/client/searchResults.css.scss b/web/app/assets/stylesheets/client/searchResults.css.scss index 6734ec71b..840666875 100644 --- a/web/app/assets/stylesheets/client/searchResults.css.scss +++ b/web/app/assets/stylesheets/client/searchResults.css.scss @@ -4,6 +4,7 @@ background-color:#4c4c4c; min-height:20px; overflow-x:hidden; + margin-top: 30px; } a.search-nav { diff --git a/web/app/views/api_search/index.rabl b/web/app/views/api_search/index.rabl index a2e6e218d..177cab95f 100644 --- a/web/app/views/api_search/index.rabl +++ b/web/app/views/api_search/index.rabl @@ -1,5 +1,7 @@ object @search +node :search_type do |ss| ss.search_type end + if @search.bands_text_search? child(:results => :bands) { attributes :id, :name, :location, :photo_url, :logo_url diff --git a/web/app/views/clients/_searchResults.html.erb b/web/app/views/clients/_searchResults.html.erb index 6377a26a5..cdb148294 100644 --- a/web/app/views/clients/_searchResults.html.erb +++ b/web/app/views/clients/_searchResults.html.erb @@ -12,10 +12,9 @@
@@ -24,7 +23,7 @@
- + + + From a4816fecfd5c0a3e966e7a8954a76a11a56c8e2e Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 22:44:58 -0600 Subject: [PATCH 09/41] vrfs988: refactored search results processing --- web/app/assets/javascripts/searchResults.js | 108 ++++++++++++++------ web/app/assets/javascripts/sidebar.js | 67 +----------- 2 files changed, 78 insertions(+), 97 deletions(-) diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index 32e335ab5..afd4541cc 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -55,46 +55,69 @@ return false; } - function onSearchSuccess(response) { + function onSearchSuccess(response) { + context.JK.SearchResultScreen.searchResults(response, false) + } + + context.JK.SearchResultScreen.searchResults = function(response, isSidebar) { var resultCount=0; if (response.search_type === 'musicians') { resultCount = response.musicians.length; // TODO: generalize this for each search result type (band, musician, et. al.) + var selector = isSidebar ? "#template-sidebar-search-result" : "#template-search-musicians-result"; $.each(response.musicians, function(index, val) { // fill in template for Connect pre-click - var template = $('#template-search-musicians-result').html(); - var searchResultHtml = context.JK.fillTemplate(template, { + var template = $(selector).html(); + var args = { userId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), profile_url: "/#/profile/" + val.id, userName: val.name, - location: val.location, - instruments: getInstrumentHtml(val.instruments) - }); - - $('#search-results').append(searchResultHtml); + location: val.location + }; + if (!isSidebar) { + args['instruments'] = getInstrumentHtml(val.instruments); + } + selector = isSidebar ? '#sidebar-search-results' : '#search-results'; + $(selector).append(context.JK.fillTemplate(template, args)); // fill in template for Connect post-click - template = $('#template-invitation-sent').html(); + selector = isSidebar ? '#template-sidebar-invitation-sent' : '#template-invitation-sent'; + template = $(selector).html(); var invitationSentHtml = context.JK.fillTemplate(template, { userId: val.id, first_name: val.first_name, profile_url: "/#/profile/" + val.id }); - $('#search-results').append(invitationSentHtml); + selector = isSidebar ? '#sidebar-search-results' : '#search-results'; + $(selector).append(invitationSentHtml); // initialize visibility of the divs - $('div[user-id=' + val.id + '].search-connected').hide(); - $('div[user-id=' + val.id + '].search-result').show(); + if (isSidebar) { + $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-connected').hide(); + $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-result').show(); + } else { + $('div[user-id=' + val.id + '].search-connected').hide(); + $('div[user-id=' + val.id + '].search-result').show(); + } // wire up button click handler if search result is not a friend or the current user - if (!val.is_friend && val.id !== context.JK.currentUserId) { - $('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest); - } - else { - $('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide(); - } + if (isSidebar) { + var $sidebar = $('div[layout=sidebar] div[user-id=' + val.id + ']'); + if (!val.is_friend && val.id !== context.JK.currentUserId) { + $sidebar.find('.btn-connect-friend').click(sendFriendRequest); + } else { + // hide the button if the search result is already a friend + $sidebar.find('.btn-connect-friend').hide(); + } + } else { + if (!val.is_friend && val.id !== context.JK.currentUserId) { + $('div[user-id=' + val.id + ']').find('.btn-connect-friend').click(sendFriendRequest); + } else { + $('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide(); + } + } }); } else if (response.search_type === 'bands') { } else if (response.search_type === 'fans') { @@ -114,26 +137,45 @@ $('div[user-id=' + val.id + '].search-result').show(); }); } + if (isSidebar) { + // show header + $('#sidebar-search-header').show(); + // hide panels + $('[layout-panel="contents"]').hide(); + $('[layout-panel="contents"]').css({"height": "1px"}); + // resize search results area + $('#sidebar-search-results').height(context.JK.Sidebar.getHeight() + 'px'); + } else { + $('#result-count').html(resultCount); + if (resultCount === 1) { + $('#result-count').append(" Result for: "); + } else { + $('#result-count').append(" Results for: "); + } + } + }; - $('#result-count').html(resultCount); - if (resultCount === 1) { - $('#result-count').append(" Result for: "); - } else { - $('#result-count').append(" Results for: "); - } - } + function friendRequestCallbackSidebar(userId) { + // toggle the pre-click and post-click divs + $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-connected').show(); + $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-result').hide(); + } - function friendRequestCallback(userId) { - // toggle the pre-click and post-click divs - $('div[user-id=' + userId + '].search-connected').show(); - $('div[user-id=' + userId + '].search-result').hide(); - } + function friendRequestCallbackSearchResults(userId) { + // toggle the pre-click and post-click divs + $('div[user-id=' + userId + '].search-connected').show(); + $('div[user-id=' + userId + '].search-result').hide(); + } - function sendFriendRequest(evt) { + function sendFriendRequest(evt) { evt.stopPropagation(); var userId = $(this).parent().attr('user-id'); - context.JK.sendFriendRequest(app, userId, friendRequestCallback); - } + if ($(this).closest('#sidebar-search-results')) { + context.JK.sendFriendRequest(app, userId, friendRequestCallbackSidebar); + } else { + context.JK.sendFriendRequest(app, userId, friendRequestCallbackSearchResults); + } + } function getInstrumentHtml(instruments) { var instrumentLogoHtml = ''; diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index 21ca0f8d2..7500adce2 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -258,7 +258,6 @@ } function search(query) { - logger.debug('query=' + query); if (query !== '') { context.JK.search(query, app, onSearchSuccess); @@ -266,58 +265,10 @@ } function onSearchSuccess(response) { - logger.debug(response); - // TODO: generalize this for each search result type (band, musician, recordings, et. al.) - $.each(response.musicians, function(index, val) { - // fill in template for Connect pre-click - var template = $('#template-sidebar-search-result').html(); - var searchResultHtml = context.JK.fillTemplate(template, { - userId: val.id, - avatar_url: context.JK.resolveAvatarUrl(val.photo_url), - profile_url: "/#/profile/" + val.id, - userName: val.name, - location: val.location - }); - - $('#sidebar-search-results').append(searchResultHtml); - - // fill in template for Connect post-click - template = $('#template-sidebar-invitation-sent').html(); - var invitationSentHtml = context.JK.fillTemplate(template, { - userId: val.id, - first_name: val.first_name, - profile_url: "/#/profile/" + val.id - }); - - $('#sidebar-search-results').append(invitationSentHtml); - - // initialize visibility of the divs - $('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-connected').hide(); - $('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-result').show(); - - // wire up button click handler if search result is not a friend or the current user - var $sidebar = $('div[layout=sidebar] div[user-id=' + val.id + ']'); - if (!val.is_friend && val.id !== context.JK.currentUserId) { - $sidebar.find('.btn-connect-friend').click(sendFriendRequest); - } - // hide the button if the search result is already a friend - else { - $sidebar.find('.btn-connect-friend').hide(); - } - }); - - // show header - $('#sidebar-search-header').show(); - - // hide panels - $('[layout-panel="contents"]').hide(); - $('[layout-panel="contents"]').css({"height": "1px"}); - - // resize search results area - $('#sidebar-search-results').height(getHeight() + 'px'); + context.JK.SearchResultScreen.searchResults(response, true) } - function getHeight() { + context.JK.Sidebar.getHeight = function() { // TODO: refactor this - copied from layout.js var sidebarHeight = $(context).height() - 75 - 2 * 60 + $('[layout-sidebar-expander]').height(); var combinedHeaderHeight = $('[layout-panel="contents"]').length * 36; @@ -330,7 +281,7 @@ function showFriendsPanel() { var $expandedPanelContents = $('[layout-id="panelFriends"] [layout-panel="contents"]'); - var expandedPanelHeight = getHeight(); + var expandedPanelHeight = context.JK.Sidebar.getHeight(); // hide all other contents $('[layout-panel="contents"]').hide(); @@ -341,18 +292,6 @@ $expandedPanelContents.animate({"height": expandedPanelHeight + "px"}, 400); } - function friendRequestCallback(userId) { - // toggle the pre-click and post-click divs - $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-connected').show(); - $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-result').hide(); - } - - function sendFriendRequest(evt) { - evt.stopPropagation(); - var userId = $(this).parent().attr('user-id'); - context.JK.sendFriendRequest(app, userId, friendRequestCallback); - } - function hideSearchResults() { emptySearchResults(); $('#search-input').val(''); From da980ce699d54e93b32f4e9656b9c9d391821537 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 11 Jan 2014 23:34:23 -0600 Subject: [PATCH 10/41] vrfs988: refactoring search results; added fans/bands result template handling --- ruby/lib/jam_ruby/models/search.rb | 1 + web/app/assets/javascripts/searchResults.js | 58 ++++++++++++------- web/app/views/clients/_searchResults.html.erb | 14 ++++- web/app/views/clients/_sidebar.html.erb | 18 +++++- 4 files changed, 67 insertions(+), 24 deletions(-) diff --git a/ruby/lib/jam_ruby/models/search.rb b/ruby/lib/jam_ruby/models/search.rb index ec9bba695..8a213e49a 100644 --- a/ruby/lib/jam_ruby/models/search.rb +++ b/ruby/lib/jam_ruby/models/search.rb @@ -46,6 +46,7 @@ module JamRuby User.musicians end @results = rel.where("(name_tsv @@ to_tsquery('jamenglish', ?))", tsquery).limit(10) + @results end def initialize(search_results=nil) diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index afd4541cc..4091d832a 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -59,12 +59,23 @@ context.JK.SearchResultScreen.searchResults(response, false) } + function resultDivVisibility(val, isSidebar) { + if (isSidebar) { + $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-connected').hide(); + $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-result').show(); + } else { + $('div[user-id=' + val.id + '].search-connected').hide(); + $('div[user-id=' + val.id + '].search-result').show(); + } + } + context.JK.SearchResultScreen.searchResults = function(response, isSidebar) { var resultCount=0; + var selector; if (response.search_type === 'musicians') { resultCount = response.musicians.length; // TODO: generalize this for each search result type (band, musician, et. al.) - var selector = isSidebar ? "#template-sidebar-search-result" : "#template-search-musicians-result"; + selector = isSidebar ? "#template-musicians-sidebar-search-result" : "#template-musicians-search-result"; $.each(response.musicians, function(index, val) { // fill in template for Connect pre-click var template = $(selector).html(); @@ -73,11 +84,9 @@ avatar_url: context.JK.resolveAvatarUrl(val.photo_url), profile_url: "/#/profile/" + val.id, userName: val.name, - location: val.location + location: val.location, + instruments: getInstrumentHtml(val.instruments) }; - if (!isSidebar) { - args['instruments'] = getInstrumentHtml(val.instruments); - } selector = isSidebar ? '#sidebar-search-results' : '#search-results'; $(selector).append(context.JK.fillTemplate(template, args)); @@ -93,16 +102,7 @@ selector = isSidebar ? '#sidebar-search-results' : '#search-results'; $(selector).append(invitationSentHtml); - // initialize visibility of the divs - if (isSidebar) { - $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-connected').hide(); - $('div[layout=sidebar user-id=' + val.id + '].sidebar-search-result').show(); - } else { - $('div[user-id=' + val.id + '].search-connected').hide(); - $('div[user-id=' + val.id + '].search-result').show(); - } - - // wire up button click handler if search result is not a friend or the current user + // wire up button click handler if search result is not a friend or the current use if (isSidebar) { var $sidebar = $('div[layout=sidebar] div[user-id=' + val.id + ']'); if (!val.is_friend && val.id !== context.JK.currentUserId) { @@ -118,13 +118,14 @@ $('div[user-id=' + val.id + ']').find('.btn-connect-friend').hide(); } } + resultDivVisibility(val, isSidebar); }); } else if (response.search_type === 'bands') { - } else if (response.search_type === 'fans') { - resultCount = response.fans.length; - $.each(response.fans, function(index, val) { + resultCount = response.bands.length; + $.each(response.bands, function(index, val) { // fill in template for Connect pre-click - var template = $('#template-search-fans-result').html(); + selector = isSidebar ? "#template-bands-sidebar-search-result" : "#template-bands-search-result"; + var template = $(selector).html(); var searchResultHtml = context.JK.fillTemplate(template, { userId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), @@ -133,8 +134,23 @@ location: val.location }); $('#search-results').append(searchResultHtml); - // initialize visibility of the divs - $('div[user-id=' + val.id + '].search-result').show(); + resultDivVisibility(val, isSidebar); + }); + } else if (response.search_type === 'fans') { + resultCount = response.fans.length; + $.each(response.fans, function(index, val) { + // fill in template for Connect pre-click + selector = isSidebar ? "#template-fans-sidebar-search-result" : "#template-fans-search-result"; + var template = $(selector).html(); + var searchResultHtml = context.JK.fillTemplate(template, { + userId: val.id, + avatar_url: context.JK.resolveAvatarUrl(val.photo_url), + profile_url: "/#/profile/" + val.id, + userName: val.name, + location: val.location + }); + $('#search-results').append(searchResultHtml); + resultDivVisibility(val, isSidebar); }); } if (isSidebar) { diff --git a/web/app/views/clients/_searchResults.html.erb b/web/app/views/clients/_searchResults.html.erb index cdb148294..ea9238448 100644 --- a/web/app/views/clients/_searchResults.html.erb +++ b/web/app/views/clients/_searchResults.html.erb @@ -23,7 +23,7 @@ - - + + + + From 1276c66bd3c62a69eab5b4f3af49c991ac1d1dbc Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 02:11:54 -0600 Subject: [PATCH 17/41] vrfs988: fixed sync bugs in searchResults --- web/app/assets/javascripts/searchResults.js | 32 ++++++++++----------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index 4d5248b73..5080621a5 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -78,17 +78,16 @@ function searchResults(response, isSidebar) { var resultCount=0; - var selector; + var selector, template_name; selector = isSidebar ? '#sidebar-search-results' : '#search-results'; $(selector).html(''); if (response.search_type === 'musicians') { resultCount = response.musicians.length; // TODO: generalize this for each search result type (band, musician, et. al.) - selector = isSidebar ? "#template-musicians-sidebar-search-result" : "#template-musicians-search-result"; + template_name = isSidebar ? "#template-musicians-sidebar-search-result" : "#template-musicians-search-result"; $.each(response.musicians, function(index, val) { // fill in template for Connect pre-click - var template = $(selector).html(); var args = { userId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), @@ -98,12 +97,11 @@ instruments: getInstrumentHtml(val.instruments) }; selector = isSidebar ? '#sidebar-search-results' : '#search-results'; - $(selector).append(context.JK.fillTemplate(template, args)); + $(selector).append(context.JK.fillTemplate($(template_name).html(), args)); // fill in template for Connect post-click selector = isSidebar ? '#template-sidebar-invitation-sent' : '#template-invitation-sent'; - template = $(selector).html(); - var invitationSentHtml = context.JK.fillTemplate(template, { + var invitationSentHtml = context.JK.fillTemplate($(selector).html(), { userId: val.id, first_name: val.first_name, profile_url: "/#/profile/" + val.id @@ -132,34 +130,34 @@ }); } else if (response.search_type === 'bands') { resultCount = response.bands.length; + template_name = isSidebar ? "#template-bands-sidebar-search-result" : "#template-bands-search-result"; $.each(response.bands, function(index, val) { // fill in template for Connect pre-click - selector = isSidebar ? "#template-bands-sidebar-search-result" : "#template-bands-search-result"; - var template = $(selector).html(); - var searchResultHtml = context.JK.fillTemplate(template, { - userId: val.id, + var searchResultHtml = context.JK.fillTemplate($(template_name).html(), { + bandId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), - profile_url: "/#/profile/" + val.id, - userName: val.name, + band_url: val.website, + bandName: val.name, location: val.location }); - $('#search-results').append(searchResultHtml); + selector = isSidebar ? '#sidebar-search-results' : '#search-results'; + $(selector).append(searchResultHtml); resultDivVisibility(val, isSidebar); }); } else if (response.search_type === 'fans') { resultCount = response.fans.length; + template_name = isSidebar ? "#template-fans-sidebar-search-result" : "#template-fans-search-result"; $.each(response.fans, function(index, val) { // fill in template for Connect pre-click - selector = isSidebar ? "#template-fans-sidebar-search-result" : "#template-fans-search-result"; - var template = $(selector).html(); - var searchResultHtml = context.JK.fillTemplate(template, { + var searchResultHtml = context.JK.fillTemplate($(template_name).html(), { userId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), profile_url: "/#/profile/" + val.id, userName: val.name, location: val.location }); - $('#search-results').append(searchResultHtml); + selector = isSidebar ? '#sidebar-search-results' : '#search-results'; + $(selector).append(searchResultHtml); resultDivVisibility(val, isSidebar); }); } From 74e95ad90880c71a08ae5994e32758af28d18291 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 02:49:57 -0600 Subject: [PATCH 18/41] vrfs988: added band spec and band.website value integrity on save --- ruby/lib/jam_ruby/models/band.rb | 9 +++++++++ ruby/spec/jam_ruby/models/band_spec.rb | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 ruby/spec/jam_ruby/models/band_spec.rb diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index de6546f84..a0a2b4b35 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -14,6 +14,7 @@ module JamRuby validates :biography, no_profanity: true before_save :check_lat_lng + before_save :check_website_url # musicians has_many :band_musicians, :class_name => "JamRuby::BandMusician" @@ -237,6 +238,14 @@ module JamRuby false end + def check_website_url + if website_changed? && self.website.present? + self.website.strip! + self.website = "http://#{self.website}" unless self.website =~ /^http/ + end + true + end + private def self.validate_genres(genres, is_nil_ok) if is_nil_ok && genres.nil? diff --git a/ruby/spec/jam_ruby/models/band_spec.rb b/ruby/spec/jam_ruby/models/band_spec.rb new file mode 100644 index 000000000..3f1c1c289 --- /dev/null +++ b/ruby/spec/jam_ruby/models/band_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe Band do + + let(:band) { FactoryGirl.create(:band) } + + describe 'website update' do + it 'should have http prefix on website url' do + band.website = 'example.com' + band.save! + expect(band.website).to match(/^http:\/\/example.com$/) + end + end + +end From 68b0fd92d6f1cf3e74b84dd0a99503217219a478 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 02:50:55 -0600 Subject: [PATCH 19/41] vrfs988: updated #query on new search; added semicolons --- web/app/assets/javascripts/searchResults.js | 6 ++++-- web/app/assets/javascripts/sidebar.js | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/web/app/assets/javascripts/searchResults.js b/web/app/assets/javascripts/searchResults.js index 5080621a5..ad14a5d84 100644 --- a/web/app/assets/javascripts/searchResults.js +++ b/web/app/assets/javascripts/searchResults.js @@ -72,8 +72,8 @@ } context.JK.SearchResultScreen.onSearchSuccess = function(response) { - searchResults(response, true) - searchResults(response, false) + searchResults(response, true); + searchResults(response, false); } function searchResults(response, isSidebar) { @@ -128,6 +128,7 @@ } resultDivVisibility(val, isSidebar); }); + } else if (response.search_type === 'bands') { resultCount = response.bands.length; template_name = isSidebar ? "#template-bands-sidebar-search-result" : "#template-bands-search-result"; @@ -144,6 +145,7 @@ $(selector).append(searchResultHtml); resultDivVisibility(val, isSidebar); }); + } else if (response.search_type === 'fans') { resultCount = response.fans.length; template_name = isSidebar ? "#template-fans-sidebar-search-result" : "#template-fans-search-result"; diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index de22418e7..cf70a749c 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -367,6 +367,8 @@ return hideSearchResults(); } if (query.length > 2) { + // FIXME: this is in searchResults + $('#query').html(query); query += '&search_text_type='+$('#search_text_type').val(); emptySearchResults(); search(query); From e0d8dd286a42f395012a8b755607772337fc529f Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 02:58:04 -0600 Subject: [PATCH 20/41] vrfs988: updated to work with new search attribute names --- .../models/band_filter_search_spec.rb | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/ruby/spec/jam_ruby/models/band_filter_search_spec.rb b/ruby/spec/jam_ruby/models/band_filter_search_spec.rb index ebfb57e08..1130361e2 100644 --- a/ruby/spec/jam_ruby/models/band_filter_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_filter_search_spec.rb @@ -26,14 +26,14 @@ describe 'Band search' do # expects all the bands num = Band.count results = Search.band_filter({ :per_page => num }) - expect(results.filter_results.count).to eq(num) + expect(results.results.count).to eq(num) end it "finds bands with proper ordering" do # the ordering should be create_at since no followers exist expect(BandFollower.count).to eq(0) results = Search.band_filter({ :per_page => Band.count }) - results.filter_results.each_with_index do |uu, idx| + results.results.each_with_index do |uu, idx| expect(uu.id).to eq(@bands.reverse[idx].id) end end @@ -54,10 +54,10 @@ describe 'Band search' do # refresh the order to ensure it works right @band2.followers.concat(users[1..-1]) results = Search.band_filter({ :per_page => @bands.size }, users[0]) - expect(results.filter_results[0].id).to eq(@band2.id) + expect(results.results[0].id).to eq(@band2.id) # check the follower count for given entry - expect(results.filter_results[0].search_follow_count.to_i).not_to eq(0) + expect(results.results[0].search_follow_count.to_i).not_to eq(0) # check the follow relationship between current_user and result expect(results.is_follower?(@band2)).to be true end @@ -66,7 +66,7 @@ describe 'Band search' do # make sure pagination works right params = { :per_page => 2, :page => 1 } results = Search.band_filter(params) - expect(results.filter_results.count).to be 2 + expect(results.results.count).to be 2 end end @@ -88,7 +88,7 @@ describe 'Band search' do # establish sorting order @band1.followers.concat(users) results = Search.band_filter({},@band1) - uu = results.filter_results.detect { |mm| mm.id == @band1.id } + uu = results.results.detect { |mm| mm.id == @band1.id } expect(uu).to_not be_nil expect(results.follow_count(uu)).to eq(users.count) end @@ -97,7 +97,7 @@ describe 'Band search' do make_session(@band1) @band1.reload results = Search.band_filter({},@band1) - uu = results.filter_results.detect { |mm| mm.id == @band1.id } + uu = results.results.detect { |mm| mm.id == @band1.id } expect(uu).to_not be_nil expect(results.session_count(uu)).to be 1 end @@ -113,8 +113,8 @@ describe 'Band search' do make_session(@band1) # order results by num recordings results = Search.band_filter({ :orderby => 'plays' }) - expect(results.filter_results[0].id).to eq(@band2.id) - expect(results.filter_results[1].id).to eq(@band1.id) + expect(results.results[0].id).to eq(@band2.id) + expect(results.results[1].id).to eq(@band1.id) end it "by now playing" do @@ -123,17 +123,17 @@ describe 'Band search' do FactoryGirl.create(:music_session_history, :music_session => session) results = Search.band_filter({ :orderby => 'playing' }) - expect(results.filter_results.count).to be 1 - expect(results.filter_results.first.id).to eq(@band3.id) + expect(results.results.count).to be 1 + expect(results.results.first.id).to eq(@band3.id) # should get 2 results with 2 active sessions # sort order should be created_at DESC session = make_session(@band4) FactoryGirl.create(:music_session_history, :music_session => session) results = Search.band_filter({ :orderby => 'playing' }) - expect(results.filter_results.count).to be 2 - expect(results.filter_results[0].id).to eq(@band4.id) - expect(results.filter_results[1].id).to eq(@band3.id) + expect(results.results.count).to be 2 + expect(results.results[0].id).to eq(@band4.id) + expect(results.results[1].id).to eq(@band3.id) end end @@ -147,10 +147,10 @@ describe 'Band search' do ggg = @band1.genres.detect { |gg| gg.id == genre.id } expect(ggg).to_not be_nil results = Search.band_filter({ :genre => ggg.id }) - results.filter_results.each do |rr| + results.results.each do |rr| expect(rr.genres.detect { |gg| gg.id==ggg.id }.id).to eq(genre.id) end - expect(results.filter_results.count).to be 1 + expect(results.results.count).to be 1 end it "finds bands within a given distance of given location" do @@ -160,26 +160,26 @@ describe 'Band search' do results = Search.band_filter({ :per_page => num, :distance => 10, :city => 'Apex' }, @band1) - expect(results.filter_results.count).to be num + expect(results.results.count).to be num # long distance results = Search.band_filter({ :per_page => num, :distance => 1000, :city => 'Miami', :state => 'FL' }, @band1) - expect(results.filter_results.count).to be num + expect(results.results.count).to be num end it "finds bands within a given distance of bands location" do expect(@band1.lat).to_not be_nil # uses the location of @band1 results = Search.band_filter({ :distance => 10, :per_page => Band.count }, @band1) - expect(results.filter_results.count).to be Band.count + expect(results.results.count).to be Band.count end it "finds no bands within a given distance of location" do expect(@band1.lat).to_not be_nil results = Search.band_filter({ :distance => 10, :city => 'San Francisco' }, @band1) - expect(results.filter_results.count).to be 0 + expect(results.results.count).to be 0 end end From 5bc7ceaba3513e1216d0ff818f2c7a425d6937bb Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 03:40:32 -0600 Subject: [PATCH 21/41] vrfs988: replaced global search with text-type search test --- web/spec/requests/musician_search_api_spec.rb | 2 +- web/spec/requests/search_api_spec.rb | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/web/spec/requests/musician_search_api_spec.rb b/web/spec/requests/musician_search_api_spec.rb index a48a1c6b1..99c87588b 100644 --- a/web/spec/requests/musician_search_api_spec.rb +++ b/web/spec/requests/musician_search_api_spec.rb @@ -59,7 +59,7 @@ describe "Musician Search API", :type => :api do it "gets no musicians for unused instruments" do get_query({:instrument => 'tuba'}) good_response - expect(json.count).to be 0 + expect(json.count).to eq(0) end end diff --git a/web/spec/requests/search_api_spec.rb b/web/spec/requests/search_api_spec.rb index 84d95af52..a3475939f 100644 --- a/web/spec/requests/search_api_spec.rb +++ b/web/spec/requests/search_api_spec.rb @@ -16,7 +16,7 @@ describe "Search API", :type => :api do it "empty search" do get '/api/search.json' last_response.status.should == 200 - JSON.parse(last_response.body).should eql(JSON.parse('{}')) + JSON.parse(last_response.body).should eql({'search_type'=>nil}) end it "simple search" do @@ -25,25 +25,15 @@ describe "Search API", :type => :api do @band = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) @band2 = Band.save(nil, "Peach", "www.bands2.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) - get '/api/search.json?query=peach' + get '/api/search.json?query=peach&search_text_type=bands' last_response.status.should == 200 response = JSON.parse(last_response.body) - response["musicians"].length.should == 1 - musician = response["musicians"][0] - musician["id"].should == @musician.id - - response["fans"].length.should == 1 - fan = response["fans"][0] - fan["id"].should == @fan.id - response["bands"].length.should == 2 bands = response["bands"] bands = [bands[0]["id"], bands[1]["id"]] bands.should include(@band.id) bands.should include(@band2.id) - - response["recordings"].should == nil end end end From c4d04adb775bd11597ebcd0046764d1fa1451752 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sun, 12 Jan 2014 22:23:18 -0600 Subject: [PATCH 22/41] vrfs988: fixed broken search test --- ruby/spec/jam_ruby/models/search_spec.rb | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ruby/spec/jam_ruby/models/search_spec.rb b/ruby/spec/jam_ruby/models/search_spec.rb index 65b658269..1f6689f45 100644 --- a/ruby/spec/jam_ruby/models/search_spec.rb +++ b/ruby/spec/jam_ruby/models/search_spec.rb @@ -13,24 +13,24 @@ describe Search do end def assert_peachy_data - search = Search.search('peach') + search = Search.musician_search('peach') + search.results.length.should == 1 + obj = search.results[0] + obj.should be_a_kind_of User + obj.id.should == @user.id - search.recordings.length.should == 0 - search.bands.length.should == 1 - search.musicians.length.should == 1 - search.fans.length.should == 1 + search = Search.fan_search('peach') + search.results.length.should == 1 + obj = search.results[0] + obj.should be_a_kind_of User + obj.id.should == @fan.id - musician = search.musicians[0] - musician.should be_a_kind_of User - musician.id.should == @user.id + search = Search.band_search('peach') + search.results.length.should == 1 + obj = search.results[0] + obj.should be_a_kind_of Band + obj.id.should == @band.id - band = search.bands[0] - band.should be_a_kind_of Band - band.id.should == @band.id - - fan = search.fans[0] - fan.should be_a_kind_of User - fan.id.should == @fan.id end it "search for band & musician " do From 1f31bb3ff5cbc3acc9d2944d3265d9877adad8a4 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 14 Jan 2014 09:47:30 -0600 Subject: [PATCH 23/41] * fixing debian postinstall issue --- web/Gemfile | 10 ++--- .../package/audiomixer-worker-upstart-run.sh | 19 --------- web/script/package/audiomixer-worker.conf | 7 ---- web/script/package/post-install.sh | 19 --------- web/script/package/post-uninstall.sh | 28 +------------ web/script/package/pre-install.sh | 40 +------------------ .../lib/jam_websockets/version.rb | 2 +- 7 files changed, 8 insertions(+), 117 deletions(-) delete mode 100755 web/script/package/audiomixer-worker-upstart-run.sh delete mode 100755 web/script/package/audiomixer-worker.conf diff --git a/web/Gemfile b/web/Gemfile index f57f9b144..149bbd86e 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -90,12 +90,12 @@ end group :test, :cucumber do gem 'capybara' -if ENV['JAMWEB_QT5'] == '1' - # necessary on platforms such as arch linux, where pacman -S qt5-webkit is your easiet option - gem "capybara-webkit", :git => 'git://github.com/thoughtbot/capybara-webkit.git' -else +#if ENV['JAMWEB_QT5'] == '1' +# # necessary on platforms such as arch linux, where pacman -S qt5-webkit is your easiet option +# gem "capybara-webkit", :git => 'git://github.com/thoughtbot/capybara-webkit.git' +#else gem "capybara-webkit" -end +#end gem 'capybara-screenshot' gem 'cucumber-rails', :require => false #, '1.3.0', :require => false gem 'guard-spork', '0.3.2' diff --git a/web/script/package/audiomixer-worker-upstart-run.sh b/web/script/package/audiomixer-worker-upstart-run.sh deleted file mode 100755 index 5bdc1dd11..000000000 --- a/web/script/package/audiomixer-worker-upstart-run.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -l - -# default config values -PORT=3000 -BUILD_NUMBER=`cat /var/lib/jam-web/BUILD_NUMBER` - - -CONFIG_FILE="/etc/jam-web/audiomixer-worker-upstart.conf" -if [ -e "$CONFIG_FILE" ]; then - . "$CONFIG_FILE" -fi - -# I don't like doing this, but the next command (bundle exec) retouches/generates -# the gemfile. This unfortunately means the next debian update doesn't update this file. -# Ultimately this means an old Gemfile.lock is left behind for a new package, -# and bundle won't run because it thinks it has the wrong versions of gems -rm -f Gemfile.lock - -RAILS_ENV=production BUILD_NUMBER=$BUILD_NUMBER QUEUE=audiomixer exec bundle exec rake environment resque:work diff --git a/web/script/package/audiomixer-worker.conf b/web/script/package/audiomixer-worker.conf deleted file mode 100755 index 82617f234..000000000 --- a/web/script/package/audiomixer-worker.conf +++ /dev/null @@ -1,7 +0,0 @@ -description "audiomixer-worker" - -start on startup -start on runlevel [2345] -stop on runlevel [016] - -exec start-stop-daemon --start --chdir /var/lib/jam-web --exec /var/lib/jam-web/script/package/audiomixer-worker-upstart-run.sh diff --git a/web/script/package/post-install.sh b/web/script/package/post-install.sh index fd85d40fa..6eb848202 100755 --- a/web/script/package/post-install.sh +++ b/web/script/package/post-install.sh @@ -15,25 +15,6 @@ mkdir -p /var/lib/$NAME/tmp mkdir -p /etc/$NAME mkdir -p /var/log/$NAME -chown -R $USER:$GROUP /var/lib/$NAME -chown -R $USER:$GROUP /etc/$NAME -chown -R $USER:$GROUP /var/log/$NAME - - -# do the same for audiomixer-worker -NAME="audiomixer-worker" - -USER="$NAME" -GROUP="$NAME" - -# copy upstart file -cp /var/lib/$NAME/script/package/$NAME.conf /etc/init/$NAME.conf - -mkdir -p /var/lib/$NAME/log -mkdir -p /var/lib/$NAME/tmp -mkdir -p /etc/$NAME -mkdir -p /var/log/$NAME - chown -R $USER:$GROUP /var/lib/$NAME chown -R $USER:$GROUP /etc/$NAME chown -R $USER:$GROUP /var/log/$NAME \ No newline at end of file diff --git a/web/script/package/post-uninstall.sh b/web/script/package/post-uninstall.sh index 923d323db..9d3ee0c14 100755 --- a/web/script/package/post-uninstall.sh +++ b/web/script/package/post-uninstall.sh @@ -24,30 +24,4 @@ then fi userdel $NAME -fi - - - -NAME="audiomixer-worker" - -set -e -if [ "$1" = "remove" ] -then - set +e - # stop the process, if any is found. we don't want this failing to cause an error, though. - sudo stop $NAME - set -e - - if [ -f /etc/init/$NAME.conf ]; then - rm /etc/init/$NAME.conf - fi -fi - -if [ "$1" = "purge" ] -then - if [ -d /var/lib/$NAME ]; then - rm -rf /var/lib/$NAME - fi - - userdel $NAME -fi +fi \ No newline at end of file diff --git a/web/script/package/pre-install.sh b/web/script/package/pre-install.sh index 057f1caa8..996f30251 100755 --- a/web/script/package/pre-install.sh +++ b/web/script/package/pre-install.sh @@ -34,42 +34,4 @@ then fi # NIS no longer a possible problem; stop ignoring errors -set -e - - - -# do the same for audiomixer-worker -NAME="audiomixer-worker" - -set -eu - -HOME="/var/lib/$NAME" -USER="$NAME" -GROUP="$NAME" - -# if NIS is used, then errors can occur but be non-fatal -if which ypwhich >/dev/null 2>&1 && ypwhich >/dev/null 2>&1 -then - set +e -fi - -if ! getent group "$GROUP" >/dev/null -then - addgroup --system "$GROUP" >/dev/null -fi - -# creating user if it isn't already there -if ! getent passwd "$USER" >/dev/null -then - adduser \ - --system \ - --home $HOME \ - --shell /bin/false \ - --disabled-login \ - --ingroup "$GROUP" \ - --gecos "$USER" \ - "$USER" >/dev/null -fi - -# NIS no longer a possible problem; stop ignoring errors -set -e +set -e \ No newline at end of file diff --git a/websocket-gateway/lib/jam_websockets/version.rb b/websocket-gateway/lib/jam_websockets/version.rb index 67a2193ef..1a8dee8f5 100644 --- a/websocket-gateway/lib/jam_websockets/version.rb +++ b/websocket-gateway/lib/jam_websockets/version.rb @@ -1,3 +1,3 @@ module JamWebsockets - VERSION = "0.0.1" + VERSION = "0.1.1" end From b15604c148803fcc860f3bfd509ad172ff24b6db Mon Sep 17 00:00:00 2001 From: jam Date: Tue, 14 Jan 2014 21:22:05 +0000 Subject: [PATCH 24/41] Icecast modules and test --- db/up/icecast.sql | 81 +++++++++++++++---- .../models/icecast_admin_authentication.rb | 67 ++++++++++----- ruby/lib/jam_ruby/models/icecast_directory.rb | 11 ++- ruby/lib/jam_ruby/models/icecast_limit.rb | 22 ++--- .../jam_ruby/models/icecast_listen_socket.rb | 12 ++- ruby/lib/jam_ruby/models/icecast_logging.rb | 12 ++- .../models/icecast_mastersvr_relay.rb | 12 ++- ruby/lib/jam_ruby/models/icecast_mount.rb | 58 ++++++++++--- ruby/lib/jam_ruby/models/icecast_path.rb | 17 +++- ruby/lib/jam_ruby/models/icecast_relay.rb | 27 ++++++- ruby/lib/jam_ruby/models/icecast_sercurity.rb | 33 +++++++- ruby/lib/jam_ruby/models/icecast_server.rb | 80 +++++++++++++++--- .../lib/jam_ruby/models/icecast_servermisc.rb | 6 +- .../jam_ruby/models/icecast_servermount.rb | 14 ++++ .../jam_ruby/models/icecast_serverrelay.rb | 14 ++++ .../jam_ruby/models/icecast_serversocket.rb | 14 ++++ .../models/icecast_user_authentication.rb | 68 +++++++++++++++- .../icecast_admin_authentication_spec.rb | 2 +- .../jam_ruby/models/icecast_directory_spec.rb | 2 + .../jam_ruby/models/icecast_limit_spec.rb | 14 ++-- .../models/icecast_listen_socket_spec.rb | 1 + .../jam_ruby/models/icecast_logging_spec.rb | 1 + .../models/icecast_mastersvr_relay_spec.rb | 8 +- .../jam_ruby/models/icecast_mount_spec.rb | 29 ++++++- .../spec/jam_ruby/models/icecast_path_spec.rb | 1 + .../jam_ruby/models/icecast_relay_spec.rb | 7 +- .../jam_ruby/models/icecast_security_spec.rb | 20 +++++ .../jam_ruby/models/icecast_server_spec.rb | 68 ++++++++++++++++ .../icecast_user_authentication_spec.rb | 31 +++++++ 29 files changed, 625 insertions(+), 107 deletions(-) create mode 100644 ruby/lib/jam_ruby/models/icecast_servermount.rb create mode 100644 ruby/lib/jam_ruby/models/icecast_serverrelay.rb create mode 100644 ruby/lib/jam_ruby/models/icecast_serversocket.rb diff --git a/db/up/icecast.sql b/db/up/icecast.sql index 01385f055..a04a62df8 100644 --- a/db/up/icecast.sql +++ b/db/up/icecast.sql @@ -147,11 +147,11 @@ create table icecast_relays ( -- mount at server. eg /example.ogg mount VARCHAR(128) not null, -- eg /different.ogg - local_mount VARCHAR(128) not null, + local_mount VARCHAR(128) not null default '/relaymout.ogg', -- eg joe. could be null - username VARCHAR(64) default NULL , + username VARCHAR(64) not null default 'jkicerelayusr' , -- user password - password VARCHAR(64) default null , + password VARCHAR(64) not null default 'jkicerelaypwd' , relay_shoutcast_metadata INTEGER default 0, --- relay only if we have someone wanting to listen on_demand INTEGER default 0, @@ -164,28 +164,28 @@ create TABLE icecast_user_authentications( id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), --"htpasswd or url" -- real name is type - stype VARCHAR(16) DEFAULT NULL , + stype VARCHAR(16) DEFAULT 'url' , -- these are for httpasswd filename VARCHAR(256) default NULL, - allow_duplicate_users INTEGER DEFAULT 0, + allow_duplicate_users INTEGER DEFAULT 1, -- these options are for url -- eg value="http://myauthserver.com/stream_start.php" - mount_add VARCHAR(256) default NULL, + mount_add VARCHAR(256) DEFAULT 'http://icecastauth.jamkazam.com/stream_start.php', --value="http://myauthserver.com/stream_end.php" - mount_remove VARCHAR(256) default NULL, + mount_remove VARCHAR(256) default 'http://icecastauth.jamkazam.com/stream_end.php', --value="http://myauthserver.com/listener_joined.php" - listener_add VARCHAR(256) default NULL, + listener_add VARCHAR(256) default 'http://icecastauth.jamkazam.com/listener_joined.php', --value="http://myauthserver.com/listener_left.php" - listener_remove VARCHAR(256) default NULL, + listener_remove VARCHAR(256) default 'http://icecastauth.jamkazam.com/listener_left.php', -- value="user" - username VARCHAR(64) default NULL, + username VARCHAR(64) default 'jkuser', -- value="pass" - password VARCHAR(64) default NULL, + password VARCHAR(64) DEFAULT 'jkhackpass', -- value="icecast-auth-user: 1" - auth_header VARCHAR(64) default NULL, + auth_header VARCHAR(64) default 'icecast-auth-user: 1', -- value="icecast-auth-timelimit:" - timelimit_header VARCHAR(64) default NULL, + timelimit_header VARCHAR(64) default 'icecast-auth-timelimit:', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP @@ -197,7 +197,7 @@ create table icecast_mounts ( -- eg/example-complex.ogg mount_name VARCHAR(128) UNIQUE NOT NULL, username VARCHAR(64) NOT NULL DEFAULT 'jamsource', - password VARCHAR(64) NOT NULL DEFAULT 'jamksource', + password VARCHAR(64) NOT NULL DEFAULT 'jamhackmesourcepwd', max_listeners INTEGER NOT NULL DEFAULT 4, max_listener_duration INTEGER NOT NULL DEFAULT 3600, -- dump of the stream coming through on this mountpoint. @@ -248,6 +248,8 @@ create table icecast_mounts ( on_connect VARCHAR(256) DEFAULT '/home/icecast/bin/source-start', on_disconnect VARCHAR(256) DEFAULT '/home/icecast/bin/source-end', + user_authentication_id varchar(64) DEFAULT NULL references icecast_user_authentications(id), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); @@ -294,15 +296,60 @@ create table icecast_securities ( updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); + create TABLE icecast_servers( id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), - icecast_limit_id VARCHAR(64) REFERENCES icecast_limits(id) + --use this to mark the server configuration as needing to be regenerated + config_changed INTEGER DEFAULT 0, + limit_id VARCHAR(64) REFERENCES icecast_limits(id), + adminauth_id VARCHAR(64) REFERENCES icecast_admin_authentications(id), + directory_id VARCHAR(64) REFERENCES icecast_directories(id), + misc_id VARCHAR(64) REFERENCES icecast_servermiscs(id), + master_relay_id VARCHAR(64) REFERENCES icecast_mastersvr_relays(id), + /* relay_ids VARCHAR(64) REFERENCES icecast_serverrelays(id), + mount_ids VARCHAR(64) REFERENCES icecast_servermounts(id), + socket_ids VARCHAR(64) REFERENCES icecast_serversockets(id) , + */ - -- configs - -- mounts + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); +CREATE TABLE icecast_servermounts ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + mount_id VARCHAR(64) REFERENCES icecast_mounts(id) ON DELETE CASCADE, + server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE icecast_servermounts ADD CONSTRAINT server_mount_uniqkey UNIQUE (server_id, mount_id); + +CREATE TABLE icecast_serverrelays ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + relay_id VARCHAR(64) REFERENCES icecast_relays(id) ON DELETE CASCADE, + server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE icecast_serverrelays ADD CONSTRAINT server_relay_uniqkey UNIQUE (server_id, relay_id); + +CREATE TABLE icecast_serversockets ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + socket_id VARCHAR(64) REFERENCES icecast_listen_sockets(id) ON DELETE CASCADE, + server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE icecast_serversockets ADD CONSTRAINT server_socket_uniqkey UNIQUE (server_id, socket_id); + + + + + diff --git a/ruby/lib/jam_ruby/models/icecast_admin_authentication.rb b/ruby/lib/jam_ruby/models/icecast_admin_authentication.rb index d94aeb1d1..f4ce4a1df 100644 --- a/ruby/lib/jam_ruby/models/icecast_admin_authentication.rb +++ b/ruby/lib/jam_ruby/models/icecast_admin_authentication.rb @@ -1,26 +1,19 @@ - -module JSONable - def jdumpXml (ovb, nm, ident=1, output=$stdout) - - serialized = Hash.new - ovb.myattr_accessor.each do |attribute| - #serialized[attribute] = ovb[attribute] - puts "attribute = #{attribute}" - #serialized[attribute] = self.public_send attribute - end - - hash = serialized +module JAmXml + def jdumpXml (hash, nm, ident=1, output=$stdout, child=nil) tb = "\t" tbs = tb * ident - tbse = tb * (ident-1) - output.puts "#{tbse}<#{nm}>" + unless ident <= 0 + tbse = tb * (ident-1) + output.puts "#{tbse}<#{nm}>" + end + hash.each do |key, val| #puts "attrib: key=#{key} val=#{val}" el = key - if key.present? + if !key.nil? && !key.empty? el = key.gsub(/_/, '-') end @@ -28,15 +21,45 @@ module JSONable sv = val if val.to_s.empty? #skip ??? + next if val.to_s.empty? else if val.instance_of? String #encode the string to be xml safe sv = CGI.escapeHTML(val) end end - output.puts "#{tbs}<#{el}>#{sv}" + + if key.empty? + output.puts "#{tbs}<#{sv}/>" + else + output.puts "#{tbs}<#{el}>#{sv}" + end end - puts "#{tbse}" + + if !child.nil? + if child.kind_of? Array + child.each { |x| x.dumpXml(ident+1,output)} + else + child.dumpXml(ident+1,output) + end + end + unless ident <= 0 + puts "#{tbse}" + end + end + + def jMakeStrXmlSafe(val) + sv = val + if val.to_s.empty? + #skip ??? + sv ="" + else + if val.instance_of? String + #encode the string to be xml safe + sv = CGI.escapeHTML(val) + end + end + return sv end end @@ -44,7 +67,7 @@ end module JamRuby class IcecastAdminAuthentication < ActiveRecord::Base - include JSONable + include JAmXml attr_accessible :source_password, :relay_user, :relay_password, :admin_user, :admin_password #myattr_accessor = [:source_password, :relay_user, :relay_password, :admin_user, :admin_password ] @@ -65,7 +88,13 @@ module JamRuby validates :admin_password, presence: true, length: {minimum: 5} def dumpXml (ident=1, output=$stdout) - self.jdumpXml(self,"authentication", ident,output) + hash = Hash["source_password" => self.source_password, + "relay_user" => self.relay_user, + "relay_password" => self.relay_password, + "admin_user" => self.admin_user, + "admin_password" => self.admin_password] + + self.jdumpXml(hash,"authentication", ident,output) end diff --git a/ruby/lib/jam_ruby/models/icecast_directory.rb b/ruby/lib/jam_ruby/models/icecast_directory.rb index f86a7f7c9..79f0f012a 100644 --- a/ruby/lib/jam_ruby/models/icecast_directory.rb +++ b/ruby/lib/jam_ruby/models/icecast_directory.rb @@ -1,10 +1,17 @@ module JamRuby class IcecastDirectory < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' + attr_accessible :yp_url_timeout, :yp_url - attr_accessor :yp_url_timeout, :yp_url + validates :yp_url_timeout, numericality: {only_integer: true}, length: {in: 1..30} + + def dumpXml (ident=1, output=$stdout) + hash = Hash["yp_url_timeout" => self.yp_url_timeout, + "yp_url" => self.yp_url] + self.jdumpXml(hash, "directory", ident, output) + end end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_limit.rb b/ruby/lib/jam_ruby/models/icecast_limit.rb index 2e006c7e1..0249cb2b1 100644 --- a/ruby/lib/jam_ruby/models/icecast_limit.rb +++ b/ruby/lib/jam_ruby/models/icecast_limit.rb @@ -1,20 +1,19 @@ module JamRuby class IcecastLimit < ActiveRecord::Base - include JSONable + include JAmXml self.primary_key = 'id' attr_accessible :clients, :sources, :queue_size, :client_timeout, :header_timeout, :source_timeout, :burst_size - #attr_accessor :clients, :sources, :queue_size, :client_timeout, :header_timeout, :source_timeout, :burst_size - #validates :clients, numericality: {only_integer: true}, length: {in: 1..15000} - validates :clients, numericality: {only_integer: true} + validates :clients, numericality: {only_integer: true}, length: {in: 1..15000} + after_initialize :init def init - puts "Init self.client #{self.clients}" + #puts "Init self.client #{self.clients}" self.clients ||= 10000 self.sources ||= 1000 self.queue_size ||= 102400 @@ -24,11 +23,16 @@ module JamRuby self.burst_size ||= 65536 end - def setclients(val) - @clients = val - end + def dumpXml (ident=1, output=$stdout) - self.jdumpXml(self, "limits", ident, output) + hash = Hash["clients" => self.clients, + "sources" => self.sources, + "queue_size" => self.queue_size, + "client_timeout" => self.client_timeout, + "header_timeout" => self.header_timeout] + hash.merge! "source_timeout" => self.source_timeout, + "burst_size" => self.burst_size + self.jdumpXml(hash, "limits", ident, output) end end diff --git a/ruby/lib/jam_ruby/models/icecast_listen_socket.rb b/ruby/lib/jam_ruby/models/icecast_listen_socket.rb index b4e1741f8..65d721b1a 100644 --- a/ruby/lib/jam_ruby/models/icecast_listen_socket.rb +++ b/ruby/lib/jam_ruby/models/icecast_listen_socket.rb @@ -1,13 +1,19 @@ module JamRuby class IcecastListenSocket < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :port, :bind_address, :shoutcast_mount, :shoutcast_compat - attr_accessor :port, :bind_address, :shoutcast_mount, :shoutcast_compat - def dumpXml() + belongs_to :server, :class_name => "JamRuby::IcecastServer" , :inverse_of => :sockets + def dumpXml (ident=1, output=$stdout) + hash = Hash["port" => self.port, + "bind_address" => self.bind_address, + "shoutcast_mount" => self.shoutcast_mount, + "shoutcast_compat" => self.shoutcast_compat] + + self.jdumpXml(hash, "listen-socket", ident, output) end diff --git a/ruby/lib/jam_ruby/models/icecast_logging.rb b/ruby/lib/jam_ruby/models/icecast_logging.rb index a2aa1cc88..45cd97401 100644 --- a/ruby/lib/jam_ruby/models/icecast_logging.rb +++ b/ruby/lib/jam_ruby/models/icecast_logging.rb @@ -1,12 +1,18 @@ module JamRuby class IcecastLogging < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :accesslog, :errorlog, :playlistlog, :loglevel - attr_accessor :accesslog, :errorlog, :playlistlog, :loglevel - def dumpXml() + def dumpXml (ident=1, output=$stdout) + + hash = Hash["accesslog" => self.accesslog, + "errorlog" => self.errorlog, + "loglevel" => self.loglevel, + "playlistlog" => self.playlistlog] + + self.jdumpXml(hash, "logging", ident, output) end diff --git a/ruby/lib/jam_ruby/models/icecast_mastersvr_relay.rb b/ruby/lib/jam_ruby/models/icecast_mastersvr_relay.rb index cd949c3d2..8cb9bd3a9 100644 --- a/ruby/lib/jam_ruby/models/icecast_mastersvr_relay.rb +++ b/ruby/lib/jam_ruby/models/icecast_mastersvr_relay.rb @@ -1,12 +1,18 @@ module JamRuby class IcecastMastersvrRelay < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :master_server, :master_server_port, :master_username, :master_password, :relays_on_demand - attr_accessible :master_server, :master_server_port, :master_username, :master_password, :relays_on_demand + validates :master_password, :master_username, presence: true - def dumpXml() + def dumpXml (ident=0, output=$stdout) + hash = Hash["master_server" => self.master_server, + "master_server_port" => self.master_server_port, + "master_username" => self.master_username, + "master_password" => self.master_password, + "relays_on_demand" => self.relays_on_demand] + self.jdumpXml(hash, "masterrelay", ident, output) end end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_mount.rb b/ruby/lib/jam_ruby/models/icecast_mount.rb index 47731cbf1..91b5873a6 100644 --- a/ruby/lib/jam_ruby/models/icecast_mount.rb +++ b/ruby/lib/jam_ruby/models/icecast_mount.rb @@ -1,24 +1,64 @@ module JamRuby class IcecastMount < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :mount_name, :username, :password, :max_listeners, :max_listener_duration, :dump_file - attr_accessor :mount_name, :username, :password, :max_listeners, :max_listener_duration, :dump_file - attr_accessible :intro, :fallback_mount, :fallback_override, :fallback_when_full, :charset - attr_accessor :intro, :fallback_mount, :fallback_override, :fallback_when_full, :charset - attr_accessible :publicc, :stream_name, :stream_description, :stream_url, :genre, :bitrate - attr_accessor :publicc, :stream_name, :stream_description, :stream_url, :genre, :bitrate - attr_accessible :mtype, :subtype, :hidden, :burst_size, :mp3_metadata_interval, :on_connect, :on_disconnect - attr_accessor :mtype, :subtype, :hidden, :burst_size, :mp3_metadata_interval, :on_connect, :on_disconnect + validates :mount_name, presence: true + validates :username, presence: true + validates :password, presence: true + + #has_one :authentication, :class_name => "IcecastUserAuthentication" has_one :authentication, :class_name => "IcecastUserAuthentication" + belongs_to :servermount, :class_name => "JamRuby::IcecastServermount" , :inverse_of => :mount - def dumpXml() + def dumpXml (ident=1, output=$stdout) + hash = Hash["mount_name" => self.mount_name, + "username" => self.username, + "password" => self.password, + "max_listeners" => self.max_listeners, + "max_listener_duration" => self.max_listener_duration, + "dump_file" => self.dump_file, + "intro" => self.intro, + "fallback_mount" => self.fallback_mount, + "fallback_override" => self.fallback_override, + "fallback_when_full" => self.fallback_when_full, + "charset" => self.charset, + + "public" => self.publicc, + "stream_name" => self.stream_name, + "stream_description" => self.stream_description, + "stream_url" => self.stream_url, + "genre" => self.genre, + "bitrate" => self.bitrate, + + "type" => self.mtype, + "subtype" => self.subtype, + "hidden" => self.hidden, + "burst_size" => self.burst_size, + "mp3_metadata_interval" => self.mp3_metadata_interval, + "on_connect" => self.on_connect, + "on_disconnect" => self.on_disconnect + ] + + self.jdumpXml(hash, "mount", ident, output, self.authentication) end + + def getMediaUrl + if !self.servermount.nil? + @server = self.servermount.server + @misc = @server.misc + url = "http://" + @misc.hostname + self.mount_name + return url; + else + raise ("Undefined severid") + end + end + end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_path.rb b/ruby/lib/jam_ruby/models/icecast_path.rb index a6f01e122..19edb23ab 100644 --- a/ruby/lib/jam_ruby/models/icecast_path.rb +++ b/ruby/lib/jam_ruby/models/icecast_path.rb @@ -1,13 +1,24 @@ module JamRuby class IcecastPath < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :basedir, :logdir, :pidfile, :webroot, :adminroot, :allow_ip, :deny_ip, :aliass - attr_accessor :basedir, :logdir, :pidfile, :webroot, :adminroot, :allow_ip, :deny_ip, :aliass - def dumpXml() + def dumpXml (ident=1, output=$stdout) + a = "alias #{self.aliass}" + hash = Hash["basedir" => self.basedir, + "logdir" => self.logdir, + "pidfile" => self.pidfile, + "webroot" => self.webroot, + "adminroot" => self.adminroot, + + "allow_ip" => self.allow_ip, + "deny_ip" => self.deny_ip, + "" => a, + ] + self.jdumpXml(hash, "paths", ident, output) end end diff --git a/ruby/lib/jam_ruby/models/icecast_relay.rb b/ruby/lib/jam_ruby/models/icecast_relay.rb index 19d9b275d..74f693f57 100644 --- a/ruby/lib/jam_ruby/models/icecast_relay.rb +++ b/ruby/lib/jam_ruby/models/icecast_relay.rb @@ -1,14 +1,35 @@ module JamRuby class IcecastRelay < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :server, :port, :mount, :local_mount, :username, :password, :relay_shoutcast_metadata, :on_demand - attr_accessor :server, :port, :mount, :local_mount, :username, :password, :relay_shoutcast_metadata, :on_demand - def dumpXml() + validates :port, numericality: {only_integer: true}, length: {in: 1..65000} + validates :mount, presence: true + validates :server, presence: true + validates :local_mount, presence: true + validates :username, presence: true + validates :password, presence: true + belongs_to :sserver, :class_name => "JamRuby::IcecastServerrelay" + + + def dumpXml (ident=1, output=$stdout) + + hash = Hash["server" => self.server, + "port" => self.port, + "mount" => self.mount, + "local_mount" => self.local_mount, + "username" => self.username, + + "password" => self.password, + "relay_shoutcast_metadata" => self.relay_shoutcast_metadata, + "on_demand" => self.on_demand + ] + self.jdumpXml(hash, "relay", ident, output) end + end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_sercurity.rb b/ruby/lib/jam_ruby/models/icecast_sercurity.rb index 318c055ed..3a8dafef8 100644 --- a/ruby/lib/jam_ruby/models/icecast_sercurity.rb +++ b/ruby/lib/jam_ruby/models/icecast_sercurity.rb @@ -1,12 +1,39 @@ module JamRuby class IcecastSecurity < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :chroot, :changeowner_user, :changeowner_group - attr_accessor :chroot, :changeowner_user, :changeowner_group - def dumpXml() + validates :chroot, numericality: {only_integer: true}, length: {in: 0..1} + + + def dumpXml (ident=1, output=$stdout) + + tb = "\t" + tbs = tb * (ident) + tbs2 = tb * (ident+1) + tbse = tb * (ident-1) + if tbse.empty? || tbse.nil? + tbse="" + end + + + nm = "security" + output.puts "#{tbse}<#{nm}>" + + output.puts "#{tbs}#{self.chroot}" + output.puts "#{tbs}" + + v = jMakeStrXmlSafe(self.changeowner_user) + output.puts "#{tbs2}#{v}" + + v = jMakeStrXmlSafe(self.changeowner_group) + output.puts "#{tbs2}#{v}" + + output.puts "#{tbs}" + + output.puts "#{tbse}" end diff --git a/ruby/lib/jam_ruby/models/icecast_server.rb b/ruby/lib/jam_ruby/models/icecast_server.rb index 8f837edc8..c753e44e0 100644 --- a/ruby/lib/jam_ruby/models/icecast_server.rb +++ b/ruby/lib/jam_ruby/models/icecast_server.rb @@ -1,21 +1,75 @@ module JamRuby class IcecastServer < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' - has_one :limit, :class_name => "JamRuby::IcecastLimit" - has_one :adminauth, :class_name => "JamRuby::IcecastAdminAuthentication" - has_one :directory, :class_name => "JamRuby::IcecastDirectory" - has_one :misc, :class_name => "JamRuby::IcecastServermisc" - has_many :listen_sockets, :class_name => "JamRuby::IcecastListenSocket" - has_one :master_relay, :class_name => "JamRuby::IcecastMastersvrRelay" - has_one :relay, :class_name => "JamRuby::IcecastRelay" - has_many :mounts, :class_name => "JamRuby::IcecastMount" - has_one :path, :class_name => "JamRuby::IcecastPath" - has_one :logging, :class_name => "JamRuby::IcecastLogging" - has_one :security, :class_name => "JamRuby::IceCastSecurity" + has_one :limit, :class_name => "JamRuby::IcecastLimit" , foreign_key: "id" + has_one :adminauth, :class_name => "JamRuby::IcecastAdminAuthentication" , foreign_key: "id" + has_one :directory, :class_name => "JamRuby::IcecastDirectory" , foreign_key: "id" + has_one :misc, :class_name => "JamRuby::IcecastServermisc" , foreign_key: "id" - def dumpXml() + has_one :master_relay, :class_name => "JamRuby::IcecastMastersvrRelay" , foreign_key: "id" + + has_many :smounts, :class_name => "JamRuby::IcecastServermount" + has_many :mounts, :class_name => "JamRuby::IcecastMount", :through => :smounts + + has_many :ssockets, :class_name => "JamRuby::IcecastServersocket" + has_many :sockets, :class_name => "JamRuby::IcecastListenSocket" ,:through => :ssockets + + has_many :srelays, :class_name => "JamRuby::IcecastServerrelay" , :inverse_of => :server + has_many :relays, :class_name => "JamRuby::IcecastRelay" , :through => :srelays + + + has_one :path, :class_name => "JamRuby::IcecastPath" , foreign_key: "id" + has_one :logging, :class_name => "JamRuby::IcecastLogging" , foreign_key: "id" + has_one :security, :class_name => "JamRuby::IcecastSecurity" , foreign_key: "id" + + def dumpXml (ident=1, output=$stdout) + ident += 1 + unless self.limit.nil? + self.limit.dumpXml(ident,output) + end + unless self.adminauth.nil? + self.adminauth.dumpXml(ident,output) + end + + unless self.directory.nil? + self.directory.dumpXml(ident,output) + end + + unless self.misc.nil? + self.misc.dumpXml(ident,output) + end + + unless self.master_relay.nil? + self.master_relay.dumpXml(ident,output) + end + + + unless self.path.nil? + self.path.dumpXml(ident,output) + end + + unless self.logging.nil? + self.logging.dumpXml(ident,output) + end + + unless self.security.nil? + self.security.dumpXml(ident,output) + end + + + self.relays.each do |rl| + sock.rl(ident,output) + end + + self.sockets.each do |sock| + sock.dumpXml(ident,output) + end + + self.mounts.each do |mount| + mount.dumpXml(ident,output) + end end diff --git a/ruby/lib/jam_ruby/models/icecast_servermisc.rb b/ruby/lib/jam_ruby/models/icecast_servermisc.rb index 881a1c811..cdc2b2c95 100644 --- a/ruby/lib/jam_ruby/models/icecast_servermisc.rb +++ b/ruby/lib/jam_ruby/models/icecast_servermisc.rb @@ -1,12 +1,12 @@ module JamRuby class IcecastServermisc < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :hostname, :location, :admin, :fileserve, :server_id - attr_accessor :hostname, :location, :admin, :fileserve, :server_id - def dumpXml() + + def dumpXml (ident=0, output=$stdout) end diff --git a/ruby/lib/jam_ruby/models/icecast_servermount.rb b/ruby/lib/jam_ruby/models/icecast_servermount.rb new file mode 100644 index 000000000..633bc6af2 --- /dev/null +++ b/ruby/lib/jam_ruby/models/icecast_servermount.rb @@ -0,0 +1,14 @@ +module JamRuby + class IcecastServermount < ActiveRecord::Base + + self.primary_key = 'id' + + belongs_to :mount, :class_name => "JamRuby::IcecastMount" , :inverse_of => :servermount + belongs_to :server, :class_name => "JamRuby::IcecastServer" + + validates :server_id, :presence => true + validates :mount_id, :presence => true + + + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_serverrelay.rb b/ruby/lib/jam_ruby/models/icecast_serverrelay.rb new file mode 100644 index 000000000..14b80220c --- /dev/null +++ b/ruby/lib/jam_ruby/models/icecast_serverrelay.rb @@ -0,0 +1,14 @@ +module JamRuby + class IcecastServerrelay < ActiveRecord::Base + + self.primary_key = 'id' + + belongs_to :relay, :class_name => "JamRuby::IcecastRelay" + belongs_to :server, :class_name => "JamRuby::IcecastServer" + + validates :server_id, :presence => true + validates :relay_id, :presence => true + + + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_serversocket.rb b/ruby/lib/jam_ruby/models/icecast_serversocket.rb new file mode 100644 index 000000000..c677e23d2 --- /dev/null +++ b/ruby/lib/jam_ruby/models/icecast_serversocket.rb @@ -0,0 +1,14 @@ +module JamRuby + class IcecastServersocket < ActiveRecord::Base + + self.primary_key = 'id' + + belongs_to :socket, :class_name => "JamRuby::IcecastListenSocket" , foreign_key: "id" + belongs_to :server, :class_name => "JamRuby::IcecastServer" , foreign_key: "id" + + validates :socket_id, :presence => true + validates :server_id, :presence => true + + + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/icecast_user_authentication.rb b/ruby/lib/jam_ruby/models/icecast_user_authentication.rb index 12d4f1520..a28056bae 100644 --- a/ruby/lib/jam_ruby/models/icecast_user_authentication.rb +++ b/ruby/lib/jam_ruby/models/icecast_user_authentication.rb @@ -1,16 +1,76 @@ module JamRuby class IcecastUserAuthentication < ActiveRecord::Base - + include JAmXml self.primary_key = 'id' attr_accessible :stype, :filename, :allow_duplicate_users, :mount_add, :mount_remove, :listener_add, :listener_remove, :username, :password, :auth_header, :timelimit_header - attr_accessor :stype, :filename, :allow_duplicate_users, :mount_add, :mount_remove, - :listener_add, :listener_remove, :username, :password, :auth_header, :timelimit_header - def dumpXml() + validates :stype, presence: true + + def dumpXml (ident=1, output=$stdout) + + tb = "\t" + tbs = tb * (ident) + tbse = tb * (ident-1) + if tbse.empty? || tbse.nil? + tbse="" + end + + if self.stype.nil? + return + elsif self.stype.empty? + return + elsif self.stype == "htpasswd" + nm = "" + + output.puts "#{tbse}#{nm}" + fname = jMakeStrXmlSafe(self.filename) + + output.puts "#{tbs}