* VRFS-1684 and VRFS-1684 (find session APIs) completede

This commit is contained in:
Seth Call 2014-06-17 17:16:49 -05:00
parent 106222638f
commit 39a55f562c
8 changed files with 308 additions and 65 deletions

View File

@ -175,4 +175,5 @@ audio_latency.sql
ams_index.sql ams_index.sql
update_ams_index.sql update_ams_index.sql
update_ams_index_2.sql update_ams_index_2.sql
sms_index.sql sms_index.sql
music_sessions_description_search.sql

View File

@ -0,0 +1,9 @@
-- add full search capabilities for description (threw in genre too)
ALTER TABLE music_sessions ADD COLUMN description_tsv tsvector;
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON music_sessions FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(description_tsv, 'public.jamenglish', description);
CREATE INDEX music_sessions_description_tsv_index ON music_sessions USING gin(description_tsv);
-- prime the pump
UPDATE music_sessions set description = description;

View File

@ -1,5 +1,8 @@
module JamRuby module JamRuby
class ActiveMusicSession < ActiveRecord::Base class ActiveMusicSession < ActiveRecord::Base
@@log = Logging.logger[ActiveMusicSession]
self.primary_key = 'id' self.primary_key = 'id'
self.table_name = 'active_music_sessions' self.table_name = 'active_music_sessions'
@ -337,10 +340,8 @@ module JamRuby
keyword = options[:keyword] keyword = options[:keyword]
offset = options[:offset] offset = options[:offset]
limit = options[:limit] limit = options[:limit]
day = options[:day]
connection = Connection.where(user_id: current_user.id, client_id: client_id).first! timezone_offset = options[:timezone_offset]
my_locidispid = connection.locidispid
my_audio_latency = connection.last_jam_audio_latency
query = MusicSession query = MusicSession
.select('music_sessions.*') .select('music_sessions.*')
@ -380,29 +381,32 @@ module JamRuby
} }
) )
if offset # if not specified, default offset to 0
query = query.offset(offset) offset ||= 0
end offset = offset.to_i
# if not specified, default limit to 20
limit ||= 20
limit = limit.to_i
if limit query = query.offset(offset)
query = query.limit(limit) query = query.limit(limit)
end query = query.where("music_sessions.genre_id = ?", genre) unless genre.blank?
query = query.where('music_sessions.language = ?', lang) unless lang.blank?
query = query.where("(description_tsv @@ to_tsquery('jamenglish', ?))", keyword + ':*') unless keyword.blank?
# cleanse keyword so it is only word characters. ignore if less than 3 characters long or greater than 100 if !day.blank? && !timezone_offset.blank?
# TODO do we want to force match of whole words only? this matches any substring... begin
# TODO do we want to match more than one word in the phrase? this matches only the first word... day = Date.parse(day)
next_day = day + 1
unless keyword.nil? or keyword.length < 3 or keyword.length > 100 timezone_offset = timezone_offset.to_i
w = keyword.split(/\W+/) query = query.where("scheduled_start BETWEEN TIMESTAMP WITH TIME ZONE '#{day} 00:00:00#{timezone_offset}'
if w.length > 0 and w[0].length >= 3 AND TIMESTAMP WITH TIME ZONE '#{next_day} 00:00:00#{timezone_offset}'")
query = query.where("music_sessions.description like '%#{w[0]}%'") rescue Exception => e
# do nothing. bad date probably
@@log.warn("unable to parse day=#{day}, timezone_offset=#{timezone_offset}, e=#{e}")
end end
end end
query = query.where("music_sessions.genre_id = ?", genre) unless genre.nil?
# TODO filter by lang
return query return query
end end
@ -428,13 +432,7 @@ module JamRuby
def self.ams_index(current_user, params) def self.ams_index(current_user, params)
ActiveMusicSession.ams_init(current_user, params) ActiveMusicSession.ams_init(current_user, params)
music_sessions = ActiveMusicSession.ams_query(current_user, music_sessions = ActiveMusicSession.ams_query(current_user, params).all
client_id: params[:client_id],
genre: params[:genre],
lang: params[:lang],
keyword: params[:keyword],
offset: params[:offset],
limit: params[:limit]).all
music_session_users = ActiveMusicSession.ams_users.all music_session_users = ActiveMusicSession.ams_users.all

View File

@ -3,6 +3,8 @@ require 'iso-639'
module JamRuby module JamRuby
class MusicSession < ActiveRecord::Base class MusicSession < ActiveRecord::Base
@@log = Logging.logger[MusicSession]
NO_RECURRING = 'once' NO_RECURRING = 'once'
RECURRING_WEEKLY = 'weekly' RECURRING_WEEKLY = 'weekly'
@ -591,10 +593,8 @@ module JamRuby
keyword = options[:keyword] keyword = options[:keyword]
offset = options[:offset] offset = options[:offset]
limit = options[:limit] limit = options[:limit]
day = options[:day]
connection = Connection.where(user_id: current_user.id, client_id: client_id).first! timezone_offset = options[:timezone_offset]
my_locidispid = connection.locidispid
my_audio_latency = connection.last_jam_audio_latency
query = MusicSession query = MusicSession
.select('music_sessions.*') .select('music_sessions.*')
@ -634,29 +634,32 @@ module JamRuby
} }
) )
if offset # if not specified, default offset to 0
query = query.offset(offset) offset ||= 0
end offset = offset.to_i
# if not specified, default limit to 20
limit ||= 20
limit = limit.to_i
if limit query = query.offset(offset)
query = query.limit(limit) query = query.limit(limit)
end query = query.where("music_sessions.genre_id = ?", genre) unless genre.blank?
query = query.where('music_sessions.language = ?', lang) unless lang.blank?
query = query.where("(description_tsv @@ to_tsquery('jamenglish', ?))", keyword + ':*') unless keyword.blank?
# cleanse keyword so it is only word characters. ignore if less than 3 characters long or greater than 100 if !day.blank? && !timezone_offset.blank?
# TODO do we want to force match of whole words only? this matches any substring... begin
# TODO do we want to match more than one word in the phrase? this matches only the first word... day = Date.parse(day)
next_day = day + 1
unless keyword.nil? or keyword.length < 3 or keyword.length > 100 timezone_offset = timezone_offset.to_i
w = keyword.split(/\W+/) query = query.where("scheduled_start BETWEEN TIMESTAMP WITH TIME ZONE '#{day} 00:00:00#{timezone_offset}'
if w.length > 0 and w[0].length >= 3 AND TIMESTAMP WITH TIME ZONE '#{next_day} 00:00:00#{timezone_offset}'")
query = query.where("music_sessions.description like '%#{w[0]}%'") rescue Exception => e
# do nothing. bad date probably
@@log.warn("unable to parse day=#{day}, timezone_offset=#{timezone_offset}, e=#{e}")
end end
end end
query = query.where("music_sessions.genre_id = ?", genre) unless genre.nil?
# TODO filter by lang
return query return query
end end
@ -682,13 +685,7 @@ module JamRuby
def self.sms_index(current_user, params) def self.sms_index(current_user, params)
MusicSession.sms_init(current_user, params) MusicSession.sms_init(current_user, params)
music_sessions = MusicSession.sms_query(current_user, music_sessions = MusicSession.sms_query(current_user, params).all
client_id: params[:client_id],
genre: params[:genre],
lang: params[:lang],
keyword: params[:keyword],
offset: params[:offset],
limit: params[:limit]).all
music_session_users = MusicSession.sms_users.all music_session_users = MusicSession.sms_users.all

View File

@ -58,13 +58,14 @@ FactoryGirl.define do
legal_terms true legal_terms true
genre JamRuby::Genre.first genre JamRuby::Genre.first
band nil band nil
language 'en'
end end
before(:create) do |session, evaluator| before(:create) do |session, evaluator|
music_session = FactoryGirl.create(:music_session, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat, music_session = FactoryGirl.create(:music_session, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat,
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access, fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band) genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band, language: evaluator.language)
session.id = music_session.id session.id = music_session.id
end end

View File

@ -332,6 +332,13 @@ describe ActiveMusicSession do
end end
end end
def ams(user, params)
ActiveRecord::Base.transaction do
return ActiveMusicSession.ams_index(user, params)
end
end
describe "ams_index" do describe "ams_index" do
it "does not crash" do it "does not crash" do
@ -347,8 +354,8 @@ describe ActiveMusicSession do
user = FactoryGirl.create(:user, last_jam_locidispid: 1, last_jam_audio_latency: 5) user = FactoryGirl.create(:user, last_jam_locidispid: 1, last_jam_audio_latency: 5)
c3 = FactoryGirl.create(:connection, user: user, locidispid: 1, last_jam_audio_latency: 5) c3 = FactoryGirl.create(:connection, user: user, locidispid: 1, last_jam_audio_latency: 5)
Score.createx(c1.locidispid, c1.client_id, c1.addr, c3.locidispid, c3.client_id, c3.addr, 20, nil); Score.createx(c1.locidispid, c1.client_id, c1.addr, c3.locidispid, c3.client_id, c3.addr, 20, nil)
Score.createx(c2.locidispid, c2.client_id, c2.addr, c3.locidispid, c3.client_id, c3.addr, 30, nil); Score.createx(c2.locidispid, c2.client_id, c2.addr, c3.locidispid, c3.client_id, c3.addr, 30, nil)
# make a transaction # make a transaction
@ -384,6 +391,120 @@ describe ActiveMusicSession do
end end
end end
describe "parameters" do
let(:creator_1) { FactoryGirl.create(:user, last_jam_locidispid: 4, last_jam_audio_latency: 8) }
let(:creator_conn_1) { FactoryGirl.create(:connection, user: creator_1, ip_address: '4.4.4.4', locidispid: 4, addr:4) }
let(:creator_2) { FactoryGirl.create(:user, last_jam_locidispid: 1, last_jam_audio_latency: 10) }
let(:creator_conn_2) { FactoryGirl.create(:connection, user: creator_2, ip_address: '4.4.4.4', locidispid: 1, addr:1) }
let(:creator_3) { FactoryGirl.create(:user, last_jam_locidispid: 2, last_jam_audio_latency: 12) }
let(:creator_conn_3) { FactoryGirl.create(:connection, user: creator_3, ip_address: '5.5.5.5', locidispid: 2, addr:2) }
let(:searcher_1) { FactoryGirl.create(:user, last_jam_locidispid: 5, last_jam_audio_latency: 6) }
let(:searcher_conn_1) { FactoryGirl.create(:connection, user: searcher_1, ip_address: '8.8.8.8', locidispid: 5, addr:5) }
let(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) }
let(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) }
let!(:music_session_1) { FactoryGirl.create(:active_music_session, :creator => creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps" ) }
let!(:music_session_2) { FactoryGirl.create(:active_music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") }
let(:good_network_score) { 20 }
let(:fair_network_score) { 30 }
let(:tracks) { [{'sound' => 'mono', 'client_track_id' => 'abc', 'instrument_id' => 'piano'}] }
it "offset/limit" do
# put creators in the session
creator_conn_1.join_the_session(music_session_1.music_session, true, tracks, creator_1, 10)
creator_conn_1.errors.any?.should be_false
creator_conn_2.join_the_session(music_session_2.music_session, true, tracks, creator_2, 10)
creator_conn_2.errors.any?.should be_false
# set up some scores to control sorting
Score.createx(searcher_conn_1.locidispid, searcher_conn_1.client_id, searcher_conn_1.addr, creator_conn_1.locidispid, creator_conn_1.client_id, creator_conn_1.addr, good_network_score, nil)
Score.createx(searcher_conn_1.locidispid, searcher_conn_1.client_id, searcher_conn_1.addr, creator_conn_2.locidispid, creator_conn_2.client_id, creator_conn_2.addr, fair_network_score, nil)
# verify we can get all 2 sessions
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
music_sessions[0].should == music_session_1.music_session
# grab just the 1st
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, offset:0, limit:1)
music_sessions.length.should == 1
music_sessions[0].should == music_session_1.music_session
# then the second
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, offset:1, limit:2)
music_sessions.length.should == 1
music_sessions[0].should == music_session_2.music_session
end
it "genre" do
# verify we can get all 2 sessions
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
# get only african
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, genre: 'african')
music_sessions.length.should == 1
music_sessions[0].genre.should == Genre.find('african')
# get only ambient
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, genre: 'ambient')
music_sessions.length.should == 1
music_sessions[0].genre.should == Genre.find('ambient')
end
it "language" do
# verify we can get all 2 sessions
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
# get only english
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'en')
music_sessions.length.should == 1
music_sessions[0].language.should == 'en'
# get only ambient
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, lang: 'es')
music_sessions.length.should == 1
music_sessions[0].language.should == 'es'
end
it "keyword" do
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'Jump')
music_sessions.length.should == 1
music_sessions[0].should == music_session_1.music_session
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'Bunny')
music_sessions.length.should == 2
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'play')
music_sessions.length.should == 1
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'bun')
music_sessions.length.should == 2
end
it "date" do
music_session_1.music_session.scheduled_start = 1.days.ago
music_session_1.music_session.save!
# if no day/timezone_offset specified, both should be returned
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
# find today's session
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, day: Date.today.to_s, timezone_offset: DateTime.now.offset.numerator)
music_sessions.length.should == 1
music_sessions[0].should == music_session_2.music_session
# find yesterday's session
music_sessions, user_search = ams(searcher_1, client_id: searcher_conn_1.client_id, day: (Date.today - 1).to_s, timezone_offset: DateTime.now.offset.numerator)
music_sessions.length.should == 1
music_sessions[0].should == music_session_1.music_session
end
end
# todo we need more tests: # todo we need more tests:
# #
# the easiest collection of tests, not involving filtering, just tagging and latency, still result in many cases # the easiest collection of tests, not involving filtering, just tagging and latency, still result in many cases

View File

@ -314,8 +314,8 @@ describe MusicSession do
let!(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) } let!(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) }
let!(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) } let!(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) }
let!(:music_session_1) { FactoryGirl.create(:music_session, creator: creator_1) } let!(:music_session_1) { FactoryGirl.create(:music_session, creator: creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps") }
let!(:music_session_2) { FactoryGirl.create(:music_session, creator: creator_2) } let!(:music_session_2) { FactoryGirl.create(:music_session, creator: creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") }
let!(:music_session_3) { FactoryGirl.create(:music_session, creator: creator_3) } let!(:music_session_3) { FactoryGirl.create(:music_session, creator: creator_3) }
let(:good_network_score) { 20 } let(:good_network_score) { 20 }
@ -385,7 +385,122 @@ describe MusicSession do
music_sessions, user_scores = sms(searcher_1, {client_id: searcher_conn_1.client_id}) music_sessions, user_scores = sms(searcher_1, {client_id: searcher_conn_1.client_id})
music_sessions.length.should == 2 music_sessions.length.should == 2
end end
end
describe "parameters" do
let(:creator_1) { FactoryGirl.create(:user, last_jam_locidispid: 4, last_jam_audio_latency: 8) }
let(:creator_conn_1) { FactoryGirl.create(:connection, user: creator_1, ip_address: '4.4.4.4', locidispid: 4, addr:4) }
let(:creator_2) { FactoryGirl.create(:user, last_jam_locidispid: 1, last_jam_audio_latency: 10) }
let(:creator_conn_2) { FactoryGirl.create(:connection, user: creator_2, ip_address: '4.4.4.4', locidispid: 1, addr:1) }
let(:creator_3) { FactoryGirl.create(:user, last_jam_locidispid: 2, last_jam_audio_latency: 12) }
let(:creator_conn_3) { FactoryGirl.create(:connection, user: creator_3, ip_address: '5.5.5.5', locidispid: 2, addr:2) }
let(:searcher_1) { FactoryGirl.create(:user, last_jam_locidispid: 5, last_jam_audio_latency: 6) }
let(:searcher_conn_1) { FactoryGirl.create(:connection, user: searcher_1, ip_address: '8.8.8.8', locidispid: 5, addr:5) }
let(:searcher_2) { FactoryGirl.create(:user, last_jam_locidispid: 3, last_jam_audio_latency: 14) }
let(:searcher_conn_2) { FactoryGirl.create(:connection, user: searcher_2, ip_address: '9.9.9.9', locidispid: 3, addr:3) }
let!(:music_session_1) { FactoryGirl.create(:music_session, :creator => creator_1, genre: Genre.find('african'), language: 'en', description: "Bunny Jumps" ) }
let!(:music_session_2) { FactoryGirl.create(:music_session, :creator => creator_2, genre: Genre.find('ambient'), language: 'es', description: "Play with us as we jam to beatles and bunnies") }
let(:good_network_score) { 20 }
let(:fair_network_score) { 30 }
it "offset/limit" do
# set up some scores to control sorting
Score.createx(searcher_conn_1.locidispid, searcher_conn_1.client_id, searcher_conn_1.addr, creator_conn_1.locidispid, creator_conn_1.client_id, creator_conn_1.addr, good_network_score, nil)
Score.createx(searcher_conn_1.locidispid, searcher_conn_1.client_id, searcher_conn_1.addr, creator_conn_2.locidispid, creator_conn_2.client_id, creator_conn_2.addr, fair_network_score, nil)
# verify we can get all 2 sessions
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
music_sessions[0].should == music_session_1
# grab just the 1st
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, offset:0, limit:1)
music_sessions.length.should == 1
music_sessions[0].should == music_session_1
# then the second
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, offset:1, limit:2)
music_sessions.length.should == 1
music_sessions[0].should == music_session_2
end
it "genre" do
# verify we can get all 2 sessions
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
# get only african
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, genre: 'african')
music_sessions.length.should == 1
music_sessions[0].genre.should == Genre.find('african')
# get only ambient
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, genre: 'ambient')
music_sessions.length.should == 1
music_sessions[0].genre.should == Genre.find('ambient')
end
it "language" do
# verify we can get all 2 sessions
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 2
# get only english
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'en')
music_sessions.length.should == 1
music_sessions[0].language.should == 'en'
# get only ambient
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, lang: 'es')
music_sessions.length.should == 1
music_sessions[0].language.should == 'es'
end
it "keyword" do
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'Jump')
music_sessions.length.should == 1
music_sessions[0].should == music_session_1
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'Bunny')
music_sessions.length.should == 2
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'play')
music_sessions.length.should == 1
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, keyword: 'bun')
music_sessions.length.should == 2
end
it "date" do
music_session_1.scheduled_start = 1.days.ago
music_session_1.save!
# if no day/timezone_offset specified, then the 15 minute slush rule will still kick in, nixing music_session_1
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id)
music_sessions.length.should == 1
music_sessions[0].should == music_session_2
# find today's session
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, day: Date.today.to_s, timezone_offset: DateTime.now.offset.numerator)
music_sessions.length.should == 1
music_sessions[0].should == music_session_2
# find yesterday's session... oh wait, you can't find a session for yesterday, because the 15 minute slush rule will still kick in.
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, day: (Date.today - 1).to_s, timezone_offset: DateTime.now.offset.numerator)
music_sessions.length.should == 0
# but let's make it tomorrow, so we can test in that direction
music_session_1.scheduled_start = 1.day.from_now
music_session_1.save!
music_sessions, user_search = sms(searcher_1, client_id: searcher_conn_1.client_id, day: (Date.today + 1).to_s, timezone_offset: DateTime.now.offset.numerator)
music_sessions.length.should == 1
music_sessions[0].should == music_session_1
end
end end
end end
end end

View File

@ -77,13 +77,14 @@ FactoryGirl.define do
legal_terms true legal_terms true
genre JamRuby::Genre.first genre JamRuby::Genre.first
band nil band nil
language 'en'
end end
before(:create) do |session, evaluator| before(:create) do |session, evaluator|
music_session = FactoryGirl.create(:music_session, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat, music_session = FactoryGirl.create(:music_session, name: evaluator.name, description: evaluator.description, fan_chat: evaluator.fan_chat,
fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access, fan_access: evaluator.fan_access, approval_required: evaluator.approval_required, musician_access: evaluator.musician_access,
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band) genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band, language: evaluator.language)
session.id = music_session.id session.id = music_session.id
end end